]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix VIA recording problem
[thirdparty/linux.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,
df694daa
KY
106 ALC262_AUTO,
107 ALC262_MODEL_LAST /* last tag */
108};
109
a361d84b
KY
110/* ALC268 models */
111enum {
eb5a6621 112 ALC267_QUANTA_IL1,
a361d84b 113 ALC268_3ST,
d1a991a6 114 ALC268_TOSHIBA,
d273809e 115 ALC268_ACER,
8ef355da 116 ALC268_ACER_ASPIRE_ONE,
3866f0b0 117 ALC268_DELL,
f12462c5 118 ALC268_ZEPTO,
86c53bd2
JW
119#ifdef CONFIG_SND_DEBUG
120 ALC268_TEST,
121#endif
a361d84b
KY
122 ALC268_AUTO,
123 ALC268_MODEL_LAST /* last tag */
124};
125
f6a92248
KY
126/* ALC269 models */
127enum {
128 ALC269_BASIC,
60db6b53 129 ALC269_QUANTA_FL1,
f53281e6
KY
130 ALC269_ASUS_EEEPC_P703,
131 ALC269_ASUS_EEEPC_P901,
f6a92248
KY
132 ALC269_AUTO,
133 ALC269_MODEL_LAST /* last tag */
134};
135
df694daa
KY
136/* ALC861 models */
137enum {
138 ALC861_3ST,
9c7f852e 139 ALC660_3ST,
df694daa
KY
140 ALC861_3ST_DIG,
141 ALC861_6ST_DIG,
22309c3e 142 ALC861_UNIWILL_M31,
a53d1aec 143 ALC861_TOSHIBA,
7cdbff94 144 ALC861_ASUS,
56bb0cab 145 ALC861_ASUS_LAPTOP,
df694daa
KY
146 ALC861_AUTO,
147 ALC861_MODEL_LAST,
148};
149
f32610ed
JS
150/* ALC861-VD models */
151enum {
152 ALC660VD_3ST,
6963f84c 153 ALC660VD_3ST_DIG,
f32610ed
JS
154 ALC861VD_3ST,
155 ALC861VD_3ST_DIG,
156 ALC861VD_6ST_DIG,
bdd148a3 157 ALC861VD_LENOVO,
272a527c 158 ALC861VD_DALLAS,
d1a991a6 159 ALC861VD_HP,
f32610ed
JS
160 ALC861VD_AUTO,
161 ALC861VD_MODEL_LAST,
162};
163
bc9f98a9
KY
164/* ALC662 models */
165enum {
166 ALC662_3ST_2ch_DIG,
167 ALC662_3ST_6ch_DIG,
168 ALC662_3ST_6ch,
169 ALC662_5ST_DIG,
170 ALC662_LENOVO_101E,
291702f0 171 ALC662_ASUS_EEEPC_P701,
8c427226 172 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
173 ALC663_ASUS_M51VA,
174 ALC663_ASUS_G71V,
175 ALC663_ASUS_H13,
176 ALC663_ASUS_G50V,
f1d4e28b
KY
177 ALC662_ECS,
178 ALC663_ASUS_MODE1,
179 ALC662_ASUS_MODE2,
180 ALC663_ASUS_MODE3,
181 ALC663_ASUS_MODE4,
182 ALC663_ASUS_MODE5,
183 ALC663_ASUS_MODE6,
bc9f98a9
KY
184 ALC662_AUTO,
185 ALC662_MODEL_LAST,
186};
187
df694daa
KY
188/* ALC882 models */
189enum {
190 ALC882_3ST_DIG,
191 ALC882_6ST_DIG,
4b146cb0 192 ALC882_ARIMA,
bdd148a3 193 ALC882_W2JC,
272a527c
KY
194 ALC882_TARGA,
195 ALC882_ASUS_A7J,
914759b7 196 ALC882_ASUS_A7M,
9102cd1c 197 ALC885_MACPRO,
87350ad0 198 ALC885_MBP3,
c54728d8 199 ALC885_IMAC24,
272a527c 200 ALC882_AUTO,
df694daa
KY
201 ALC882_MODEL_LAST,
202};
203
9c7f852e
TI
204/* ALC883 models */
205enum {
206 ALC883_3ST_2ch_DIG,
207 ALC883_3ST_6ch_DIG,
208 ALC883_3ST_6ch,
209 ALC883_6ST_DIG,
ccc656ce
KY
210 ALC883_TARGA_DIG,
211 ALC883_TARGA_2ch_DIG,
bab282b9 212 ALC883_ACER,
2880a867 213 ALC883_ACER_ASPIRE,
c07584c8 214 ALC883_MEDION,
ea1fb29a 215 ALC883_MEDION_MD2,
b373bdeb 216 ALC883_LAPTOP_EAPD,
bc9f98a9 217 ALC883_LENOVO_101E_2ch,
272a527c 218 ALC883_LENOVO_NB0763,
189609ae 219 ALC888_LENOVO_MS7195_DIG,
e2757d5e 220 ALC888_LENOVO_SKY,
ea1fb29a 221 ALC883_HAIER_W66,
4723c022 222 ALC888_3ST_HP,
5795b9e6 223 ALC888_6ST_DELL,
a8848bd6 224 ALC883_MITAC,
0c4cc443 225 ALC883_CLEVO_M720,
fb97dc67 226 ALC883_FUJITSU_PI2515,
17bba1b7 227 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
228 ALC888_ASUS_M90V,
229 ALC888_ASUS_EEE1601,
9c7f852e
TI
230 ALC883_AUTO,
231 ALC883_MODEL_LAST,
232};
233
df694daa
KY
234/* for GPIO Poll */
235#define GPIO_MASK 0x03
236
1da177e4
LT
237struct alc_spec {
238 /* codec parameterization */
df694daa 239 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
240 unsigned int num_mixers;
241
df694daa 242 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
243 * don't forget NULL
244 * termination!
e9edcee0
TI
245 */
246 unsigned int num_init_verbs;
1da177e4 247
16ded525 248 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
249 struct hda_pcm_stream *stream_analog_playback;
250 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
251 struct hda_pcm_stream *stream_analog_alt_playback;
252 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 253
f12ab1e0 254 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
255 struct hda_pcm_stream *stream_digital_playback;
256 struct hda_pcm_stream *stream_digital_capture;
257
258 /* playback */
16ded525
TI
259 struct hda_multi_out multiout; /* playback set-up
260 * max_channels, dacs must be set
261 * dig_out_nid and hp_nid are optional
262 */
6330079f 263 hda_nid_t alt_dac_nid;
1da177e4
LT
264
265 /* capture */
266 unsigned int num_adc_nids;
267 hda_nid_t *adc_nids;
e1406348 268 hda_nid_t *capsrc_nids;
16ded525 269 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
270
271 /* capture source */
a1e8d2da 272 unsigned int num_mux_defs;
1da177e4
LT
273 const struct hda_input_mux *input_mux;
274 unsigned int cur_mux[3];
275
276 /* channel model */
d2a6d7dc 277 const struct hda_channel_mode *channel_mode;
1da177e4 278 int num_channel_mode;
4e195a7b 279 int need_dac_fix;
1da177e4
LT
280
281 /* PCM information */
4c5186ed 282 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 283
e9edcee0
TI
284 /* dynamic controls, init_verbs and input_mux */
285 struct auto_pin_cfg autocfg;
286 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 287 struct snd_kcontrol_new *kctl_alloc;
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;
df694daa
KY
309};
310
311/*
312 * configuration template - to be copied to the spec instance
313 */
314struct alc_config_preset {
9c7f852e
TI
315 struct snd_kcontrol_new *mixers[5]; /* should be identical size
316 * with spec
317 */
df694daa
KY
318 const struct hda_verb *init_verbs[5];
319 unsigned int num_dacs;
320 hda_nid_t *dac_nids;
321 hda_nid_t dig_out_nid; /* optional */
322 hda_nid_t hp_nid; /* optional */
323 unsigned int num_adc_nids;
324 hda_nid_t *adc_nids;
e1406348 325 hda_nid_t *capsrc_nids;
df694daa
KY
326 hda_nid_t dig_in_nid;
327 unsigned int num_channel_mode;
328 const struct hda_channel_mode *channel_mode;
4e195a7b 329 int need_dac_fix;
a1e8d2da 330 unsigned int num_mux_defs;
df694daa 331 const struct hda_input_mux *input_mux;
ae6b813a
TI
332 void (*unsol_event)(struct hda_codec *, unsigned int);
333 void (*init_hook)(struct hda_codec *);
cb53c626
TI
334#ifdef CONFIG_SND_HDA_POWER_SAVE
335 struct hda_amp_list *loopbacks;
336#endif
1da177e4
LT
337};
338
1da177e4
LT
339
340/*
341 * input MUX handling
342 */
9c7f852e
TI
343static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
345{
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
348 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
349 if (mux_idx >= spec->num_mux_defs)
350 mux_idx = 0;
351 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
352}
353
9c7f852e
TI
354static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
356{
357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct alc_spec *spec = codec->spec;
359 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
360
361 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
362 return 0;
363}
364
9c7f852e
TI
365static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
367{
368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct alc_spec *spec = codec->spec;
370 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da 371 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
e1406348
TI
372 hda_nid_t nid = spec->capsrc_nids ?
373 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
a1e8d2da 374 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
e1406348 375 nid, &spec->cur_mux[adc_idx]);
1da177e4
LT
376}
377
e9edcee0 378
1da177e4
LT
379/*
380 * channel mode setting
381 */
9c7f852e
TI
382static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
384{
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
387 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
388 spec->num_channel_mode);
1da177e4
LT
389}
390
9c7f852e
TI
391static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
392 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
393{
394 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
395 struct alc_spec *spec = codec->spec;
d2a6d7dc 396 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
397 spec->num_channel_mode,
398 spec->multiout.max_channels);
1da177e4
LT
399}
400
9c7f852e
TI
401static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
403{
404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405 struct alc_spec *spec = codec->spec;
4e195a7b
TI
406 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
407 spec->num_channel_mode,
408 &spec->multiout.max_channels);
bd2033f2 409 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
410 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
411 return err;
1da177e4
LT
412}
413
a9430dd8 414/*
4c5186ed 415 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 416 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
417 * being part of a format specifier. Maximum allowed length of a value is
418 * 63 characters plus NULL terminator.
7cf51e48
JW
419 *
420 * Note: some retasking pin complexes seem to ignore requests for input
421 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
422 * are requested. Therefore order this list so that this behaviour will not
423 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
424 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
425 * March 2006.
4c5186ed
JW
426 */
427static char *alc_pin_mode_names[] = {
7cf51e48
JW
428 "Mic 50pc bias", "Mic 80pc bias",
429 "Line in", "Line out", "Headphone out",
4c5186ed
JW
430};
431static unsigned char alc_pin_mode_values[] = {
7cf51e48 432 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
433};
434/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
435 * in the pin being assumed to be exclusively an input or an output pin. In
436 * addition, "input" pins may or may not process the mic bias option
437 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
438 * accept requests for bias as of chip versions up to March 2006) and/or
439 * wiring in the computer.
a9430dd8 440 */
a1e8d2da
JW
441#define ALC_PIN_DIR_IN 0x00
442#define ALC_PIN_DIR_OUT 0x01
443#define ALC_PIN_DIR_INOUT 0x02
444#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
445#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 446
ea1fb29a 447/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
448 * For each direction the minimum and maximum values are given.
449 */
a1e8d2da 450static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
451 { 0, 2 }, /* ALC_PIN_DIR_IN */
452 { 3, 4 }, /* ALC_PIN_DIR_OUT */
453 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
454 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
455 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
456};
457#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
458#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
459#define alc_pin_mode_n_items(_dir) \
460 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
461
9c7f852e
TI
462static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
463 struct snd_ctl_elem_info *uinfo)
a9430dd8 464{
4c5186ed
JW
465 unsigned int item_num = uinfo->value.enumerated.item;
466 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
467
468 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 469 uinfo->count = 1;
4c5186ed
JW
470 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
471
472 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
473 item_num = alc_pin_mode_min(dir);
474 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
475 return 0;
476}
477
9c7f852e
TI
478static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
479 struct snd_ctl_elem_value *ucontrol)
a9430dd8 480{
4c5186ed 481 unsigned int i;
a9430dd8
JW
482 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
483 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 484 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 485 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
486 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
487 AC_VERB_GET_PIN_WIDGET_CONTROL,
488 0x00);
a9430dd8 489
4c5186ed
JW
490 /* Find enumerated value for current pinctl setting */
491 i = alc_pin_mode_min(dir);
9c7f852e 492 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 493 i++;
9c7f852e 494 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
495 return 0;
496}
497
9c7f852e
TI
498static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
a9430dd8 500{
4c5186ed 501 signed int change;
a9430dd8
JW
502 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
504 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
505 long val = *ucontrol->value.integer.value;
9c7f852e
TI
506 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
507 AC_VERB_GET_PIN_WIDGET_CONTROL,
508 0x00);
a9430dd8 509
f12ab1e0 510 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
511 val = alc_pin_mode_min(dir);
512
513 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
514 if (change) {
515 /* Set pin mode to that requested */
82beb8fd
TI
516 snd_hda_codec_write_cache(codec, nid, 0,
517 AC_VERB_SET_PIN_WIDGET_CONTROL,
518 alc_pin_mode_values[val]);
cdcd9268 519
ea1fb29a 520 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
521 * for the requested pin mode. Enum values of 2 or less are
522 * input modes.
523 *
524 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
525 * reduces noise slightly (particularly on input) so we'll
526 * do it. However, having both input and output buffers
527 * enabled simultaneously doesn't seem to be problematic if
528 * this turns out to be necessary in the future.
cdcd9268
JW
529 */
530 if (val <= 2) {
47fd830a
TI
531 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
532 HDA_AMP_MUTE, HDA_AMP_MUTE);
533 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
534 HDA_AMP_MUTE, 0);
cdcd9268 535 } else {
47fd830a
TI
536 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
537 HDA_AMP_MUTE, HDA_AMP_MUTE);
538 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
539 HDA_AMP_MUTE, 0);
cdcd9268
JW
540 }
541 }
a9430dd8
JW
542 return change;
543}
544
4c5186ed 545#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 546 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
547 .info = alc_pin_mode_info, \
548 .get = alc_pin_mode_get, \
549 .put = alc_pin_mode_put, \
550 .private_value = nid | (dir<<16) }
df694daa 551
5c8f858d
JW
552/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
553 * together using a mask with more than one bit set. This control is
554 * currently used only by the ALC260 test model. At this stage they are not
555 * needed for any "production" models.
556 */
557#ifdef CONFIG_SND_DEBUG
a5ce8890 558#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 559
9c7f852e
TI
560static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
562{
563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564 hda_nid_t nid = kcontrol->private_value & 0xffff;
565 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
566 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
567 unsigned int val = snd_hda_codec_read(codec, nid, 0,
568 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
569
570 *valp = (val & mask) != 0;
571 return 0;
572}
9c7f852e
TI
573static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
575{
576 signed int change;
577 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
578 hda_nid_t nid = kcontrol->private_value & 0xffff;
579 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
580 long val = *ucontrol->value.integer.value;
9c7f852e
TI
581 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
582 AC_VERB_GET_GPIO_DATA,
583 0x00);
5c8f858d
JW
584
585 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
586 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
587 if (val == 0)
5c8f858d
JW
588 gpio_data &= ~mask;
589 else
590 gpio_data |= mask;
82beb8fd
TI
591 snd_hda_codec_write_cache(codec, nid, 0,
592 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
593
594 return change;
595}
596#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
597 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
598 .info = alc_gpio_data_info, \
599 .get = alc_gpio_data_get, \
600 .put = alc_gpio_data_put, \
601 .private_value = nid | (mask<<16) }
602#endif /* CONFIG_SND_DEBUG */
603
92621f13
JW
604/* A switch control to allow the enabling of the digital IO pins on the
605 * ALC260. This is incredibly simplistic; the intention of this control is
606 * to provide something in the test model allowing digital outputs to be
607 * identified if present. If models are found which can utilise these
608 * outputs a more complete mixer control can be devised for those models if
609 * necessary.
610 */
611#ifdef CONFIG_SND_DEBUG
a5ce8890 612#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 613
9c7f852e
TI
614static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
616{
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620 long *valp = ucontrol->value.integer.value;
9c7f852e 621 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 622 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
623
624 *valp = (val & mask) != 0;
625 return 0;
626}
9c7f852e
TI
627static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
629{
630 signed int change;
631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632 hda_nid_t nid = kcontrol->private_value & 0xffff;
633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634 long val = *ucontrol->value.integer.value;
9c7f852e 635 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 636 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 637 0x00);
92621f13
JW
638
639 /* Set/unset the masked control bit(s) as needed */
9c7f852e 640 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
641 if (val==0)
642 ctrl_data &= ~mask;
643 else
644 ctrl_data |= mask;
82beb8fd
TI
645 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
646 ctrl_data);
92621f13
JW
647
648 return change;
649}
650#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
652 .info = alc_spdif_ctrl_info, \
653 .get = alc_spdif_ctrl_get, \
654 .put = alc_spdif_ctrl_put, \
655 .private_value = nid | (mask<<16) }
656#endif /* CONFIG_SND_DEBUG */
657
f8225f6d
JW
658/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
659 * Again, this is only used in the ALC26x test models to help identify when
660 * the EAPD line must be asserted for features to work.
661 */
662#ifdef CONFIG_SND_DEBUG
663#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
664
665static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
666 struct snd_ctl_elem_value *ucontrol)
667{
668 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
669 hda_nid_t nid = kcontrol->private_value & 0xffff;
670 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
671 long *valp = ucontrol->value.integer.value;
672 unsigned int val = snd_hda_codec_read(codec, nid, 0,
673 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
674
675 *valp = (val & mask) != 0;
676 return 0;
677}
678
679static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
681{
682 int change;
683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684 hda_nid_t nid = kcontrol->private_value & 0xffff;
685 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686 long val = *ucontrol->value.integer.value;
687 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
688 AC_VERB_GET_EAPD_BTLENABLE,
689 0x00);
690
691 /* Set/unset the masked control bit(s) as needed */
692 change = (!val ? 0 : mask) != (ctrl_data & mask);
693 if (!val)
694 ctrl_data &= ~mask;
695 else
696 ctrl_data |= mask;
697 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
698 ctrl_data);
699
700 return change;
701}
702
703#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
704 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
705 .info = alc_eapd_ctrl_info, \
706 .get = alc_eapd_ctrl_get, \
707 .put = alc_eapd_ctrl_put, \
708 .private_value = nid | (mask<<16) }
709#endif /* CONFIG_SND_DEBUG */
710
df694daa
KY
711/*
712 * set up from the preset table
713 */
9c7f852e
TI
714static void setup_preset(struct alc_spec *spec,
715 const struct alc_config_preset *preset)
df694daa
KY
716{
717 int i;
718
719 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
720 spec->mixers[spec->num_mixers++] = preset->mixers[i];
9c7f852e
TI
721 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
722 i++)
723 spec->init_verbs[spec->num_init_verbs++] =
724 preset->init_verbs[i];
ea1fb29a 725
df694daa
KY
726 spec->channel_mode = preset->channel_mode;
727 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 728 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
729
730 spec->multiout.max_channels = spec->channel_mode[0].channels;
731
732 spec->multiout.num_dacs = preset->num_dacs;
733 spec->multiout.dac_nids = preset->dac_nids;
734 spec->multiout.dig_out_nid = preset->dig_out_nid;
735 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 736
a1e8d2da 737 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 738 if (!spec->num_mux_defs)
a1e8d2da 739 spec->num_mux_defs = 1;
df694daa
KY
740 spec->input_mux = preset->input_mux;
741
742 spec->num_adc_nids = preset->num_adc_nids;
743 spec->adc_nids = preset->adc_nids;
e1406348 744 spec->capsrc_nids = preset->capsrc_nids;
df694daa 745 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
746
747 spec->unsol_event = preset->unsol_event;
748 spec->init_hook = preset->init_hook;
cb53c626
TI
749#ifdef CONFIG_SND_HDA_POWER_SAVE
750 spec->loopback.amplist = preset->loopbacks;
751#endif
df694daa
KY
752}
753
bc9f98a9
KY
754/* Enable GPIO mask and set output */
755static struct hda_verb alc_gpio1_init_verbs[] = {
756 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
757 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
758 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
759 { }
760};
761
762static struct hda_verb alc_gpio2_init_verbs[] = {
763 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
764 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
765 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
766 { }
767};
768
bdd148a3
KY
769static struct hda_verb alc_gpio3_init_verbs[] = {
770 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
771 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
772 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
773 { }
774};
775
2c3bf9ab
TI
776/*
777 * Fix hardware PLL issue
778 * On some codecs, the analog PLL gating control must be off while
779 * the default value is 1.
780 */
781static void alc_fix_pll(struct hda_codec *codec)
782{
783 struct alc_spec *spec = codec->spec;
784 unsigned int val;
785
786 if (!spec->pll_nid)
787 return;
788 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
789 spec->pll_coef_idx);
790 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
791 AC_VERB_GET_PROC_COEF, 0);
792 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
793 spec->pll_coef_idx);
794 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
795 val & ~(1 << spec->pll_coef_bit));
796}
797
798static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
799 unsigned int coef_idx, unsigned int coef_bit)
800{
801 struct alc_spec *spec = codec->spec;
802 spec->pll_nid = nid;
803 spec->pll_coef_idx = coef_idx;
804 spec->pll_coef_bit = coef_bit;
805 alc_fix_pll(codec);
806}
807
c9b58006
KY
808static void alc_sku_automute(struct hda_codec *codec)
809{
810 struct alc_spec *spec = codec->spec;
c9b58006
KY
811 unsigned int present;
812 unsigned int hp_nid = spec->autocfg.hp_pins[0];
813 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
814
815 /* need to execute and sync at first */
816 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
817 present = snd_hda_codec_read(codec, hp_nid, 0,
818 AC_VERB_GET_PIN_SENSE, 0);
819 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
820 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
821 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
822}
823
824/* unsolicited event for HP jack sensing */
825static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
826{
827 if (codec->vendor_id == 0x10ec0880)
828 res >>= 28;
829 else
830 res >>= 26;
831 if (res != ALC880_HP_EVENT)
832 return;
833
834 alc_sku_automute(codec);
835}
836
f9423e7a
KY
837/* additional initialization for ALC888 variants */
838static void alc888_coef_init(struct hda_codec *codec)
839{
840 unsigned int tmp;
841
842 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
843 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
844 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
845 if ((tmp & 0xf0) == 2)
846 /* alc888S-VC */
847 snd_hda_codec_read(codec, 0x20, 0,
848 AC_VERB_SET_PROC_COEF, 0x830);
849 else
850 /* alc888-VB */
851 snd_hda_codec_read(codec, 0x20, 0,
852 AC_VERB_SET_PROC_COEF, 0x3030);
853}
854
bc9f98a9
KY
855/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
856 * 31 ~ 16 : Manufacture ID
857 * 15 ~ 8 : SKU ID
858 * 7 ~ 0 : Assembly ID
859 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
860 */
861static void alc_subsystem_id(struct hda_codec *codec,
862 unsigned int porta, unsigned int porte,
863 unsigned int portd)
864{
c9b58006
KY
865 unsigned int ass, tmp, i;
866 unsigned nid;
867 struct alc_spec *spec = codec->spec;
bc9f98a9 868
c9b58006
KY
869 ass = codec->subsystem_id & 0xffff;
870 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
871 goto do_sku;
872
ea1fb29a 873 /*
c9b58006
KY
874 * 31~30 : port conetcivity
875 * 29~21 : reserve
876 * 20 : PCBEEP input
877 * 19~16 : Check sum (15:1)
878 * 15~1 : Custom
879 * 0 : override
880 */
881 nid = 0x1d;
882 if (codec->vendor_id == 0x10ec0260)
883 nid = 0x17;
884 ass = snd_hda_codec_read(codec, nid, 0,
885 AC_VERB_GET_CONFIG_DEFAULT, 0);
886 if (!(ass & 1) && !(ass & 0x100000))
887 return;
888 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
889 return;
890
c9b58006
KY
891 /* check sum */
892 tmp = 0;
893 for (i = 1; i < 16; i++) {
8c427226 894 if ((ass >> i) & 1)
c9b58006
KY
895 tmp++;
896 }
897 if (((ass >> 16) & 0xf) != tmp)
898 return;
899do_sku:
900 /*
901 * 0 : override
902 * 1 : Swap Jack
903 * 2 : 0 --> Desktop, 1 --> Laptop
904 * 3~5 : External Amplifier control
905 * 7~6 : Reserved
906 */
bc9f98a9
KY
907 tmp = (ass & 0x38) >> 3; /* external Amp control */
908 switch (tmp) {
909 case 1:
910 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
911 break;
912 case 3:
913 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
914 break;
bdd148a3
KY
915 case 7:
916 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
917 break;
c9b58006 918 case 5: /* set EAPD output high */
bdd148a3 919 switch (codec->vendor_id) {
c9b58006
KY
920 case 0x10ec0260:
921 snd_hda_codec_write(codec, 0x0f, 0,
922 AC_VERB_SET_EAPD_BTLENABLE, 2);
923 snd_hda_codec_write(codec, 0x10, 0,
924 AC_VERB_SET_EAPD_BTLENABLE, 2);
925 break;
926 case 0x10ec0262:
bdd148a3
KY
927 case 0x10ec0267:
928 case 0x10ec0268:
c9b58006 929 case 0x10ec0269:
f9423e7a
KY
930 case 0x10ec0660:
931 case 0x10ec0662:
932 case 0x10ec0663:
c9b58006 933 case 0x10ec0862:
20a3a05d 934 case 0x10ec0889:
bdd148a3
KY
935 snd_hda_codec_write(codec, 0x14, 0,
936 AC_VERB_SET_EAPD_BTLENABLE, 2);
937 snd_hda_codec_write(codec, 0x15, 0,
938 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 939 break;
bdd148a3 940 }
c9b58006
KY
941 switch (codec->vendor_id) {
942 case 0x10ec0260:
943 snd_hda_codec_write(codec, 0x1a, 0,
944 AC_VERB_SET_COEF_INDEX, 7);
945 tmp = snd_hda_codec_read(codec, 0x1a, 0,
946 AC_VERB_GET_PROC_COEF, 0);
947 snd_hda_codec_write(codec, 0x1a, 0,
948 AC_VERB_SET_COEF_INDEX, 7);
949 snd_hda_codec_write(codec, 0x1a, 0,
950 AC_VERB_SET_PROC_COEF,
951 tmp | 0x2010);
952 break;
953 case 0x10ec0262:
954 case 0x10ec0880:
955 case 0x10ec0882:
956 case 0x10ec0883:
957 case 0x10ec0885:
20a3a05d 958 case 0x10ec0889:
c9b58006
KY
959 snd_hda_codec_write(codec, 0x20, 0,
960 AC_VERB_SET_COEF_INDEX, 7);
961 tmp = snd_hda_codec_read(codec, 0x20, 0,
962 AC_VERB_GET_PROC_COEF, 0);
963 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 964 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
965 snd_hda_codec_write(codec, 0x20, 0,
966 AC_VERB_SET_PROC_COEF,
967 tmp | 0x2010);
968 break;
f9423e7a 969 case 0x10ec0888:
1082c748 970 /*alc888_coef_init(codec);*/ /* called in alc_init() */
f9423e7a 971 break;
c9b58006
KY
972 case 0x10ec0267:
973 case 0x10ec0268:
974 snd_hda_codec_write(codec, 0x20, 0,
975 AC_VERB_SET_COEF_INDEX, 7);
976 tmp = snd_hda_codec_read(codec, 0x20, 0,
977 AC_VERB_GET_PROC_COEF, 0);
978 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 979 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
980 snd_hda_codec_write(codec, 0x20, 0,
981 AC_VERB_SET_PROC_COEF,
982 tmp | 0x3000);
983 break;
bc9f98a9 984 }
c9b58006 985 default:
bc9f98a9
KY
986 break;
987 }
ea1fb29a 988
8c427226 989 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
990 * when the external headphone out jack is plugged"
991 */
8c427226 992 if (!(ass & 0x8000))
c9b58006
KY
993 return;
994 /*
995 * 10~8 : Jack location
996 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
997 * 14~13: Resvered
998 * 15 : 1 --> enable the function "Mute internal speaker
999 * when the external headphone out jack is plugged"
1000 */
1001 if (!spec->autocfg.speaker_pins[0]) {
8c427226 1002 if (spec->autocfg.line_out_pins[0])
c9b58006 1003 spec->autocfg.speaker_pins[0] =
8c427226 1004 spec->autocfg.line_out_pins[0];
c9b58006
KY
1005 else
1006 return;
1007 }
1008
1009 if (!spec->autocfg.hp_pins[0]) {
1010 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1011 if (tmp == 0)
1012 spec->autocfg.hp_pins[0] = porta;
1013 else if (tmp == 1)
1014 spec->autocfg.hp_pins[0] = porte;
1015 else if (tmp == 2)
1016 spec->autocfg.hp_pins[0] = portd;
1017 else
1018 return;
1019 }
1020
1021 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1022 AC_VERB_SET_UNSOLICITED_ENABLE,
1023 AC_USRSP_EN | ALC880_HP_EVENT);
ea1fb29a 1024
c9b58006 1025 spec->unsol_event = alc_sku_unsol_event;
bc9f98a9
KY
1026}
1027
f95474ec
TI
1028/*
1029 * Fix-up pin default configurations
1030 */
1031
1032struct alc_pincfg {
1033 hda_nid_t nid;
1034 u32 val;
1035};
1036
1037static void alc_fix_pincfg(struct hda_codec *codec,
1038 const struct snd_pci_quirk *quirk,
1039 const struct alc_pincfg **pinfix)
1040{
1041 const struct alc_pincfg *cfg;
1042
1043 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1044 if (!quirk)
1045 return;
1046
1047 cfg = pinfix[quirk->value];
1048 for (; cfg->nid; cfg++) {
1049 int i;
1050 u32 val = cfg->val;
1051 for (i = 0; i < 4; i++) {
1052 snd_hda_codec_write(codec, cfg->nid, 0,
1053 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1054 val & 0xff);
1055 val >>= 8;
1056 }
1057 }
1058}
1059
1da177e4 1060/*
e9edcee0
TI
1061 * ALC880 3-stack model
1062 *
1063 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1064 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1065 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1066 */
1067
e9edcee0
TI
1068static hda_nid_t alc880_dac_nids[4] = {
1069 /* front, rear, clfe, rear_surr */
1070 0x02, 0x05, 0x04, 0x03
1071};
1072
1073static hda_nid_t alc880_adc_nids[3] = {
1074 /* ADC0-2 */
1075 0x07, 0x08, 0x09,
1076};
1077
1078/* The datasheet says the node 0x07 is connected from inputs,
1079 * but it shows zero connection in the real implementation on some devices.
df694daa 1080 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1081 */
e9edcee0
TI
1082static hda_nid_t alc880_adc_nids_alt[2] = {
1083 /* ADC1-2 */
1084 0x08, 0x09,
1085};
1086
1087#define ALC880_DIGOUT_NID 0x06
1088#define ALC880_DIGIN_NID 0x0a
1089
1090static struct hda_input_mux alc880_capture_source = {
1091 .num_items = 4,
1092 .items = {
1093 { "Mic", 0x0 },
1094 { "Front Mic", 0x3 },
1095 { "Line", 0x2 },
1096 { "CD", 0x4 },
1097 },
1098};
1099
1100/* channel source setting (2/6 channel selection for 3-stack) */
1101/* 2ch mode */
1102static struct hda_verb alc880_threestack_ch2_init[] = {
1103 /* set line-in to input, mute it */
1104 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1105 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1106 /* set mic-in to input vref 80%, mute it */
1107 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1108 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1109 { } /* end */
1110};
1111
1112/* 6ch mode */
1113static struct hda_verb alc880_threestack_ch6_init[] = {
1114 /* set line-in to output, unmute it */
1115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1117 /* set mic-in to output, unmute it */
1118 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1119 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1120 { } /* end */
1121};
1122
d2a6d7dc 1123static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1124 { 2, alc880_threestack_ch2_init },
1125 { 6, alc880_threestack_ch6_init },
1126};
1127
c8b6bf9b 1128static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1129 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1130 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1131 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1132 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1133 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1134 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1135 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1136 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1137 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1138 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1139 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1140 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1142 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1143 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1144 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1145 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1146 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1148 {
1149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1150 .name = "Channel Mode",
df694daa
KY
1151 .info = alc_ch_mode_info,
1152 .get = alc_ch_mode_get,
1153 .put = alc_ch_mode_put,
e9edcee0
TI
1154 },
1155 { } /* end */
1156};
1157
1158/* capture mixer elements */
c8b6bf9b 1159static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1160 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1161 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1162 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1163 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1164 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1165 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1166 {
1167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1168 /* The multiple "Capture Source" controls confuse alsamixer
1169 * So call somewhat different..
1da177e4
LT
1170 */
1171 /* .name = "Capture Source", */
1172 .name = "Input Source",
e9edcee0 1173 .count = 3,
1da177e4
LT
1174 .info = alc_mux_enum_info,
1175 .get = alc_mux_enum_get,
1176 .put = alc_mux_enum_put,
1177 },
1da177e4
LT
1178 { } /* end */
1179};
1180
e9edcee0 1181/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1182static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1183 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1184 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1185 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1186 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1187 {
1188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1189 /* The multiple "Capture Source" controls confuse alsamixer
1190 * So call somewhat different..
1da177e4
LT
1191 */
1192 /* .name = "Capture Source", */
1193 .name = "Input Source",
1194 .count = 2,
1195 .info = alc_mux_enum_info,
1196 .get = alc_mux_enum_get,
1197 .put = alc_mux_enum_put,
1198 },
1da177e4
LT
1199 { } /* end */
1200};
1201
e9edcee0
TI
1202
1203
1204/*
1205 * ALC880 5-stack model
1206 *
9c7f852e
TI
1207 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1208 * Side = 0x02 (0xd)
e9edcee0
TI
1209 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1210 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1211 */
1212
1213/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1214static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1215 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1216 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1217 { } /* end */
1218};
1219
e9edcee0
TI
1220/* channel source setting (6/8 channel selection for 5-stack) */
1221/* 6ch mode */
1222static struct hda_verb alc880_fivestack_ch6_init[] = {
1223 /* set line-in to input, mute it */
1224 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1225 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1226 { } /* end */
1227};
1228
e9edcee0
TI
1229/* 8ch mode */
1230static struct hda_verb alc880_fivestack_ch8_init[] = {
1231 /* set line-in to output, unmute it */
1232 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1233 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1234 { } /* end */
1235};
1236
d2a6d7dc 1237static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1238 { 6, alc880_fivestack_ch6_init },
1239 { 8, alc880_fivestack_ch8_init },
1240};
1241
1242
1243/*
1244 * ALC880 6-stack model
1245 *
9c7f852e
TI
1246 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1247 * Side = 0x05 (0x0f)
e9edcee0
TI
1248 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1249 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1250 */
1251
1252static hda_nid_t alc880_6st_dac_nids[4] = {
1253 /* front, rear, clfe, rear_surr */
1254 0x02, 0x03, 0x04, 0x05
f12ab1e0 1255};
e9edcee0
TI
1256
1257static struct hda_input_mux alc880_6stack_capture_source = {
1258 .num_items = 4,
1259 .items = {
1260 { "Mic", 0x0 },
1261 { "Front Mic", 0x1 },
1262 { "Line", 0x2 },
1263 { "CD", 0x4 },
1264 },
1265};
1266
1267/* fixed 8-channels */
d2a6d7dc 1268static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1269 { 8, NULL },
1270};
1271
c8b6bf9b 1272static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1273 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1274 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1275 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1276 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1277 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1278 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1279 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1280 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1281 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1282 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1289 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1290 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1291 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1292 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1293 {
1294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1295 .name = "Channel Mode",
df694daa
KY
1296 .info = alc_ch_mode_info,
1297 .get = alc_ch_mode_get,
1298 .put = alc_ch_mode_put,
16ded525
TI
1299 },
1300 { } /* end */
1301};
1302
e9edcee0
TI
1303
1304/*
1305 * ALC880 W810 model
1306 *
1307 * W810 has rear IO for:
1308 * Front (DAC 02)
1309 * Surround (DAC 03)
1310 * Center/LFE (DAC 04)
1311 * Digital out (06)
1312 *
1313 * The system also has a pair of internal speakers, and a headphone jack.
1314 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 1315 *
e9edcee0
TI
1316 * There is a variable resistor to control the speaker or headphone
1317 * volume. This is a hardware-only device without a software API.
1318 *
1319 * Plugging headphones in will disable the internal speakers. This is
1320 * implemented in hardware, not via the driver using jack sense. In
1321 * a similar fashion, plugging into the rear socket marked "front" will
1322 * disable both the speakers and headphones.
1323 *
1324 * For input, there's a microphone jack, and an "audio in" jack.
1325 * These may not do anything useful with this driver yet, because I
1326 * haven't setup any initialization verbs for these yet...
1327 */
1328
1329static hda_nid_t alc880_w810_dac_nids[3] = {
1330 /* front, rear/surround, clfe */
1331 0x02, 0x03, 0x04
16ded525
TI
1332};
1333
e9edcee0 1334/* fixed 6 channels */
d2a6d7dc 1335static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1336 { 6, NULL }
1337};
1338
1339/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1340static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1341 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1342 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1343 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1344 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1345 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1346 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1347 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1348 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1349 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1350 { } /* end */
1351};
1352
1353
1354/*
1355 * Z710V model
1356 *
1357 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1358 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1359 * Line = 0x1a
e9edcee0
TI
1360 */
1361
1362static hda_nid_t alc880_z71v_dac_nids[1] = {
1363 0x02
1364};
1365#define ALC880_Z71V_HP_DAC 0x03
1366
1367/* fixed 2 channels */
d2a6d7dc 1368static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1369 { 2, NULL }
1370};
1371
c8b6bf9b 1372static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1373 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1374 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1375 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1376 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1377 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1378 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1381 { } /* end */
1382};
1383
e9edcee0 1384
e9edcee0
TI
1385/*
1386 * ALC880 F1734 model
1387 *
1388 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1389 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1390 */
1391
1392static hda_nid_t alc880_f1734_dac_nids[1] = {
1393 0x03
1394};
1395#define ALC880_F1734_HP_DAC 0x02
1396
c8b6bf9b 1397static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1398 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1399 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1400 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1401 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1406 { } /* end */
1407};
1408
937b4160
TI
1409static struct hda_input_mux alc880_f1734_capture_source = {
1410 .num_items = 2,
1411 .items = {
1412 { "Mic", 0x1 },
1413 { "CD", 0x4 },
1414 },
1415};
1416
e9edcee0 1417
e9edcee0
TI
1418/*
1419 * ALC880 ASUS model
1420 *
1421 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1422 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1423 * Mic = 0x18, Line = 0x1a
1424 */
1425
1426#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1427#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1428
c8b6bf9b 1429static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1432 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1433 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1434 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1435 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1436 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1437 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1438 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1439 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1440 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1441 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1443 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1444 {
1445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1446 .name = "Channel Mode",
df694daa
KY
1447 .info = alc_ch_mode_info,
1448 .get = alc_ch_mode_get,
1449 .put = alc_ch_mode_put,
16ded525
TI
1450 },
1451 { } /* end */
1452};
e9edcee0 1453
e9edcee0
TI
1454/*
1455 * ALC880 ASUS W1V model
1456 *
1457 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1458 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1459 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1460 */
1461
1462/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1463static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1464 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1465 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1466 { } /* end */
1467};
1468
3c10a9d9 1469/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1470static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1471 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1472 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1473 { } /* end */
1474};
e9edcee0 1475
df694daa
KY
1476/* TCL S700 */
1477static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1479 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1481 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1482 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1485 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1486 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1487 {
1488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1489 /* The multiple "Capture Source" controls confuse alsamixer
1490 * So call somewhat different..
df694daa
KY
1491 */
1492 /* .name = "Capture Source", */
1493 .name = "Input Source",
1494 .count = 1,
1495 .info = alc_mux_enum_info,
1496 .get = alc_mux_enum_get,
1497 .put = alc_mux_enum_put,
1498 },
1499 { } /* end */
1500};
1501
ccc656ce
KY
1502/* Uniwill */
1503static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1504 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1505 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1506 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1507 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1508 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1509 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1510 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1511 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1512 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1513 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1515 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1518 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1520 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1521 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1522 {
1523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1524 .name = "Channel Mode",
1525 .info = alc_ch_mode_info,
1526 .get = alc_ch_mode_get,
1527 .put = alc_ch_mode_put,
1528 },
1529 { } /* end */
1530};
1531
2cf9f0fc
TD
1532static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1534 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1535 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1536 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1539 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1540 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1541 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1542 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1543 { } /* end */
1544};
1545
ccc656ce 1546static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1547 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1548 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1549 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1550 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1553 { } /* end */
1554};
1555
2134ea4f
TI
1556/*
1557 * virtual master controls
1558 */
1559
1560/*
1561 * slave controls for virtual master
1562 */
1563static const char *alc_slave_vols[] = {
1564 "Front Playback Volume",
1565 "Surround Playback Volume",
1566 "Center Playback Volume",
1567 "LFE Playback Volume",
1568 "Side Playback Volume",
1569 "Headphone Playback Volume",
1570 "Speaker Playback Volume",
1571 "Mono Playback Volume",
2134ea4f
TI
1572 "Line-Out Playback Volume",
1573 NULL,
1574};
1575
1576static const char *alc_slave_sws[] = {
1577 "Front Playback Switch",
1578 "Surround Playback Switch",
1579 "Center Playback Switch",
1580 "LFE Playback Switch",
1581 "Side Playback Switch",
1582 "Headphone Playback Switch",
1583 "Speaker Playback Switch",
1584 "Mono Playback Switch",
edb54a55 1585 "IEC958 Playback Switch",
2134ea4f
TI
1586 NULL,
1587};
1588
1da177e4 1589/*
e9edcee0 1590 * build control elements
1da177e4
LT
1591 */
1592static int alc_build_controls(struct hda_codec *codec)
1593{
1594 struct alc_spec *spec = codec->spec;
1595 int err;
1596 int i;
1597
1598 for (i = 0; i < spec->num_mixers; i++) {
1599 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1600 if (err < 0)
1601 return err;
1602 }
1603
1604 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1605 err = snd_hda_create_spdif_out_ctls(codec,
1606 spec->multiout.dig_out_nid);
1da177e4
LT
1607 if (err < 0)
1608 return err;
9a08160b
TI
1609 err = snd_hda_create_spdif_share_sw(codec,
1610 &spec->multiout);
1611 if (err < 0)
1612 return err;
1613 spec->multiout.share_spdif = 1;
1da177e4
LT
1614 }
1615 if (spec->dig_in_nid) {
1616 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1617 if (err < 0)
1618 return err;
1619 }
2134ea4f
TI
1620
1621 /* if we have no master control, let's create it */
1622 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 1623 unsigned int vmaster_tlv[4];
2134ea4f 1624 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 1625 HDA_OUTPUT, vmaster_tlv);
2134ea4f 1626 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 1627 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
1628 if (err < 0)
1629 return err;
1630 }
1631 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1632 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1633 NULL, alc_slave_sws);
1634 if (err < 0)
1635 return err;
1636 }
1637
1da177e4
LT
1638 return 0;
1639}
1640
e9edcee0 1641
1da177e4
LT
1642/*
1643 * initialize the codec volumes, etc
1644 */
1645
e9edcee0
TI
1646/*
1647 * generic initialization of ADC, input mixers and output mixers
1648 */
1649static struct hda_verb alc880_volume_init_verbs[] = {
1650 /*
1651 * Unmute ADC0-2 and set the default input to mic-in
1652 */
71fe7b82 1653 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1655 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1657 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1659
e9edcee0
TI
1660 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1661 * mixer widget
9c7f852e
TI
1662 * Note: PASD motherboards uses the Line In 2 as the input for front
1663 * panel mic (mic 2)
1da177e4 1664 */
e9edcee0 1665 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1666 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1667 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1668 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1669 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1672 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1673
e9edcee0
TI
1674 /*
1675 * Set up output mixers (0x0c - 0x0f)
1da177e4 1676 */
e9edcee0
TI
1677 /* set vol=0 to output mixers */
1678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1680 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1681 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1682 /* set up input amps for analog loopback */
1683 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1690 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1691 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1692
1693 { }
1694};
1695
e9edcee0
TI
1696/*
1697 * 3-stack pin configuration:
1698 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1699 */
1700static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1701 /*
1702 * preset connection lists of input pins
1703 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1704 */
1705 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1706 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1707 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1708
1709 /*
1710 * Set pin mode and muting
1711 */
1712 /* set front pin widgets 0x14 for output */
05acb863 1713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1715 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1718 /* Mic2 (as headphone out) for HP output */
1719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1721 /* Line In pin widget for input */
05acb863 1722 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1723 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1724 /* Line2 (as front mic) pin widget for input and vref at 80% */
1725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1726 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1727 /* CD pin widget for input */
05acb863 1728 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1729
e9edcee0
TI
1730 { }
1731};
1da177e4 1732
e9edcee0
TI
1733/*
1734 * 5-stack pin configuration:
1735 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1736 * line-in/side = 0x1a, f-mic = 0x1b
1737 */
1738static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1739 /*
1740 * preset connection lists of input pins
1741 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1742 */
e9edcee0
TI
1743 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1744 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1745
e9edcee0
TI
1746 /*
1747 * Set pin mode and muting
1da177e4 1748 */
e9edcee0
TI
1749 /* set pin widgets 0x14-0x17 for output */
1750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1752 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1753 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1754 /* unmute pins for output (no gain on this amp) */
1755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1758 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1759
1760 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1761 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1762 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1763 /* Mic2 (as headphone out) for HP output */
1764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1766 /* Line In pin widget for input */
1767 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1768 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1769 /* Line2 (as front mic) pin widget for input and vref at 80% */
1770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1771 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1772 /* CD pin widget for input */
1773 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1774
1775 { }
1776};
1777
e9edcee0
TI
1778/*
1779 * W810 pin configuration:
1780 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1781 */
1782static struct hda_verb alc880_pin_w810_init_verbs[] = {
1783 /* hphone/speaker input selector: front DAC */
1784 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1785
05acb863 1786 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1789 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1790 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1791 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1792
e9edcee0 1793 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1794 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1795
1da177e4
LT
1796 { }
1797};
1798
e9edcee0
TI
1799/*
1800 * Z71V pin configuration:
1801 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1802 */
1803static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1808
16ded525 1809 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1810 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1811 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1813
1814 { }
1815};
1816
e9edcee0
TI
1817/*
1818 * 6-stack pin configuration:
9c7f852e
TI
1819 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1820 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1821 */
1822static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1823 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1824
16ded525 1825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1826 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1827 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1829 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1831 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1833
16ded525 1834 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1836 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1838 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1840 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1841 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1842 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 1843
e9edcee0
TI
1844 { }
1845};
1846
ccc656ce
KY
1847/*
1848 * Uniwill pin configuration:
1849 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1850 * line = 0x1a
1851 */
1852static struct hda_verb alc880_uniwill_init_verbs[] = {
1853 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1854
1855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1861 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1862 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1869
1870 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1872 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1874 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1875 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1876 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1877 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1878 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1879
1880 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1881 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1882
1883 { }
1884};
1885
1886/*
1887* Uniwill P53
ea1fb29a 1888* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
1889 */
1890static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1891 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1892
1893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1896 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1897 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1900 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1901 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1902 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1903 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1905
1906 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1908 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1909 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1912
1913 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1914 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1915
1916 { }
1917};
1918
2cf9f0fc
TD
1919static struct hda_verb alc880_beep_init_verbs[] = {
1920 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1921 { }
1922};
1923
ccc656ce 1924/* toggle speaker-output according to the hp-jack state */
458a4fab 1925static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1926{
1927 unsigned int present;
f12ab1e0 1928 unsigned char bits;
ccc656ce
KY
1929
1930 present = snd_hda_codec_read(codec, 0x14, 0,
1931 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1932 bits = present ? HDA_AMP_MUTE : 0;
1933 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1934 HDA_AMP_MUTE, bits);
1935 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1936 HDA_AMP_MUTE, bits);
458a4fab
TI
1937}
1938
1939/* auto-toggle front mic */
1940static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1941{
1942 unsigned int present;
1943 unsigned char bits;
ccc656ce
KY
1944
1945 present = snd_hda_codec_read(codec, 0x18, 0,
1946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1947 bits = present ? HDA_AMP_MUTE : 0;
1948 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1949}
1950
1951static void alc880_uniwill_automute(struct hda_codec *codec)
1952{
1953 alc880_uniwill_hp_automute(codec);
1954 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1955}
1956
1957static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1958 unsigned int res)
1959{
1960 /* Looks like the unsol event is incompatible with the standard
1961 * definition. 4bit tag is placed at 28 bit!
1962 */
458a4fab
TI
1963 switch (res >> 28) {
1964 case ALC880_HP_EVENT:
1965 alc880_uniwill_hp_automute(codec);
1966 break;
1967 case ALC880_MIC_EVENT:
1968 alc880_uniwill_mic_automute(codec);
1969 break;
1970 }
ccc656ce
KY
1971}
1972
1973static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1974{
1975 unsigned int present;
f12ab1e0 1976 unsigned char bits;
ccc656ce
KY
1977
1978 present = snd_hda_codec_read(codec, 0x14, 0,
1979 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a 1980 bits = present ? HDA_AMP_MUTE : 0;
64654c2f 1981 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1982}
1983
1984static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1985{
1986 unsigned int present;
ea1fb29a 1987
ccc656ce 1988 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1989 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1990 present &= HDA_AMP_VOLMASK;
1991 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1992 HDA_AMP_VOLMASK, present);
1993 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1994 HDA_AMP_VOLMASK, present);
ccc656ce 1995}
47fd830a 1996
ccc656ce
KY
1997static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1998 unsigned int res)
1999{
2000 /* Looks like the unsol event is incompatible with the standard
2001 * definition. 4bit tag is placed at 28 bit!
2002 */
2003 if ((res >> 28) == ALC880_HP_EVENT)
2004 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 2005 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
2006 alc880_uniwill_p53_dcvol_automute(codec);
2007}
2008
e9edcee0
TI
2009/*
2010 * F1734 pin configuration:
2011 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2012 */
2013static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2014 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2015 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2016 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2017 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2018 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2019
e9edcee0 2020 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2021 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2022 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2023 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2024
e9edcee0
TI
2025 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2026 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2028 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2030 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2031 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2032 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2033 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2034
937b4160
TI
2035 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2036 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2037
dfc0ff62
TI
2038 { }
2039};
2040
e9edcee0
TI
2041/*
2042 * ASUS pin configuration:
2043 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2044 */
2045static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2046 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2047 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2048 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2049 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2050
2051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2052 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2055 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2057 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2059
2060 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2061 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2062 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2063 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2064 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2067 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2068 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2069
e9edcee0
TI
2070 { }
2071};
16ded525 2072
e9edcee0 2073/* Enable GPIO mask and set output */
bc9f98a9
KY
2074#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2075#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
2076
2077/* Clevo m520g init */
2078static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2079 /* headphone output */
2080 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2081 /* line-out */
2082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2083 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2084 /* Line-in */
2085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2087 /* CD */
2088 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2089 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090 /* Mic1 (rear panel) */
2091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2093 /* Mic2 (front panel) */
2094 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2095 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2096 /* headphone */
2097 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2099 /* change to EAPD mode */
2100 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2101 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2102
2103 { }
16ded525
TI
2104};
2105
df694daa 2106static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2107 /* change to EAPD mode */
2108 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2109 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2110
df694daa
KY
2111 /* Headphone output */
2112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2113 /* Front output*/
2114 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2115 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2116
2117 /* Line In pin widget for input */
2118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2119 /* CD pin widget for input */
2120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2121 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2123
2124 /* change to EAPD mode */
2125 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2126 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2127
2128 { }
2129};
16ded525 2130
e9edcee0 2131/*
ae6b813a
TI
2132 * LG m1 express dual
2133 *
2134 * Pin assignment:
2135 * Rear Line-In/Out (blue): 0x14
2136 * Build-in Mic-In: 0x15
2137 * Speaker-out: 0x17
2138 * HP-Out (green): 0x1b
2139 * Mic-In/Out (red): 0x19
2140 * SPDIF-Out: 0x1e
2141 */
2142
2143/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2144static hda_nid_t alc880_lg_dac_nids[3] = {
2145 0x05, 0x02, 0x03
2146};
2147
2148/* seems analog CD is not working */
2149static struct hda_input_mux alc880_lg_capture_source = {
2150 .num_items = 3,
2151 .items = {
2152 { "Mic", 0x1 },
2153 { "Line", 0x5 },
2154 { "Internal Mic", 0x6 },
2155 },
2156};
2157
2158/* 2,4,6 channel modes */
2159static struct hda_verb alc880_lg_ch2_init[] = {
2160 /* set line-in and mic-in to input */
2161 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2162 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2163 { }
2164};
2165
2166static struct hda_verb alc880_lg_ch4_init[] = {
2167 /* set line-in to out and mic-in to input */
2168 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2169 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2170 { }
2171};
2172
2173static struct hda_verb alc880_lg_ch6_init[] = {
2174 /* set line-in and mic-in to output */
2175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2176 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2177 { }
2178};
2179
2180static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2181 { 2, alc880_lg_ch2_init },
2182 { 4, alc880_lg_ch4_init },
2183 { 6, alc880_lg_ch6_init },
2184};
2185
2186static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2187 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2188 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2189 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2190 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2191 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2192 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2193 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2194 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2200 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2201 {
2202 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2203 .name = "Channel Mode",
2204 .info = alc_ch_mode_info,
2205 .get = alc_ch_mode_get,
2206 .put = alc_ch_mode_put,
2207 },
2208 { } /* end */
2209};
2210
2211static struct hda_verb alc880_lg_init_verbs[] = {
2212 /* set capture source to mic-in */
2213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2214 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2216 /* mute all amp mixer inputs */
2217 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2220 /* line-in to input */
2221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 /* built-in mic */
2224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226 /* speaker-out */
2227 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2228 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 /* mic-in to input */
2230 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2231 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2232 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233 /* HP-out */
2234 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2235 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2236 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2237 /* jack sense */
2238 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2239 { }
2240};
2241
2242/* toggle speaker-output according to the hp-jack state */
2243static void alc880_lg_automute(struct hda_codec *codec)
2244{
2245 unsigned int present;
f12ab1e0 2246 unsigned char bits;
ae6b813a
TI
2247
2248 present = snd_hda_codec_read(codec, 0x1b, 0,
2249 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2250 bits = present ? HDA_AMP_MUTE : 0;
2251 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2252 HDA_AMP_MUTE, bits);
ae6b813a
TI
2253}
2254
2255static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2256{
2257 /* Looks like the unsol event is incompatible with the standard
2258 * definition. 4bit tag is placed at 28 bit!
2259 */
2260 if ((res >> 28) == 0x01)
2261 alc880_lg_automute(codec);
2262}
2263
d681518a
TI
2264/*
2265 * LG LW20
2266 *
2267 * Pin assignment:
2268 * Speaker-out: 0x14
2269 * Mic-In: 0x18
e4f41da9
CM
2270 * Built-in Mic-In: 0x19
2271 * Line-In: 0x1b
2272 * HP-Out: 0x1a
d681518a
TI
2273 * SPDIF-Out: 0x1e
2274 */
2275
d681518a 2276static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2277 .num_items = 3,
d681518a
TI
2278 .items = {
2279 { "Mic", 0x0 },
2280 { "Internal Mic", 0x1 },
e4f41da9 2281 { "Line In", 0x2 },
d681518a
TI
2282 },
2283};
2284
0a8c5da3
CM
2285#define alc880_lg_lw_modes alc880_threestack_modes
2286
d681518a 2287static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2289 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2290 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2291 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2292 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2293 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2294 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2295 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2296 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2297 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2301 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2302 {
2303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2304 .name = "Channel Mode",
2305 .info = alc_ch_mode_info,
2306 .get = alc_ch_mode_get,
2307 .put = alc_ch_mode_put,
2308 },
d681518a
TI
2309 { } /* end */
2310};
2311
2312static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2313 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2314 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2315 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2316
d681518a
TI
2317 /* set capture source to mic-in */
2318 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2321 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2322 /* speaker-out */
2323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2325 /* HP-out */
d681518a
TI
2326 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2327 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 /* mic-in to input */
2329 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2330 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2331 /* built-in mic */
2332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2334 /* jack sense */
2335 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2336 { }
2337};
2338
2339/* toggle speaker-output according to the hp-jack state */
2340static void alc880_lg_lw_automute(struct hda_codec *codec)
2341{
2342 unsigned int present;
f12ab1e0 2343 unsigned char bits;
d681518a
TI
2344
2345 present = snd_hda_codec_read(codec, 0x1b, 0,
2346 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2347 bits = present ? HDA_AMP_MUTE : 0;
2348 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2349 HDA_AMP_MUTE, bits);
d681518a
TI
2350}
2351
2352static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2353{
2354 /* Looks like the unsol event is incompatible with the standard
2355 * definition. 4bit tag is placed at 28 bit!
2356 */
2357 if ((res >> 28) == 0x01)
2358 alc880_lg_lw_automute(codec);
2359}
2360
df99cd33
TI
2361static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2362 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2363 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
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, 0x1, HDA_INPUT),
2367 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2368 { } /* end */
2369};
2370
2371static struct hda_input_mux alc880_medion_rim_capture_source = {
2372 .num_items = 2,
2373 .items = {
2374 { "Mic", 0x0 },
2375 { "Internal Mic", 0x1 },
2376 },
2377};
2378
2379static struct hda_verb alc880_medion_rim_init_verbs[] = {
2380 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2381
2382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2383 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2384
2385 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2388 /* Mic2 (as headphone out) for HP output */
2389 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2390 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2391 /* Internal Speaker */
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394
2395 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2396 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2397
2398 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2399 { }
2400};
2401
2402/* toggle speaker-output according to the hp-jack state */
2403static void alc880_medion_rim_automute(struct hda_codec *codec)
2404{
2405 unsigned int present;
2406 unsigned char bits;
2407
2408 present = snd_hda_codec_read(codec, 0x14, 0,
2409 AC_VERB_GET_PIN_SENSE, 0)
2410 & AC_PINSENSE_PRESENCE;
2411 bits = present ? HDA_AMP_MUTE : 0;
2412 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2413 HDA_AMP_MUTE, bits);
2414 if (present)
2415 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2416 else
2417 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2418}
2419
2420static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2421 unsigned int res)
2422{
2423 /* Looks like the unsol event is incompatible with the standard
2424 * definition. 4bit tag is placed at 28 bit!
2425 */
2426 if ((res >> 28) == ALC880_HP_EVENT)
2427 alc880_medion_rim_automute(codec);
2428}
2429
cb53c626
TI
2430#ifdef CONFIG_SND_HDA_POWER_SAVE
2431static struct hda_amp_list alc880_loopbacks[] = {
2432 { 0x0b, HDA_INPUT, 0 },
2433 { 0x0b, HDA_INPUT, 1 },
2434 { 0x0b, HDA_INPUT, 2 },
2435 { 0x0b, HDA_INPUT, 3 },
2436 { 0x0b, HDA_INPUT, 4 },
2437 { } /* end */
2438};
2439
2440static struct hda_amp_list alc880_lg_loopbacks[] = {
2441 { 0x0b, HDA_INPUT, 1 },
2442 { 0x0b, HDA_INPUT, 6 },
2443 { 0x0b, HDA_INPUT, 7 },
2444 { } /* end */
2445};
2446#endif
2447
ae6b813a
TI
2448/*
2449 * Common callbacks
e9edcee0
TI
2450 */
2451
1da177e4
LT
2452static int alc_init(struct hda_codec *codec)
2453{
2454 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2455 unsigned int i;
2456
2c3bf9ab 2457 alc_fix_pll(codec);
1082c748
TI
2458 if (codec->vendor_id == 0x10ec0888)
2459 alc888_coef_init(codec);
2c3bf9ab 2460
e9edcee0
TI
2461 for (i = 0; i < spec->num_init_verbs; i++)
2462 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2463
2464 if (spec->init_hook)
2465 spec->init_hook(codec);
2466
1da177e4
LT
2467 return 0;
2468}
2469
ae6b813a
TI
2470static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2471{
2472 struct alc_spec *spec = codec->spec;
2473
2474 if (spec->unsol_event)
2475 spec->unsol_event(codec, res);
2476}
2477
cb53c626
TI
2478#ifdef CONFIG_SND_HDA_POWER_SAVE
2479static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2480{
2481 struct alc_spec *spec = codec->spec;
2482 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2483}
2484#endif
2485
1da177e4
LT
2486/*
2487 * Analog playback callbacks
2488 */
2489static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2490 struct hda_codec *codec,
c8b6bf9b 2491 struct snd_pcm_substream *substream)
1da177e4
LT
2492{
2493 struct alc_spec *spec = codec->spec;
9a08160b
TI
2494 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2495 hinfo);
1da177e4
LT
2496}
2497
2498static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2499 struct hda_codec *codec,
2500 unsigned int stream_tag,
2501 unsigned int format,
c8b6bf9b 2502 struct snd_pcm_substream *substream)
1da177e4
LT
2503{
2504 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2505 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2506 stream_tag, format, substream);
1da177e4
LT
2507}
2508
2509static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2510 struct hda_codec *codec,
c8b6bf9b 2511 struct snd_pcm_substream *substream)
1da177e4
LT
2512{
2513 struct alc_spec *spec = codec->spec;
2514 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2515}
2516
2517/*
2518 * Digital out
2519 */
2520static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2521 struct hda_codec *codec,
c8b6bf9b 2522 struct snd_pcm_substream *substream)
1da177e4
LT
2523{
2524 struct alc_spec *spec = codec->spec;
2525 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2526}
2527
6b97eb45
TI
2528static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2529 struct hda_codec *codec,
2530 unsigned int stream_tag,
2531 unsigned int format,
2532 struct snd_pcm_substream *substream)
2533{
2534 struct alc_spec *spec = codec->spec;
2535 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2536 stream_tag, format, substream);
2537}
2538
1da177e4
LT
2539static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2540 struct hda_codec *codec,
c8b6bf9b 2541 struct snd_pcm_substream *substream)
1da177e4
LT
2542{
2543 struct alc_spec *spec = codec->spec;
2544 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2545}
2546
2547/*
2548 * Analog capture
2549 */
6330079f 2550static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2551 struct hda_codec *codec,
2552 unsigned int stream_tag,
2553 unsigned int format,
c8b6bf9b 2554 struct snd_pcm_substream *substream)
1da177e4
LT
2555{
2556 struct alc_spec *spec = codec->spec;
2557
6330079f 2558 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2559 stream_tag, 0, format);
2560 return 0;
2561}
2562
6330079f 2563static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2564 struct hda_codec *codec,
c8b6bf9b 2565 struct snd_pcm_substream *substream)
1da177e4
LT
2566{
2567 struct alc_spec *spec = codec->spec;
2568
888afa15
TI
2569 snd_hda_codec_cleanup_stream(codec,
2570 spec->adc_nids[substream->number + 1]);
1da177e4
LT
2571 return 0;
2572}
2573
2574
2575/*
2576 */
2577static struct hda_pcm_stream alc880_pcm_analog_playback = {
2578 .substreams = 1,
2579 .channels_min = 2,
2580 .channels_max = 8,
e9edcee0 2581 /* NID is set in alc_build_pcms */
1da177e4
LT
2582 .ops = {
2583 .open = alc880_playback_pcm_open,
2584 .prepare = alc880_playback_pcm_prepare,
2585 .cleanup = alc880_playback_pcm_cleanup
2586 },
2587};
2588
2589static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2590 .substreams = 1,
2591 .channels_min = 2,
2592 .channels_max = 2,
2593 /* NID is set in alc_build_pcms */
2594};
2595
2596static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2597 .substreams = 1,
2598 .channels_min = 2,
2599 .channels_max = 2,
2600 /* NID is set in alc_build_pcms */
2601};
2602
2603static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2604 .substreams = 2, /* can be overridden */
1da177e4
LT
2605 .channels_min = 2,
2606 .channels_max = 2,
e9edcee0 2607 /* NID is set in alc_build_pcms */
1da177e4 2608 .ops = {
6330079f
TI
2609 .prepare = alc880_alt_capture_pcm_prepare,
2610 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2611 },
2612};
2613
2614static struct hda_pcm_stream alc880_pcm_digital_playback = {
2615 .substreams = 1,
2616 .channels_min = 2,
2617 .channels_max = 2,
2618 /* NID is set in alc_build_pcms */
2619 .ops = {
2620 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2621 .close = alc880_dig_playback_pcm_close,
2622 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2623 },
2624};
2625
2626static struct hda_pcm_stream alc880_pcm_digital_capture = {
2627 .substreams = 1,
2628 .channels_min = 2,
2629 .channels_max = 2,
2630 /* NID is set in alc_build_pcms */
2631};
2632
4c5186ed 2633/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2634static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2635 .substreams = 0,
2636 .channels_min = 0,
2637 .channels_max = 0,
2638};
2639
1da177e4
LT
2640static int alc_build_pcms(struct hda_codec *codec)
2641{
2642 struct alc_spec *spec = codec->spec;
2643 struct hda_pcm *info = spec->pcm_rec;
2644 int i;
2645
2646 codec->num_pcms = 1;
2647 codec->pcm_info = info;
2648
2649 info->name = spec->stream_name_analog;
4a471b7d 2650 if (spec->stream_analog_playback) {
da3cec35
TI
2651 if (snd_BUG_ON(!spec->multiout.dac_nids))
2652 return -EINVAL;
4a471b7d
TI
2653 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2654 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2655 }
2656 if (spec->stream_analog_capture) {
da3cec35
TI
2657 if (snd_BUG_ON(!spec->adc_nids))
2658 return -EINVAL;
4a471b7d
TI
2659 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2660 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2661 }
2662
2663 if (spec->channel_mode) {
2664 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2665 for (i = 0; i < spec->num_channel_mode; i++) {
2666 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2667 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2668 }
1da177e4
LT
2669 }
2670 }
2671
e08a007d 2672 /* SPDIF for stream index #1 */
1da177e4 2673 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2674 codec->num_pcms = 2;
c06134d7 2675 info = spec->pcm_rec + 1;
1da177e4 2676 info->name = spec->stream_name_digital;
7ba72ba1 2677 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2678 if (spec->multiout.dig_out_nid &&
2679 spec->stream_digital_playback) {
1da177e4
LT
2680 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2681 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2682 }
4a471b7d
TI
2683 if (spec->dig_in_nid &&
2684 spec->stream_digital_capture) {
1da177e4
LT
2685 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2686 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2687 }
963f803f
TI
2688 /* FIXME: do we need this for all Realtek codec models? */
2689 codec->spdif_status_reset = 1;
1da177e4
LT
2690 }
2691
e08a007d
TI
2692 /* If the use of more than one ADC is requested for the current
2693 * model, configure a second analog capture-only PCM.
2694 */
2695 /* Additional Analaog capture for index #2 */
6330079f
TI
2696 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2697 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2698 codec->num_pcms = 3;
c06134d7 2699 info = spec->pcm_rec + 2;
e08a007d 2700 info->name = spec->stream_name_analog;
6330079f
TI
2701 if (spec->alt_dac_nid) {
2702 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2703 *spec->stream_analog_alt_playback;
2704 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2705 spec->alt_dac_nid;
2706 } else {
2707 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2708 alc_pcm_null_stream;
2709 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2710 }
2711 if (spec->num_adc_nids > 1) {
2712 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2713 *spec->stream_analog_alt_capture;
2714 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2715 spec->adc_nids[1];
2716 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2717 spec->num_adc_nids - 1;
2718 } else {
2719 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2720 alc_pcm_null_stream;
2721 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2722 }
2723 }
2724
1da177e4
LT
2725 return 0;
2726}
2727
2728static void alc_free(struct hda_codec *codec)
2729{
e9edcee0
TI
2730 struct alc_spec *spec = codec->spec;
2731 unsigned int i;
2732
f12ab1e0 2733 if (!spec)
e9edcee0
TI
2734 return;
2735
2736 if (spec->kctl_alloc) {
2737 for (i = 0; i < spec->num_kctl_used; i++)
2738 kfree(spec->kctl_alloc[i].name);
2739 kfree(spec->kctl_alloc);
2740 }
2741 kfree(spec);
7943a8ab 2742 codec->spec = NULL; /* to be sure */
1da177e4
LT
2743}
2744
2745/*
2746 */
2747static struct hda_codec_ops alc_patch_ops = {
2748 .build_controls = alc_build_controls,
2749 .build_pcms = alc_build_pcms,
2750 .init = alc_init,
2751 .free = alc_free,
ae6b813a 2752 .unsol_event = alc_unsol_event,
cb53c626
TI
2753#ifdef CONFIG_SND_HDA_POWER_SAVE
2754 .check_power_status = alc_check_power_status,
2755#endif
1da177e4
LT
2756};
2757
2fa522be
TI
2758
2759/*
2760 * Test configuration for debugging
2761 *
2762 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2763 * enum controls.
2764 */
2765#ifdef CONFIG_SND_DEBUG
2766static hda_nid_t alc880_test_dac_nids[4] = {
2767 0x02, 0x03, 0x04, 0x05
2768};
2769
2770static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2771 .num_items = 7,
2fa522be
TI
2772 .items = {
2773 { "In-1", 0x0 },
2774 { "In-2", 0x1 },
2775 { "In-3", 0x2 },
2776 { "In-4", 0x3 },
2777 { "CD", 0x4 },
ae6b813a
TI
2778 { "Front", 0x5 },
2779 { "Surround", 0x6 },
2fa522be
TI
2780 },
2781};
2782
d2a6d7dc 2783static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2784 { 2, NULL },
fd2c326d 2785 { 4, NULL },
2fa522be 2786 { 6, NULL },
fd2c326d 2787 { 8, NULL },
2fa522be
TI
2788};
2789
9c7f852e
TI
2790static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2791 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2792{
2793 static char *texts[] = {
2794 "N/A", "Line Out", "HP Out",
2795 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2796 };
2797 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2798 uinfo->count = 1;
2799 uinfo->value.enumerated.items = 8;
2800 if (uinfo->value.enumerated.item >= 8)
2801 uinfo->value.enumerated.item = 7;
2802 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2803 return 0;
2804}
2805
9c7f852e
TI
2806static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2807 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2808{
2809 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2810 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2811 unsigned int pin_ctl, item = 0;
2812
2813 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2814 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2815 if (pin_ctl & AC_PINCTL_OUT_EN) {
2816 if (pin_ctl & AC_PINCTL_HP_EN)
2817 item = 2;
2818 else
2819 item = 1;
2820 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2821 switch (pin_ctl & AC_PINCTL_VREFEN) {
2822 case AC_PINCTL_VREF_HIZ: item = 3; break;
2823 case AC_PINCTL_VREF_50: item = 4; break;
2824 case AC_PINCTL_VREF_GRD: item = 5; break;
2825 case AC_PINCTL_VREF_80: item = 6; break;
2826 case AC_PINCTL_VREF_100: item = 7; break;
2827 }
2828 }
2829 ucontrol->value.enumerated.item[0] = item;
2830 return 0;
2831}
2832
9c7f852e
TI
2833static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2834 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2835{
2836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2837 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2838 static unsigned int ctls[] = {
2839 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2840 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2841 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2842 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2843 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2844 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2845 };
2846 unsigned int old_ctl, new_ctl;
2847
2848 old_ctl = snd_hda_codec_read(codec, nid, 0,
2849 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2850 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2851 if (old_ctl != new_ctl) {
82beb8fd
TI
2852 int val;
2853 snd_hda_codec_write_cache(codec, nid, 0,
2854 AC_VERB_SET_PIN_WIDGET_CONTROL,
2855 new_ctl);
47fd830a
TI
2856 val = ucontrol->value.enumerated.item[0] >= 3 ?
2857 HDA_AMP_MUTE : 0;
2858 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2859 HDA_AMP_MUTE, val);
2fa522be
TI
2860 return 1;
2861 }
2862 return 0;
2863}
2864
9c7f852e
TI
2865static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2866 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2867{
2868 static char *texts[] = {
2869 "Front", "Surround", "CLFE", "Side"
2870 };
2871 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2872 uinfo->count = 1;
2873 uinfo->value.enumerated.items = 4;
2874 if (uinfo->value.enumerated.item >= 4)
2875 uinfo->value.enumerated.item = 3;
2876 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2877 return 0;
2878}
2879
9c7f852e
TI
2880static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2881 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2882{
2883 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2884 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2885 unsigned int sel;
2886
2887 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2888 ucontrol->value.enumerated.item[0] = sel & 3;
2889 return 0;
2890}
2891
9c7f852e
TI
2892static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2893 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2894{
2895 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2896 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2897 unsigned int sel;
2898
2899 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2900 if (ucontrol->value.enumerated.item[0] != sel) {
2901 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2902 snd_hda_codec_write_cache(codec, nid, 0,
2903 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2904 return 1;
2905 }
2906 return 0;
2907}
2908
2909#define PIN_CTL_TEST(xname,nid) { \
2910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2911 .name = xname, \
2912 .info = alc_test_pin_ctl_info, \
2913 .get = alc_test_pin_ctl_get, \
2914 .put = alc_test_pin_ctl_put, \
2915 .private_value = nid \
2916 }
2917
2918#define PIN_SRC_TEST(xname,nid) { \
2919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2920 .name = xname, \
2921 .info = alc_test_pin_src_info, \
2922 .get = alc_test_pin_src_get, \
2923 .put = alc_test_pin_src_put, \
2924 .private_value = nid \
2925 }
2926
c8b6bf9b 2927static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2928 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2929 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2930 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2931 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2932 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2933 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2934 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2935 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2936 PIN_CTL_TEST("Front Pin Mode", 0x14),
2937 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2938 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2939 PIN_CTL_TEST("Side Pin Mode", 0x17),
2940 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2941 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2942 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2943 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2944 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2945 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2946 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2947 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2948 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2949 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2950 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2951 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2952 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2953 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2954 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2955 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2956 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2957 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2958 {
2959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2960 .name = "Channel Mode",
df694daa
KY
2961 .info = alc_ch_mode_info,
2962 .get = alc_ch_mode_get,
2963 .put = alc_ch_mode_put,
2fa522be
TI
2964 },
2965 { } /* end */
2966};
2967
2968static struct hda_verb alc880_test_init_verbs[] = {
2969 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2972 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2974 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2976 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2977 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2978 /* Vol output for 0x0c-0x0f */
05acb863
TI
2979 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2980 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2981 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2982 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2983 /* Set output pins 0x14-0x17 */
05acb863
TI
2984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2986 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2987 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2988 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2989 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2993 /* Set input pins 0x18-0x1c */
16ded525
TI
2994 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2995 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2996 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2998 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2999 /* Mute input pins 0x18-0x1b */
05acb863
TI
3000 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3001 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3003 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3004 /* ADC set up */
05acb863 3005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3006 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3008 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3010 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3011 /* Analog input/passthru */
3012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3017 { }
3018};
3019#endif
3020
1da177e4
LT
3021/*
3022 */
3023
f5fcc13c
TI
3024static const char *alc880_models[ALC880_MODEL_LAST] = {
3025 [ALC880_3ST] = "3stack",
3026 [ALC880_TCL_S700] = "tcl",
3027 [ALC880_3ST_DIG] = "3stack-digout",
3028 [ALC880_CLEVO] = "clevo",
3029 [ALC880_5ST] = "5stack",
3030 [ALC880_5ST_DIG] = "5stack-digout",
3031 [ALC880_W810] = "w810",
3032 [ALC880_Z71V] = "z71v",
3033 [ALC880_6ST] = "6stack",
3034 [ALC880_6ST_DIG] = "6stack-digout",
3035 [ALC880_ASUS] = "asus",
3036 [ALC880_ASUS_W1V] = "asus-w1v",
3037 [ALC880_ASUS_DIG] = "asus-dig",
3038 [ALC880_ASUS_DIG2] = "asus-dig2",
3039 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3040 [ALC880_UNIWILL_P53] = "uniwill-p53",
3041 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3042 [ALC880_F1734] = "F1734",
3043 [ALC880_LG] = "lg",
3044 [ALC880_LG_LW] = "lg-lw",
df99cd33 3045 [ALC880_MEDION_RIM] = "medion",
2fa522be 3046#ifdef CONFIG_SND_DEBUG
f5fcc13c 3047 [ALC880_TEST] = "test",
2fa522be 3048#endif
f5fcc13c
TI
3049 [ALC880_AUTO] = "auto",
3050};
3051
3052static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3053 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3054 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3055 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3056 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3057 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3058 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3059 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3060 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3061 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3062 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3063 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3064 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3065 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3066 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3067 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3068 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3069 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3070 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3071 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3072 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3073 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3074 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3075 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3076 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3077 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 3078 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3079 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3080 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3081 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3082 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3083 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3084 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3085 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3086 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3087 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3088 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3089 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3090 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3091 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3092 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3093 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3094 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3095 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3096 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3097 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3098 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3099 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3100 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3101 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3102 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3103 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3104 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3105 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3106 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3107 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3108 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3109 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3110 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3111 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3112 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3113 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3114 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3115 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3116 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3117 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3118 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3119 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3120 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3121 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3122 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3123 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3124 {}
3125};
3126
16ded525 3127/*
df694daa 3128 * ALC880 codec presets
16ded525 3129 */
16ded525
TI
3130static struct alc_config_preset alc880_presets[] = {
3131 [ALC880_3ST] = {
e9edcee0 3132 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3133 .init_verbs = { alc880_volume_init_verbs,
3134 alc880_pin_3stack_init_verbs },
16ded525 3135 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3136 .dac_nids = alc880_dac_nids,
16ded525
TI
3137 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3138 .channel_mode = alc880_threestack_modes,
4e195a7b 3139 .need_dac_fix = 1,
16ded525
TI
3140 .input_mux = &alc880_capture_source,
3141 },
3142 [ALC880_3ST_DIG] = {
e9edcee0 3143 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3144 .init_verbs = { alc880_volume_init_verbs,
3145 alc880_pin_3stack_init_verbs },
16ded525 3146 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3147 .dac_nids = alc880_dac_nids,
3148 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3149 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3150 .channel_mode = alc880_threestack_modes,
4e195a7b 3151 .need_dac_fix = 1,
16ded525
TI
3152 .input_mux = &alc880_capture_source,
3153 },
df694daa
KY
3154 [ALC880_TCL_S700] = {
3155 .mixers = { alc880_tcl_s700_mixer },
3156 .init_verbs = { alc880_volume_init_verbs,
3157 alc880_pin_tcl_S700_init_verbs,
3158 alc880_gpio2_init_verbs },
3159 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3160 .dac_nids = alc880_dac_nids,
3161 .hp_nid = 0x03,
3162 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3163 .channel_mode = alc880_2_jack_modes,
3164 .input_mux = &alc880_capture_source,
3165 },
16ded525 3166 [ALC880_5ST] = {
f12ab1e0
TI
3167 .mixers = { alc880_three_stack_mixer,
3168 alc880_five_stack_mixer},
3169 .init_verbs = { alc880_volume_init_verbs,
3170 alc880_pin_5stack_init_verbs },
16ded525
TI
3171 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3172 .dac_nids = alc880_dac_nids,
16ded525
TI
3173 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3174 .channel_mode = alc880_fivestack_modes,
3175 .input_mux = &alc880_capture_source,
3176 },
3177 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3178 .mixers = { alc880_three_stack_mixer,
3179 alc880_five_stack_mixer },
3180 .init_verbs = { alc880_volume_init_verbs,
3181 alc880_pin_5stack_init_verbs },
16ded525
TI
3182 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3183 .dac_nids = alc880_dac_nids,
3184 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3185 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3186 .channel_mode = alc880_fivestack_modes,
3187 .input_mux = &alc880_capture_source,
3188 },
b6482d48
TI
3189 [ALC880_6ST] = {
3190 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3191 .init_verbs = { alc880_volume_init_verbs,
3192 alc880_pin_6stack_init_verbs },
b6482d48
TI
3193 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3194 .dac_nids = alc880_6st_dac_nids,
3195 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3196 .channel_mode = alc880_sixstack_modes,
3197 .input_mux = &alc880_6stack_capture_source,
3198 },
16ded525 3199 [ALC880_6ST_DIG] = {
e9edcee0 3200 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3201 .init_verbs = { alc880_volume_init_verbs,
3202 alc880_pin_6stack_init_verbs },
16ded525
TI
3203 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3204 .dac_nids = alc880_6st_dac_nids,
3205 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3206 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3207 .channel_mode = alc880_sixstack_modes,
3208 .input_mux = &alc880_6stack_capture_source,
3209 },
3210 [ALC880_W810] = {
e9edcee0 3211 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3212 .init_verbs = { alc880_volume_init_verbs,
3213 alc880_pin_w810_init_verbs,
b0af0de5 3214 alc880_gpio2_init_verbs },
16ded525
TI
3215 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3216 .dac_nids = alc880_w810_dac_nids,
3217 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3218 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3219 .channel_mode = alc880_w810_modes,
3220 .input_mux = &alc880_capture_source,
3221 },
3222 [ALC880_Z71V] = {
e9edcee0 3223 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3224 .init_verbs = { alc880_volume_init_verbs,
3225 alc880_pin_z71v_init_verbs },
16ded525
TI
3226 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3227 .dac_nids = alc880_z71v_dac_nids,
3228 .dig_out_nid = ALC880_DIGOUT_NID,
3229 .hp_nid = 0x03,
e9edcee0
TI
3230 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3231 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3232 .input_mux = &alc880_capture_source,
3233 },
3234 [ALC880_F1734] = {
e9edcee0 3235 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3236 .init_verbs = { alc880_volume_init_verbs,
3237 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3238 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3239 .dac_nids = alc880_f1734_dac_nids,
3240 .hp_nid = 0x02,
3241 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3242 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3243 .input_mux = &alc880_f1734_capture_source,
3244 .unsol_event = alc880_uniwill_p53_unsol_event,
3245 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3246 },
3247 [ALC880_ASUS] = {
e9edcee0 3248 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3249 .init_verbs = { alc880_volume_init_verbs,
3250 alc880_pin_asus_init_verbs,
e9edcee0
TI
3251 alc880_gpio1_init_verbs },
3252 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3253 .dac_nids = alc880_asus_dac_nids,
3254 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3255 .channel_mode = alc880_asus_modes,
4e195a7b 3256 .need_dac_fix = 1,
16ded525
TI
3257 .input_mux = &alc880_capture_source,
3258 },
3259 [ALC880_ASUS_DIG] = {
e9edcee0 3260 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3261 .init_verbs = { alc880_volume_init_verbs,
3262 alc880_pin_asus_init_verbs,
e9edcee0
TI
3263 alc880_gpio1_init_verbs },
3264 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3265 .dac_nids = alc880_asus_dac_nids,
16ded525 3266 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3267 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3268 .channel_mode = alc880_asus_modes,
4e195a7b 3269 .need_dac_fix = 1,
16ded525
TI
3270 .input_mux = &alc880_capture_source,
3271 },
df694daa
KY
3272 [ALC880_ASUS_DIG2] = {
3273 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3274 .init_verbs = { alc880_volume_init_verbs,
3275 alc880_pin_asus_init_verbs,
df694daa
KY
3276 alc880_gpio2_init_verbs }, /* use GPIO2 */
3277 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3278 .dac_nids = alc880_asus_dac_nids,
3279 .dig_out_nid = ALC880_DIGOUT_NID,
3280 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3281 .channel_mode = alc880_asus_modes,
4e195a7b 3282 .need_dac_fix = 1,
df694daa
KY
3283 .input_mux = &alc880_capture_source,
3284 },
16ded525 3285 [ALC880_ASUS_W1V] = {
e9edcee0 3286 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3287 .init_verbs = { alc880_volume_init_verbs,
3288 alc880_pin_asus_init_verbs,
e9edcee0
TI
3289 alc880_gpio1_init_verbs },
3290 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3291 .dac_nids = alc880_asus_dac_nids,
16ded525 3292 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3293 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3294 .channel_mode = alc880_asus_modes,
4e195a7b 3295 .need_dac_fix = 1,
16ded525
TI
3296 .input_mux = &alc880_capture_source,
3297 },
3298 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3299 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3300 .init_verbs = { alc880_volume_init_verbs,
3301 alc880_pin_asus_init_verbs },
e9edcee0
TI
3302 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3303 .dac_nids = alc880_asus_dac_nids,
16ded525 3304 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3305 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3306 .channel_mode = alc880_asus_modes,
4e195a7b 3307 .need_dac_fix = 1,
16ded525
TI
3308 .input_mux = &alc880_capture_source,
3309 },
ccc656ce
KY
3310 [ALC880_UNIWILL] = {
3311 .mixers = { alc880_uniwill_mixer },
3312 .init_verbs = { alc880_volume_init_verbs,
3313 alc880_uniwill_init_verbs },
3314 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3315 .dac_nids = alc880_asus_dac_nids,
3316 .dig_out_nid = ALC880_DIGOUT_NID,
3317 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3318 .channel_mode = alc880_threestack_modes,
3319 .need_dac_fix = 1,
3320 .input_mux = &alc880_capture_source,
3321 .unsol_event = alc880_uniwill_unsol_event,
3322 .init_hook = alc880_uniwill_automute,
3323 },
3324 [ALC880_UNIWILL_P53] = {
3325 .mixers = { alc880_uniwill_p53_mixer },
3326 .init_verbs = { alc880_volume_init_verbs,
3327 alc880_uniwill_p53_init_verbs },
3328 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3329 .dac_nids = alc880_asus_dac_nids,
3330 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3331 .channel_mode = alc880_threestack_modes,
3332 .input_mux = &alc880_capture_source,
3333 .unsol_event = alc880_uniwill_p53_unsol_event,
3334 .init_hook = alc880_uniwill_p53_hp_automute,
3335 },
3336 [ALC880_FUJITSU] = {
f12ab1e0 3337 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3338 alc880_pcbeep_mixer, },
3339 .init_verbs = { alc880_volume_init_verbs,
3340 alc880_uniwill_p53_init_verbs,
3341 alc880_beep_init_verbs },
3342 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3343 .dac_nids = alc880_dac_nids,
d53d7d9e 3344 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3345 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3346 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3347 .input_mux = &alc880_capture_source,
3348 .unsol_event = alc880_uniwill_p53_unsol_event,
3349 .init_hook = alc880_uniwill_p53_hp_automute,
3350 },
df694daa
KY
3351 [ALC880_CLEVO] = {
3352 .mixers = { alc880_three_stack_mixer },
3353 .init_verbs = { alc880_volume_init_verbs,
3354 alc880_pin_clevo_init_verbs },
3355 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3356 .dac_nids = alc880_dac_nids,
3357 .hp_nid = 0x03,
3358 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3359 .channel_mode = alc880_threestack_modes,
4e195a7b 3360 .need_dac_fix = 1,
df694daa
KY
3361 .input_mux = &alc880_capture_source,
3362 },
ae6b813a
TI
3363 [ALC880_LG] = {
3364 .mixers = { alc880_lg_mixer },
3365 .init_verbs = { alc880_volume_init_verbs,
3366 alc880_lg_init_verbs },
3367 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3368 .dac_nids = alc880_lg_dac_nids,
3369 .dig_out_nid = ALC880_DIGOUT_NID,
3370 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3371 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3372 .need_dac_fix = 1,
ae6b813a
TI
3373 .input_mux = &alc880_lg_capture_source,
3374 .unsol_event = alc880_lg_unsol_event,
3375 .init_hook = alc880_lg_automute,
cb53c626
TI
3376#ifdef CONFIG_SND_HDA_POWER_SAVE
3377 .loopbacks = alc880_lg_loopbacks,
3378#endif
ae6b813a 3379 },
d681518a
TI
3380 [ALC880_LG_LW] = {
3381 .mixers = { alc880_lg_lw_mixer },
3382 .init_verbs = { alc880_volume_init_verbs,
3383 alc880_lg_lw_init_verbs },
0a8c5da3 3384 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3385 .dac_nids = alc880_dac_nids,
3386 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3387 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3388 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3389 .input_mux = &alc880_lg_lw_capture_source,
3390 .unsol_event = alc880_lg_lw_unsol_event,
3391 .init_hook = alc880_lg_lw_automute,
3392 },
df99cd33
TI
3393 [ALC880_MEDION_RIM] = {
3394 .mixers = { alc880_medion_rim_mixer },
3395 .init_verbs = { alc880_volume_init_verbs,
3396 alc880_medion_rim_init_verbs,
3397 alc_gpio2_init_verbs },
3398 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3399 .dac_nids = alc880_dac_nids,
3400 .dig_out_nid = ALC880_DIGOUT_NID,
3401 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3402 .channel_mode = alc880_2_jack_modes,
3403 .input_mux = &alc880_medion_rim_capture_source,
3404 .unsol_event = alc880_medion_rim_unsol_event,
3405 .init_hook = alc880_medion_rim_automute,
3406 },
16ded525
TI
3407#ifdef CONFIG_SND_DEBUG
3408 [ALC880_TEST] = {
e9edcee0
TI
3409 .mixers = { alc880_test_mixer },
3410 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3411 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3412 .dac_nids = alc880_test_dac_nids,
3413 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3414 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3415 .channel_mode = alc880_test_modes,
3416 .input_mux = &alc880_test_capture_source,
3417 },
3418#endif
3419};
3420
e9edcee0
TI
3421/*
3422 * Automatic parse of I/O pins from the BIOS configuration
3423 */
3424
3425#define NUM_CONTROL_ALLOC 32
3426#define NUM_VERB_ALLOC 32
3427
3428enum {
3429 ALC_CTL_WIDGET_VOL,
3430 ALC_CTL_WIDGET_MUTE,
3431 ALC_CTL_BIND_MUTE,
3432};
c8b6bf9b 3433static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3434 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3435 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3436 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3437};
3438
3439/* add dynamic controls */
f12ab1e0
TI
3440static int add_control(struct alc_spec *spec, int type, const char *name,
3441 unsigned long val)
e9edcee0 3442{
c8b6bf9b 3443 struct snd_kcontrol_new *knew;
e9edcee0
TI
3444
3445 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3446 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3447
f12ab1e0
TI
3448 /* array + terminator */
3449 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3450 if (!knew)
e9edcee0
TI
3451 return -ENOMEM;
3452 if (spec->kctl_alloc) {
f12ab1e0
TI
3453 memcpy(knew, spec->kctl_alloc,
3454 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3455 kfree(spec->kctl_alloc);
3456 }
3457 spec->kctl_alloc = knew;
3458 spec->num_kctl_alloc = num;
3459 }
3460
3461 knew = &spec->kctl_alloc[spec->num_kctl_used];
3462 *knew = alc880_control_templates[type];
543537bd 3463 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3464 if (!knew->name)
e9edcee0
TI
3465 return -ENOMEM;
3466 knew->private_value = val;
3467 spec->num_kctl_used++;
3468 return 0;
3469}
3470
3471#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3472#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3473#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3474#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3475#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3476#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3477#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3478#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3479#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3480#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3481#define ALC880_PIN_CD_NID 0x1c
3482
3483/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3484static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3485 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3486{
3487 hda_nid_t nid;
3488 int assigned[4];
3489 int i, j;
3490
3491 memset(assigned, 0, sizeof(assigned));
b0af0de5 3492 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3493
3494 /* check the pins hardwired to audio widget */
3495 for (i = 0; i < cfg->line_outs; i++) {
3496 nid = cfg->line_out_pins[i];
3497 if (alc880_is_fixed_pin(nid)) {
3498 int idx = alc880_fixed_pin_idx(nid);
5014f193 3499 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3500 assigned[idx] = 1;
3501 }
3502 }
3503 /* left pins can be connect to any audio widget */
3504 for (i = 0; i < cfg->line_outs; i++) {
3505 nid = cfg->line_out_pins[i];
3506 if (alc880_is_fixed_pin(nid))
3507 continue;
3508 /* search for an empty channel */
3509 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3510 if (!assigned[j]) {
3511 spec->multiout.dac_nids[i] =
3512 alc880_idx_to_dac(j);
e9edcee0
TI
3513 assigned[j] = 1;
3514 break;
3515 }
3516 }
3517 }
3518 spec->multiout.num_dacs = cfg->line_outs;
3519 return 0;
3520}
3521
3522/* add playback controls from the parsed DAC table */
df694daa
KY
3523static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3524 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3525{
3526 char name[32];
f12ab1e0
TI
3527 static const char *chname[4] = {
3528 "Front", "Surround", NULL /*CLFE*/, "Side"
3529 };
e9edcee0
TI
3530 hda_nid_t nid;
3531 int i, err;
3532
3533 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3534 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3535 continue;
3536 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3537 if (i == 2) {
3538 /* Center/LFE */
f12ab1e0
TI
3539 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3540 "Center Playback Volume",
3541 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3542 HDA_OUTPUT));
3543 if (err < 0)
e9edcee0 3544 return err;
f12ab1e0
TI
3545 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3546 "LFE Playback Volume",
3547 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3548 HDA_OUTPUT));
3549 if (err < 0)
e9edcee0 3550 return err;
f12ab1e0
TI
3551 err = add_control(spec, ALC_CTL_BIND_MUTE,
3552 "Center Playback Switch",
3553 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3554 HDA_INPUT));
3555 if (err < 0)
e9edcee0 3556 return err;
f12ab1e0
TI
3557 err = add_control(spec, ALC_CTL_BIND_MUTE,
3558 "LFE Playback Switch",
3559 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3560 HDA_INPUT));
3561 if (err < 0)
e9edcee0
TI
3562 return err;
3563 } else {
3564 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3565 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3566 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3567 HDA_OUTPUT));
3568 if (err < 0)
e9edcee0
TI
3569 return err;
3570 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3571 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3572 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3573 HDA_INPUT));
3574 if (err < 0)
e9edcee0
TI
3575 return err;
3576 }
3577 }
e9edcee0
TI
3578 return 0;
3579}
3580
8d88bc3d
TI
3581/* add playback controls for speaker and HP outputs */
3582static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3583 const char *pfx)
e9edcee0
TI
3584{
3585 hda_nid_t nid;
3586 int err;
8d88bc3d 3587 char name[32];
e9edcee0 3588
f12ab1e0 3589 if (!pin)
e9edcee0
TI
3590 return 0;
3591
3592 if (alc880_is_fixed_pin(pin)) {
3593 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3594 /* specify the DAC as the extra output */
f12ab1e0 3595 if (!spec->multiout.hp_nid)
e9edcee0 3596 spec->multiout.hp_nid = nid;
82bc955f
TI
3597 else
3598 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3599 /* control HP volume/switch on the output mixer amp */
3600 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3601 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3602 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3603 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3604 if (err < 0)
e9edcee0 3605 return err;
8d88bc3d 3606 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3607 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3608 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3609 if (err < 0)
e9edcee0
TI
3610 return err;
3611 } else if (alc880_is_multi_pin(pin)) {
3612 /* set manual connection */
e9edcee0 3613 /* we have only a switch on HP-out PIN */
8d88bc3d 3614 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3615 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3616 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3617 if (err < 0)
e9edcee0
TI
3618 return err;
3619 }
3620 return 0;
3621}
3622
3623/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3624static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3625 const char *ctlname,
df694daa 3626 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3627{
3628 char name[32];
df694daa 3629 int err;
e9edcee0
TI
3630
3631 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3632 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3633 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3634 if (err < 0)
e9edcee0
TI
3635 return err;
3636 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3637 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3638 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3639 if (err < 0)
e9edcee0
TI
3640 return err;
3641 return 0;
3642}
3643
3644/* create playback/capture controls for input pins */
df694daa
KY
3645static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3646 const struct auto_pin_cfg *cfg)
e9edcee0 3647{
e9edcee0 3648 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3649 int i, err, idx;
e9edcee0
TI
3650
3651 for (i = 0; i < AUTO_PIN_LAST; i++) {
3652 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3653 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3654 err = new_analog_input(spec, cfg->input_pins[i],
3655 auto_pin_cfg_labels[i],
df694daa 3656 idx, 0x0b);
e9edcee0
TI
3657 if (err < 0)
3658 return err;
f12ab1e0
TI
3659 imux->items[imux->num_items].label =
3660 auto_pin_cfg_labels[i];
3661 imux->items[imux->num_items].index =
3662 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3663 imux->num_items++;
3664 }
3665 }
3666 return 0;
3667}
3668
f6c7e546
TI
3669static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3670 unsigned int pin_type)
3671{
3672 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3673 pin_type);
3674 /* unmute pin */
d260cdf6
TI
3675 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3676 AMP_OUT_UNMUTE);
f6c7e546
TI
3677}
3678
df694daa
KY
3679static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3680 hda_nid_t nid, int pin_type,
e9edcee0
TI
3681 int dac_idx)
3682{
f6c7e546 3683 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3684 /* need the manual connection? */
3685 if (alc880_is_multi_pin(nid)) {
3686 struct alc_spec *spec = codec->spec;
3687 int idx = alc880_multi_pin_idx(nid);
3688 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3689 AC_VERB_SET_CONNECT_SEL,
3690 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3691 }
3692}
3693
baba8ee9
TI
3694static int get_pin_type(int line_out_type)
3695{
3696 if (line_out_type == AUTO_PIN_HP_OUT)
3697 return PIN_HP;
3698 else
3699 return PIN_OUT;
3700}
3701
e9edcee0
TI
3702static void alc880_auto_init_multi_out(struct hda_codec *codec)
3703{
3704 struct alc_spec *spec = codec->spec;
3705 int i;
ea1fb29a 3706
bc9f98a9 3707 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3708 for (i = 0; i < spec->autocfg.line_outs; i++) {
3709 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3710 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3711 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3712 }
3713}
3714
8d88bc3d 3715static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3716{
3717 struct alc_spec *spec = codec->spec;
3718 hda_nid_t pin;
3719
82bc955f 3720 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3721 if (pin) /* connect to front */
3722 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3723 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3724 if (pin) /* connect to front */
3725 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3726}
3727
3728static void alc880_auto_init_analog_input(struct hda_codec *codec)
3729{
3730 struct alc_spec *spec = codec->spec;
3731 int i;
3732
3733 for (i = 0; i < AUTO_PIN_LAST; i++) {
3734 hda_nid_t nid = spec->autocfg.input_pins[i];
3735 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3736 snd_hda_codec_write(codec, nid, 0,
3737 AC_VERB_SET_PIN_WIDGET_CONTROL,
3738 i <= AUTO_PIN_FRONT_MIC ?
3739 PIN_VREF80 : PIN_IN);
e9edcee0 3740 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3741 snd_hda_codec_write(codec, nid, 0,
3742 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3743 AMP_OUT_MUTE);
3744 }
3745 }
3746}
3747
3748/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3749/* return 1 if successful, 0 if the proper config is not found,
3750 * or a negative error code
3751 */
e9edcee0
TI
3752static int alc880_parse_auto_config(struct hda_codec *codec)
3753{
3754 struct alc_spec *spec = codec->spec;
3755 int err;
df694daa 3756 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3757
f12ab1e0
TI
3758 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3759 alc880_ignore);
3760 if (err < 0)
e9edcee0 3761 return err;
f12ab1e0 3762 if (!spec->autocfg.line_outs)
e9edcee0 3763 return 0; /* can't find valid BIOS pin config */
df694daa 3764
f12ab1e0
TI
3765 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3766 if (err < 0)
3767 return err;
3768 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3769 if (err < 0)
3770 return err;
3771 err = alc880_auto_create_extra_out(spec,
3772 spec->autocfg.speaker_pins[0],
3773 "Speaker");
3774 if (err < 0)
3775 return err;
3776 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3777 "Headphone");
3778 if (err < 0)
3779 return err;
3780 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3781 if (err < 0)
e9edcee0
TI
3782 return err;
3783
3784 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3785
3786 if (spec->autocfg.dig_out_pin)
3787 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3788 if (spec->autocfg.dig_in_pin)
3789 spec->dig_in_nid = ALC880_DIGIN_NID;
3790
3791 if (spec->kctl_alloc)
3792 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3793
3794 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3795
a1e8d2da 3796 spec->num_mux_defs = 1;
e9edcee0
TI
3797 spec->input_mux = &spec->private_imux;
3798
3799 return 1;
3800}
3801
ae6b813a
TI
3802/* additional initialization for auto-configuration model */
3803static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3804{
f6c7e546 3805 struct alc_spec *spec = codec->spec;
e9edcee0 3806 alc880_auto_init_multi_out(codec);
8d88bc3d 3807 alc880_auto_init_extra_out(codec);
e9edcee0 3808 alc880_auto_init_analog_input(codec);
f6c7e546
TI
3809 if (spec->unsol_event)
3810 alc_sku_automute(codec);
e9edcee0
TI
3811}
3812
3813/*
3814 * OK, here we have finally the patch for ALC880
3815 */
3816
1da177e4
LT
3817static int patch_alc880(struct hda_codec *codec)
3818{
3819 struct alc_spec *spec;
3820 int board_config;
df694daa 3821 int err;
1da177e4 3822
e560d8d8 3823 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3824 if (spec == NULL)
3825 return -ENOMEM;
3826
3827 codec->spec = spec;
3828
f5fcc13c
TI
3829 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3830 alc880_models,
3831 alc880_cfg_tbl);
3832 if (board_config < 0) {
9c7f852e
TI
3833 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3834 "trying auto-probe from BIOS...\n");
e9edcee0 3835 board_config = ALC880_AUTO;
1da177e4 3836 }
1da177e4 3837
e9edcee0
TI
3838 if (board_config == ALC880_AUTO) {
3839 /* automatic parse from the BIOS config */
3840 err = alc880_parse_auto_config(codec);
3841 if (err < 0) {
3842 alc_free(codec);
3843 return err;
f12ab1e0 3844 } else if (!err) {
9c7f852e
TI
3845 printk(KERN_INFO
3846 "hda_codec: Cannot set up configuration "
3847 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3848 board_config = ALC880_3ST;
3849 }
1da177e4
LT
3850 }
3851
df694daa
KY
3852 if (board_config != ALC880_AUTO)
3853 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3854
3855 spec->stream_name_analog = "ALC880 Analog";
3856 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3857 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3858 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3859
3860 spec->stream_name_digital = "ALC880 Digital";
3861 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3862 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3863
f12ab1e0 3864 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3865 /* check whether NID 0x07 is valid */
54d17403 3866 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3867 /* get type */
3868 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3869 if (wcap != AC_WID_AUD_IN) {
3870 spec->adc_nids = alc880_adc_nids_alt;
3871 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3872 spec->mixers[spec->num_mixers] =
3873 alc880_capture_alt_mixer;
e9edcee0
TI
3874 spec->num_mixers++;
3875 } else {
3876 spec->adc_nids = alc880_adc_nids;
3877 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3878 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3879 spec->num_mixers++;
3880 }
3881 }
1da177e4 3882
2134ea4f
TI
3883 spec->vmaster_nid = 0x0c;
3884
1da177e4 3885 codec->patch_ops = alc_patch_ops;
e9edcee0 3886 if (board_config == ALC880_AUTO)
ae6b813a 3887 spec->init_hook = alc880_auto_init;
cb53c626
TI
3888#ifdef CONFIG_SND_HDA_POWER_SAVE
3889 if (!spec->loopback.amplist)
3890 spec->loopback.amplist = alc880_loopbacks;
3891#endif
1da177e4
LT
3892
3893 return 0;
3894}
3895
e9edcee0 3896
1da177e4
LT
3897/*
3898 * ALC260 support
3899 */
3900
e9edcee0
TI
3901static hda_nid_t alc260_dac_nids[1] = {
3902 /* front */
3903 0x02,
3904};
3905
3906static hda_nid_t alc260_adc_nids[1] = {
3907 /* ADC0 */
3908 0x04,
3909};
3910
df694daa 3911static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3912 /* ADC1 */
3913 0x05,
3914};
3915
df694daa
KY
3916static hda_nid_t alc260_hp_adc_nids[2] = {
3917 /* ADC1, 0 */
3918 0x05, 0x04
3919};
3920
d57fdac0
JW
3921/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3922 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3923 */
3924static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3925 /* ADC0, ADC1 */
3926 0x04, 0x05
3927};
3928
e9edcee0
TI
3929#define ALC260_DIGOUT_NID 0x03
3930#define ALC260_DIGIN_NID 0x06
3931
3932static struct hda_input_mux alc260_capture_source = {
3933 .num_items = 4,
3934 .items = {
3935 { "Mic", 0x0 },
3936 { "Front Mic", 0x1 },
3937 { "Line", 0x2 },
3938 { "CD", 0x4 },
3939 },
3940};
3941
17e7aec6 3942/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3943 * headphone jack and the internal CD lines since these are the only pins at
3944 * which audio can appear. For flexibility, also allow the option of
3945 * recording the mixer output on the second ADC (ADC0 doesn't have a
3946 * connection to the mixer output).
a9430dd8 3947 */
a1e8d2da
JW
3948static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3949 {
3950 .num_items = 3,
3951 .items = {
3952 { "Mic/Line", 0x0 },
3953 { "CD", 0x4 },
3954 { "Headphone", 0x2 },
3955 },
a9430dd8 3956 },
a1e8d2da
JW
3957 {
3958 .num_items = 4,
3959 .items = {
3960 { "Mic/Line", 0x0 },
3961 { "CD", 0x4 },
3962 { "Headphone", 0x2 },
3963 { "Mixer", 0x5 },
3964 },
3965 },
3966
a9430dd8
JW
3967};
3968
a1e8d2da
JW
3969/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3970 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3971 */
a1e8d2da
JW
3972static struct hda_input_mux alc260_acer_capture_sources[2] = {
3973 {
3974 .num_items = 4,
3975 .items = {
3976 { "Mic", 0x0 },
3977 { "Line", 0x2 },
3978 { "CD", 0x4 },
3979 { "Headphone", 0x5 },
3980 },
3981 },
3982 {
3983 .num_items = 5,
3984 .items = {
3985 { "Mic", 0x0 },
3986 { "Line", 0x2 },
3987 { "CD", 0x4 },
3988 { "Headphone", 0x6 },
3989 { "Mixer", 0x5 },
3990 },
0bfc90e9
JW
3991 },
3992};
1da177e4
LT
3993/*
3994 * This is just place-holder, so there's something for alc_build_pcms to look
3995 * at when it calculates the maximum number of channels. ALC260 has no mixer
3996 * element which allows changing the channel mode, so the verb list is
3997 * never used.
3998 */
d2a6d7dc 3999static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4000 { 2, NULL },
4001};
4002
df694daa
KY
4003
4004/* Mixer combinations
4005 *
4006 * basic: base_output + input + pc_beep + capture
4007 * HP: base_output + input + capture_alt
4008 * HP_3013: hp_3013 + input + capture
4009 * fujitsu: fujitsu + capture
0bfc90e9 4010 * acer: acer + capture
df694daa
KY
4011 */
4012
4013static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4014 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4015 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4016 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4017 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4018 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4019 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4020 { } /* end */
f12ab1e0 4021};
1da177e4 4022
df694daa 4023static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4024 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4025 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4026 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4027 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4029 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4031 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4032 { } /* end */
4033};
4034
4035static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4036 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4037 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4038 { } /* end */
4039};
4040
bec15c3a
TI
4041/* update HP, line and mono out pins according to the master switch */
4042static void alc260_hp_master_update(struct hda_codec *codec,
4043 hda_nid_t hp, hda_nid_t line,
4044 hda_nid_t mono)
4045{
4046 struct alc_spec *spec = codec->spec;
4047 unsigned int val = spec->master_sw ? PIN_HP : 0;
4048 /* change HP and line-out pins */
4049 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4050 val);
4051 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4052 val);
4053 /* mono (speaker) depending on the HP jack sense */
4054 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4055 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4056 val);
4057}
4058
4059static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4060 struct snd_ctl_elem_value *ucontrol)
4061{
4062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4063 struct alc_spec *spec = codec->spec;
4064 *ucontrol->value.integer.value = spec->master_sw;
4065 return 0;
4066}
4067
4068static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4069 struct snd_ctl_elem_value *ucontrol)
4070{
4071 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4072 struct alc_spec *spec = codec->spec;
4073 int val = !!*ucontrol->value.integer.value;
4074 hda_nid_t hp, line, mono;
4075
4076 if (val == spec->master_sw)
4077 return 0;
4078 spec->master_sw = val;
4079 hp = (kcontrol->private_value >> 16) & 0xff;
4080 line = (kcontrol->private_value >> 8) & 0xff;
4081 mono = kcontrol->private_value & 0xff;
4082 alc260_hp_master_update(codec, hp, line, mono);
4083 return 1;
4084}
4085
4086static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4087 {
4088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4089 .name = "Master Playback Switch",
4090 .info = snd_ctl_boolean_mono_info,
4091 .get = alc260_hp_master_sw_get,
4092 .put = alc260_hp_master_sw_put,
4093 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4094 },
4095 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4096 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4098 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4099 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4100 HDA_OUTPUT),
4101 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4102 { } /* end */
4103};
4104
4105static struct hda_verb alc260_hp_unsol_verbs[] = {
4106 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4107 {},
4108};
4109
4110static void alc260_hp_automute(struct hda_codec *codec)
4111{
4112 struct alc_spec *spec = codec->spec;
4113 unsigned int present;
4114
4115 present = snd_hda_codec_read(codec, 0x10, 0,
4116 AC_VERB_GET_PIN_SENSE, 0);
4117 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4118 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4119}
4120
4121static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4122{
4123 if ((res >> 26) == ALC880_HP_EVENT)
4124 alc260_hp_automute(codec);
4125}
4126
df694daa 4127static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4128 {
4129 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4130 .name = "Master Playback Switch",
4131 .info = snd_ctl_boolean_mono_info,
4132 .get = alc260_hp_master_sw_get,
4133 .put = alc260_hp_master_sw_put,
4134 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4135 },
df694daa
KY
4136 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4137 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4138 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4139 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4140 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4141 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4142 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4143 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4144 { } /* end */
4145};
4146
3f878308
KY
4147static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4148 .ops = &snd_hda_bind_vol,
4149 .values = {
4150 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4151 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4152 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4153 0
4154 },
4155};
4156
4157static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4158 .ops = &snd_hda_bind_sw,
4159 .values = {
4160 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4161 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4162 0
4163 },
4164};
4165
4166static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4167 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4168 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4169 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4170 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4171 { } /* end */
4172};
4173
bec15c3a
TI
4174static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4175 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4176 {},
4177};
4178
4179static void alc260_hp_3013_automute(struct hda_codec *codec)
4180{
4181 struct alc_spec *spec = codec->spec;
4182 unsigned int present;
4183
4184 present = snd_hda_codec_read(codec, 0x15, 0,
4185 AC_VERB_GET_PIN_SENSE, 0);
4186 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4187 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4188}
4189
4190static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4191 unsigned int res)
4192{
4193 if ((res >> 26) == ALC880_HP_EVENT)
4194 alc260_hp_3013_automute(codec);
4195}
4196
3f878308
KY
4197static void alc260_hp_3012_automute(struct hda_codec *codec)
4198{
4199 unsigned int present, bits;
4200
4201 present = snd_hda_codec_read(codec, 0x10, 0,
4202 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4203
4204 bits = present ? 0 : PIN_OUT;
4205 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4206 bits);
4207 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4208 bits);
4209 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4210 bits);
4211}
4212
4213static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4214 unsigned int res)
4215{
4216 if ((res >> 26) == ALC880_HP_EVENT)
4217 alc260_hp_3012_automute(codec);
4218}
4219
4220/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4221 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4222 */
c8b6bf9b 4223static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4225 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4226 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4227 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4228 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4229 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4230 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4231 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
4232 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4233 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4234 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4235 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4236 { } /* end */
4237};
4238
a1e8d2da
JW
4239/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4240 * versions of the ALC260 don't act on requests to enable mic bias from NID
4241 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4242 * datasheet doesn't mention this restriction. At this stage it's not clear
4243 * whether this behaviour is intentional or is a hardware bug in chip
4244 * revisions available in early 2006. Therefore for now allow the
4245 * "Headphone Jack Mode" control to span all choices, but if it turns out
4246 * that the lack of mic bias for this NID is intentional we could change the
4247 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4248 *
4249 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4250 * don't appear to make the mic bias available from the "line" jack, even
4251 * though the NID used for this jack (0x14) can supply it. The theory is
4252 * that perhaps Acer have included blocking capacitors between the ALC260
4253 * and the output jack. If this turns out to be the case for all such
4254 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4255 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4256 *
4257 * The C20x Tablet series have a mono internal speaker which is controlled
4258 * via the chip's Mono sum widget and pin complex, so include the necessary
4259 * controls for such models. On models without a "mono speaker" the control
4260 * won't do anything.
a1e8d2da 4261 */
0bfc90e9
JW
4262static struct snd_kcontrol_new alc260_acer_mixer[] = {
4263 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4264 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4265 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4266 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4267 HDA_OUTPUT),
31bffaa9 4268 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4269 HDA_INPUT),
0bfc90e9
JW
4270 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4271 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4273 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4274 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4275 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4276 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4277 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4278 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4279 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4280 { } /* end */
4281};
4282
bc9f98a9
KY
4283/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4284 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4285 */
4286static struct snd_kcontrol_new alc260_will_mixer[] = {
4287 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4288 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4289 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4290 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4291 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4292 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4293 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4294 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4295 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4296 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4297 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4298 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4299 { } /* end */
4300};
4301
4302/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4303 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4304 */
4305static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4306 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4307 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4309 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4310 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4311 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4312 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4313 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4314 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4315 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4316 { } /* end */
4317};
4318
df694daa
KY
4319/* capture mixer elements */
4320static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4321 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4322 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4323 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4324 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4325 {
4326 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4327 /* The multiple "Capture Source" controls confuse alsamixer
4328 * So call somewhat different..
df694daa
KY
4329 */
4330 /* .name = "Capture Source", */
4331 .name = "Input Source",
4332 .count = 2,
4333 .info = alc_mux_enum_info,
4334 .get = alc_mux_enum_get,
4335 .put = alc_mux_enum_put,
4336 },
4337 { } /* end */
4338};
4339
4340static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4341 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4342 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4343 {
4344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4345 /* The multiple "Capture Source" controls confuse alsamixer
4346 * So call somewhat different..
df694daa
KY
4347 */
4348 /* .name = "Capture Source", */
4349 .name = "Input Source",
4350 .count = 1,
a9430dd8
JW
4351 .info = alc_mux_enum_info,
4352 .get = alc_mux_enum_get,
4353 .put = alc_mux_enum_put,
4354 },
4355 { } /* end */
4356};
4357
df694daa
KY
4358/*
4359 * initialization verbs
4360 */
1da177e4
LT
4361static struct hda_verb alc260_init_verbs[] = {
4362 /* Line In pin widget for input */
05acb863 4363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4364 /* CD pin widget for input */
05acb863 4365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4366 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4367 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4368 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4369 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4370 /* LINE-2 is used for line-out in rear */
05acb863 4371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4372 /* select line-out */
fd56f2db 4373 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4374 /* LINE-OUT pin */
05acb863 4375 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4376 /* enable HP */
05acb863 4377 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4378 /* enable Mono */
05acb863
TI
4379 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4380 /* mute capture amp left and right */
16ded525 4381 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4382 /* set connection select to line in (default select for this ADC) */
4383 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4384 /* mute capture amp left and right */
4385 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4386 /* set connection select to line in (default select for this ADC) */
4387 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4388 /* set vol=0 Line-Out mixer amp left and right */
4389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4390 /* unmute pin widget amp left and right (no gain on this amp) */
4391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4392 /* set vol=0 HP mixer amp left and right */
4393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4394 /* unmute pin widget amp left and right (no gain on this amp) */
4395 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4396 /* set vol=0 Mono mixer amp left and right */
4397 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4398 /* unmute pin widget amp left and right (no gain on this amp) */
4399 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4400 /* unmute LINE-2 out pin */
4401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4402 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4403 * Line In 2 = 0x03
4404 */
cb53c626
TI
4405 /* mute analog inputs */
4406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4411 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4412 /* mute Front out path */
4413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4415 /* mute Headphone out path */
4416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4417 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4418 /* mute Mono out path */
4419 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4420 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4421 { }
4422};
4423
474167d6 4424#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4425static struct hda_verb alc260_hp_init_verbs[] = {
4426 /* Headphone and output */
4427 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4428 /* mono output */
4429 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4430 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4432 /* Mic2 (front panel) pin widget for input and vref at 80% */
4433 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4434 /* Line In pin widget for input */
4435 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4436 /* Line-2 pin widget for output */
4437 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4438 /* CD pin widget for input */
4439 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4440 /* unmute amp left and right */
4441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4442 /* set connection select to line in (default select for this ADC) */
4443 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4444 /* unmute Line-Out mixer amp left and right (volume = 0) */
4445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4446 /* mute pin widget amp left and right (no gain on this amp) */
4447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4448 /* unmute HP mixer amp left and right (volume = 0) */
4449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4450 /* mute pin widget amp left and right (no gain on this amp) */
4451 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4452 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4453 * Line In 2 = 0x03
4454 */
cb53c626
TI
4455 /* mute analog inputs */
4456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4460 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4461 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4462 /* Unmute Front out path */
4463 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4465 /* Unmute Headphone out path */
4466 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4468 /* Unmute Mono out path */
4469 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4470 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4471 { }
4472};
474167d6 4473#endif
df694daa
KY
4474
4475static struct hda_verb alc260_hp_3013_init_verbs[] = {
4476 /* Line out and output */
4477 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4478 /* mono output */
4479 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4480 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4481 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4482 /* Mic2 (front panel) pin widget for input and vref at 80% */
4483 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4484 /* Line In pin widget for input */
4485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4486 /* Headphone pin widget for output */
4487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4488 /* CD pin widget for input */
4489 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4490 /* unmute amp left and right */
4491 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4492 /* set connection select to line in (default select for this ADC) */
4493 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4494 /* unmute Line-Out mixer amp left and right (volume = 0) */
4495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4496 /* mute pin widget amp left and right (no gain on this amp) */
4497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4498 /* unmute HP mixer amp left and right (volume = 0) */
4499 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4500 /* mute pin widget amp left and right (no gain on this amp) */
4501 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4502 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4503 * Line In 2 = 0x03
4504 */
cb53c626
TI
4505 /* mute analog inputs */
4506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4511 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4512 /* Unmute Front out path */
4513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4514 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4515 /* Unmute Headphone out path */
4516 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4518 /* Unmute Mono out path */
4519 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4520 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4521 { }
4522};
4523
a9430dd8 4524/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4525 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4526 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4527 */
4528static struct hda_verb alc260_fujitsu_init_verbs[] = {
4529 /* Disable all GPIOs */
4530 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4531 /* Internal speaker is connected to headphone pin */
4532 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4533 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4535 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4536 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4537 /* Ensure all other unused pins are disabled and muted. */
4538 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4540 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4541 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4542 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4543 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4546
4547 /* Disable digital (SPDIF) pins */
4548 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4549 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4550
ea1fb29a 4551 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
4552 * when acting as an output.
4553 */
4554 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4555
f7ace40d 4556 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4557 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4562 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4563 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4564 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4565 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4566
f7ace40d
JW
4567 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4568 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4569 /* Unmute Line1 pin widget output buffer since it starts as an output.
4570 * If the pin mode is changed by the user the pin mode control will
4571 * take care of enabling the pin's input/output buffers as needed.
4572 * Therefore there's no need to enable the input buffer at this
4573 * stage.
cdcd9268 4574 */
f7ace40d 4575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 4576 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
4577 * mixer ctrl)
4578 */
f7ace40d
JW
4579 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4580
4581 /* Mute capture amp left and right */
4582 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 4583 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
4584 * in (on mic1 pin)
4585 */
4586 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4587
4588 /* Do the same for the second ADC: mute capture input amp and
4589 * set ADC connection to line in (on mic1 pin)
4590 */
4591 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4592 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4593
4594 /* Mute all inputs to mixer widget (even unconnected ones) */
4595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4596 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4597 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4603
4604 { }
a9430dd8
JW
4605};
4606
0bfc90e9
JW
4607/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4608 * similar laptops (adapted from Fujitsu init verbs).
4609 */
4610static struct hda_verb alc260_acer_init_verbs[] = {
4611 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4612 * the headphone jack. Turn this on and rely on the standard mute
4613 * methods whenever the user wants to turn these outputs off.
4614 */
4615 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4616 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4617 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4618 /* Internal speaker/Headphone jack is connected to Line-out pin */
4619 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4620 /* Internal microphone/Mic jack is connected to Mic1 pin */
4621 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4622 /* Line In jack is connected to Line1 pin */
4623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4624 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4625 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4626 /* Ensure all other unused pins are disabled and muted. */
4627 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4628 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4629 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4630 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4633 /* Disable digital (SPDIF) pins */
4634 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4635 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4636
ea1fb29a 4637 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
4638 * bus when acting as outputs.
4639 */
4640 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4641 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4642
4643 /* Start with output sum widgets muted and their output gains at min */
4644 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4645 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4646 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4647 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4648 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4649 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4650 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4651 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4652 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4653
f12ab1e0
TI
4654 /* Unmute Line-out pin widget amp left and right
4655 * (no equiv mixer ctrl)
4656 */
0bfc90e9 4657 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4658 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4659 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4660 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4661 * inputs. If the pin mode is changed by the user the pin mode control
4662 * will take care of enabling the pin's input/output buffers as needed.
4663 * Therefore there's no need to enable the input buffer at this
4664 * stage.
4665 */
4666 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4667 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4668
4669 /* Mute capture amp left and right */
4670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4671 /* Set ADC connection select to match default mixer setting - mic
4672 * (on mic1 pin)
4673 */
4674 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4675
4676 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4677 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4678 */
4679 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4680 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4681
4682 /* Mute all inputs to mixer widget (even unconnected ones) */
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4686 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4691
4692 { }
4693};
4694
bc9f98a9
KY
4695static struct hda_verb alc260_will_verbs[] = {
4696 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4697 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4698 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4699 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4700 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4701 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4702 {}
4703};
4704
4705static struct hda_verb alc260_replacer_672v_verbs[] = {
4706 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4707 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4708 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4709
4710 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4711 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4712 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4713
4714 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4715 {}
4716};
4717
4718/* toggle speaker-output according to the hp-jack state */
4719static void alc260_replacer_672v_automute(struct hda_codec *codec)
4720{
4721 unsigned int present;
4722
4723 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4724 present = snd_hda_codec_read(codec, 0x0f, 0,
4725 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4726 if (present) {
82beb8fd
TI
4727 snd_hda_codec_write_cache(codec, 0x01, 0,
4728 AC_VERB_SET_GPIO_DATA, 1);
4729 snd_hda_codec_write_cache(codec, 0x0f, 0,
4730 AC_VERB_SET_PIN_WIDGET_CONTROL,
4731 PIN_HP);
bc9f98a9 4732 } else {
82beb8fd
TI
4733 snd_hda_codec_write_cache(codec, 0x01, 0,
4734 AC_VERB_SET_GPIO_DATA, 0);
4735 snd_hda_codec_write_cache(codec, 0x0f, 0,
4736 AC_VERB_SET_PIN_WIDGET_CONTROL,
4737 PIN_OUT);
bc9f98a9
KY
4738 }
4739}
4740
4741static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4742 unsigned int res)
4743{
4744 if ((res >> 26) == ALC880_HP_EVENT)
4745 alc260_replacer_672v_automute(codec);
4746}
4747
3f878308
KY
4748static struct hda_verb alc260_hp_dc7600_verbs[] = {
4749 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4750 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4751 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4752 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4753 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4755 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4756 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4757 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4758 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4759 {}
4760};
4761
7cf51e48
JW
4762/* Test configuration for debugging, modelled after the ALC880 test
4763 * configuration.
4764 */
4765#ifdef CONFIG_SND_DEBUG
4766static hda_nid_t alc260_test_dac_nids[1] = {
4767 0x02,
4768};
4769static hda_nid_t alc260_test_adc_nids[2] = {
4770 0x04, 0x05,
4771};
a1e8d2da 4772/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 4773 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 4774 * is NID 0x04.
17e7aec6 4775 */
a1e8d2da
JW
4776static struct hda_input_mux alc260_test_capture_sources[2] = {
4777 {
4778 .num_items = 7,
4779 .items = {
4780 { "MIC1 pin", 0x0 },
4781 { "MIC2 pin", 0x1 },
4782 { "LINE1 pin", 0x2 },
4783 { "LINE2 pin", 0x3 },
4784 { "CD pin", 0x4 },
4785 { "LINE-OUT pin", 0x5 },
4786 { "HP-OUT pin", 0x6 },
4787 },
4788 },
4789 {
4790 .num_items = 8,
4791 .items = {
4792 { "MIC1 pin", 0x0 },
4793 { "MIC2 pin", 0x1 },
4794 { "LINE1 pin", 0x2 },
4795 { "LINE2 pin", 0x3 },
4796 { "CD pin", 0x4 },
4797 { "Mixer", 0x5 },
4798 { "LINE-OUT pin", 0x6 },
4799 { "HP-OUT pin", 0x7 },
4800 },
7cf51e48
JW
4801 },
4802};
4803static struct snd_kcontrol_new alc260_test_mixer[] = {
4804 /* Output driver widgets */
4805 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4806 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4807 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4808 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4809 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4810 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4811
a1e8d2da
JW
4812 /* Modes for retasking pin widgets
4813 * Note: the ALC260 doesn't seem to act on requests to enable mic
4814 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4815 * mention this restriction. At this stage it's not clear whether
4816 * this behaviour is intentional or is a hardware bug in chip
4817 * revisions available at least up until early 2006. Therefore for
4818 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4819 * choices, but if it turns out that the lack of mic bias for these
4820 * NIDs is intentional we could change their modes from
4821 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4822 */
7cf51e48
JW
4823 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4824 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4825 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4826 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4827 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4828 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4829
4830 /* Loopback mixer controls */
4831 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4832 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4833 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4834 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4835 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4836 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4837 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4838 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4839 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4840 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4841 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4842 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4843 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4844 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4845 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4846 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4847
4848 /* Controls for GPIO pins, assuming they are configured as outputs */
4849 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4850 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4851 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4852 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4853
92621f13
JW
4854 /* Switches to allow the digital IO pins to be enabled. The datasheet
4855 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 4856 * make this output available should provide clarification.
92621f13
JW
4857 */
4858 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4859 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4860
f8225f6d
JW
4861 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4862 * this output to turn on an external amplifier.
4863 */
4864 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4865 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4866
7cf51e48
JW
4867 { } /* end */
4868};
4869static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4870 /* Enable all GPIOs as outputs with an initial value of 0 */
4871 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4872 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4873 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4874
7cf51e48
JW
4875 /* Enable retasking pins as output, initially without power amp */
4876 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4877 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4878 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4879 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4880 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4881 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4882
92621f13
JW
4883 /* Disable digital (SPDIF) pins initially, but users can enable
4884 * them via a mixer switch. In the case of SPDIF-out, this initverb
4885 * payload also sets the generation to 0, output to be in "consumer"
4886 * PCM format, copyright asserted, no pre-emphasis and no validity
4887 * control.
4888 */
7cf51e48
JW
4889 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4890 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4891
ea1fb29a 4892 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4893 * OUT1 sum bus when acting as an output.
4894 */
4895 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4896 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4897 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4898 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4899
4900 /* Start with output sum widgets muted and their output gains at min */
4901 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4905 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4908 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4909 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4910
cdcd9268
JW
4911 /* Unmute retasking pin widget output buffers since the default
4912 * state appears to be output. As the pin mode is changed by the
4913 * user the pin mode control will take care of enabling the pin's
4914 * input/output buffers as needed.
4915 */
7cf51e48
JW
4916 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4917 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4919 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4920 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4921 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4922 /* Also unmute the mono-out pin widget */
4923 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4924
7cf51e48
JW
4925 /* Mute capture amp left and right */
4926 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4927 /* Set ADC connection select to match default mixer setting (mic1
4928 * pin)
7cf51e48
JW
4929 */
4930 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4931
4932 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4933 * set ADC connection to mic1 pin
7cf51e48
JW
4934 */
4935 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4936 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4937
4938 /* Mute all inputs to mixer widget (even unconnected ones) */
4939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4942 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4945 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4947
4948 { }
4949};
4950#endif
4951
6330079f
TI
4952#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4953#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 4954
a3bcba38
TI
4955#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4956#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4957
df694daa
KY
4958/*
4959 * for BIOS auto-configuration
4960 */
16ded525 4961
df694daa
KY
4962static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4963 const char *pfx)
4964{
4965 hda_nid_t nid_vol;
4966 unsigned long vol_val, sw_val;
4967 char name[32];
4968 int err;
4969
4970 if (nid >= 0x0f && nid < 0x11) {
4971 nid_vol = nid - 0x7;
4972 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4973 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4974 } else if (nid == 0x11) {
4975 nid_vol = nid - 0x7;
4976 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4977 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4978 } else if (nid >= 0x12 && nid <= 0x15) {
4979 nid_vol = 0x08;
4980 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4981 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4982 } else
4983 return 0; /* N/A */
ea1fb29a 4984
df694daa 4985 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4986 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4987 if (err < 0)
df694daa
KY
4988 return err;
4989 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4990 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4991 if (err < 0)
df694daa
KY
4992 return err;
4993 return 1;
4994}
4995
4996/* add playback controls from the parsed DAC table */
4997static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4998 const struct auto_pin_cfg *cfg)
4999{
5000 hda_nid_t nid;
5001 int err;
5002
5003 spec->multiout.num_dacs = 1;
5004 spec->multiout.dac_nids = spec->private_dac_nids;
5005 spec->multiout.dac_nids[0] = 0x02;
5006
5007 nid = cfg->line_out_pins[0];
5008 if (nid) {
5009 err = alc260_add_playback_controls(spec, nid, "Front");
5010 if (err < 0)
5011 return err;
5012 }
5013
82bc955f 5014 nid = cfg->speaker_pins[0];
df694daa
KY
5015 if (nid) {
5016 err = alc260_add_playback_controls(spec, nid, "Speaker");
5017 if (err < 0)
5018 return err;
5019 }
5020
eb06ed8f 5021 nid = cfg->hp_pins[0];
df694daa
KY
5022 if (nid) {
5023 err = alc260_add_playback_controls(spec, nid, "Headphone");
5024 if (err < 0)
5025 return err;
5026 }
f12ab1e0 5027 return 0;
df694daa
KY
5028}
5029
5030/* create playback/capture controls for input pins */
5031static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5032 const struct auto_pin_cfg *cfg)
5033{
df694daa
KY
5034 struct hda_input_mux *imux = &spec->private_imux;
5035 int i, err, idx;
5036
5037 for (i = 0; i < AUTO_PIN_LAST; i++) {
5038 if (cfg->input_pins[i] >= 0x12) {
5039 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5040 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5041 auto_pin_cfg_labels[i], idx,
5042 0x07);
df694daa
KY
5043 if (err < 0)
5044 return err;
f12ab1e0
TI
5045 imux->items[imux->num_items].label =
5046 auto_pin_cfg_labels[i];
df694daa
KY
5047 imux->items[imux->num_items].index = idx;
5048 imux->num_items++;
5049 }
f12ab1e0 5050 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5051 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5052 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5053 auto_pin_cfg_labels[i], idx,
5054 0x07);
df694daa
KY
5055 if (err < 0)
5056 return err;
f12ab1e0
TI
5057 imux->items[imux->num_items].label =
5058 auto_pin_cfg_labels[i];
df694daa
KY
5059 imux->items[imux->num_items].index = idx;
5060 imux->num_items++;
5061 }
5062 }
5063 return 0;
5064}
5065
5066static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5067 hda_nid_t nid, int pin_type,
5068 int sel_idx)
5069{
f6c7e546 5070 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5071 /* need the manual connection? */
5072 if (nid >= 0x12) {
5073 int idx = nid - 0x12;
5074 snd_hda_codec_write(codec, idx + 0x0b, 0,
5075 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5076 }
5077}
5078
5079static void alc260_auto_init_multi_out(struct hda_codec *codec)
5080{
5081 struct alc_spec *spec = codec->spec;
5082 hda_nid_t nid;
5083
bc9f98a9 5084 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 5085 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5086 if (nid) {
5087 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5088 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5089 }
ea1fb29a 5090
82bc955f 5091 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5092 if (nid)
5093 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5094
eb06ed8f 5095 nid = spec->autocfg.hp_pins[0];
df694daa 5096 if (nid)
baba8ee9 5097 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5098}
df694daa
KY
5099
5100#define ALC260_PIN_CD_NID 0x16
5101static void alc260_auto_init_analog_input(struct hda_codec *codec)
5102{
5103 struct alc_spec *spec = codec->spec;
5104 int i;
5105
5106 for (i = 0; i < AUTO_PIN_LAST; i++) {
5107 hda_nid_t nid = spec->autocfg.input_pins[i];
5108 if (nid >= 0x12) {
f12ab1e0
TI
5109 snd_hda_codec_write(codec, nid, 0,
5110 AC_VERB_SET_PIN_WIDGET_CONTROL,
5111 i <= AUTO_PIN_FRONT_MIC ?
5112 PIN_VREF80 : PIN_IN);
df694daa 5113 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
5114 snd_hda_codec_write(codec, nid, 0,
5115 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5116 AMP_OUT_MUTE);
5117 }
5118 }
5119}
5120
5121/*
5122 * generic initialization of ADC, input mixers and output mixers
5123 */
5124static struct hda_verb alc260_volume_init_verbs[] = {
5125 /*
5126 * Unmute ADC0-1 and set the default input to mic-in
5127 */
5128 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5130 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5131 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5132
df694daa
KY
5133 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5134 * mixer widget
f12ab1e0
TI
5135 * Note: PASD motherboards uses the Line In 2 as the input for
5136 * front panel mic (mic 2)
df694daa
KY
5137 */
5138 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5139 /* mute analog inputs */
5140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5145
5146 /*
5147 * Set up output mixers (0x08 - 0x0a)
5148 */
5149 /* set vol=0 to output mixers */
5150 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5152 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5153 /* set up input amps for analog loopback */
5154 /* Amp Indices: DAC = 0, mixer = 1 */
5155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5159 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5161
df694daa
KY
5162 { }
5163};
5164
5165static int alc260_parse_auto_config(struct hda_codec *codec)
5166{
5167 struct alc_spec *spec = codec->spec;
5168 unsigned int wcap;
5169 int err;
5170 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5171
f12ab1e0
TI
5172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5173 alc260_ignore);
5174 if (err < 0)
df694daa 5175 return err;
f12ab1e0
TI
5176 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5177 if (err < 0)
4a471b7d 5178 return err;
f12ab1e0 5179 if (!spec->kctl_alloc)
df694daa 5180 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5181 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5182 if (err < 0)
df694daa
KY
5183 return err;
5184
5185 spec->multiout.max_channels = 2;
5186
5187 if (spec->autocfg.dig_out_pin)
5188 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5189 if (spec->kctl_alloc)
5190 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5191
5192 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5193
a1e8d2da 5194 spec->num_mux_defs = 1;
df694daa
KY
5195 spec->input_mux = &spec->private_imux;
5196
5197 /* check whether NID 0x04 is valid */
4a471b7d 5198 wcap = get_wcaps(codec, 0x04);
df694daa 5199 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
67ebcb03 5200 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
df694daa
KY
5201 spec->adc_nids = alc260_adc_nids_alt;
5202 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5203 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
5204 } else {
5205 spec->adc_nids = alc260_adc_nids;
5206 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5207 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 5208 }
4a471b7d 5209 spec->num_mixers++;
df694daa
KY
5210
5211 return 1;
5212}
5213
ae6b813a
TI
5214/* additional initialization for auto-configuration model */
5215static void alc260_auto_init(struct hda_codec *codec)
df694daa 5216{
f6c7e546 5217 struct alc_spec *spec = codec->spec;
df694daa
KY
5218 alc260_auto_init_multi_out(codec);
5219 alc260_auto_init_analog_input(codec);
f6c7e546
TI
5220 if (spec->unsol_event)
5221 alc_sku_automute(codec);
df694daa
KY
5222}
5223
cb53c626
TI
5224#ifdef CONFIG_SND_HDA_POWER_SAVE
5225static struct hda_amp_list alc260_loopbacks[] = {
5226 { 0x07, HDA_INPUT, 0 },
5227 { 0x07, HDA_INPUT, 1 },
5228 { 0x07, HDA_INPUT, 2 },
5229 { 0x07, HDA_INPUT, 3 },
5230 { 0x07, HDA_INPUT, 4 },
5231 { } /* end */
5232};
5233#endif
5234
df694daa
KY
5235/*
5236 * ALC260 configurations
5237 */
f5fcc13c
TI
5238static const char *alc260_models[ALC260_MODEL_LAST] = {
5239 [ALC260_BASIC] = "basic",
5240 [ALC260_HP] = "hp",
5241 [ALC260_HP_3013] = "hp-3013",
5242 [ALC260_FUJITSU_S702X] = "fujitsu",
5243 [ALC260_ACER] = "acer",
bc9f98a9
KY
5244 [ALC260_WILL] = "will",
5245 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 5246#ifdef CONFIG_SND_DEBUG
f5fcc13c 5247 [ALC260_TEST] = "test",
7cf51e48 5248#endif
f5fcc13c
TI
5249 [ALC260_AUTO] = "auto",
5250};
5251
5252static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5253 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5254 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5255 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5256 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 5257 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 5258 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 5259 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
5260 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5261 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5262 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5263 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5264 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5265 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5266 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5267 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5268 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5269 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5270 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5271 {}
5272};
5273
5274static struct alc_config_preset alc260_presets[] = {
5275 [ALC260_BASIC] = {
5276 .mixers = { alc260_base_output_mixer,
5277 alc260_input_mixer,
5278 alc260_pc_beep_mixer,
5279 alc260_capture_mixer },
5280 .init_verbs = { alc260_init_verbs },
5281 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5282 .dac_nids = alc260_dac_nids,
5283 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5284 .adc_nids = alc260_adc_nids,
5285 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5286 .channel_mode = alc260_modes,
5287 .input_mux = &alc260_capture_source,
5288 },
5289 [ALC260_HP] = {
bec15c3a 5290 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5291 alc260_input_mixer,
5292 alc260_capture_alt_mixer },
bec15c3a
TI
5293 .init_verbs = { alc260_init_verbs,
5294 alc260_hp_unsol_verbs },
df694daa
KY
5295 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5296 .dac_nids = alc260_dac_nids,
5297 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5298 .adc_nids = alc260_hp_adc_nids,
5299 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5300 .channel_mode = alc260_modes,
5301 .input_mux = &alc260_capture_source,
bec15c3a
TI
5302 .unsol_event = alc260_hp_unsol_event,
5303 .init_hook = alc260_hp_automute,
df694daa 5304 },
3f878308
KY
5305 [ALC260_HP_DC7600] = {
5306 .mixers = { alc260_hp_dc7600_mixer,
5307 alc260_input_mixer,
5308 alc260_capture_alt_mixer },
5309 .init_verbs = { alc260_init_verbs,
5310 alc260_hp_dc7600_verbs },
5311 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5312 .dac_nids = alc260_dac_nids,
5313 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5314 .adc_nids = alc260_hp_adc_nids,
5315 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5316 .channel_mode = alc260_modes,
5317 .input_mux = &alc260_capture_source,
5318 .unsol_event = alc260_hp_3012_unsol_event,
5319 .init_hook = alc260_hp_3012_automute,
5320 },
df694daa
KY
5321 [ALC260_HP_3013] = {
5322 .mixers = { alc260_hp_3013_mixer,
5323 alc260_input_mixer,
5324 alc260_capture_alt_mixer },
bec15c3a
TI
5325 .init_verbs = { alc260_hp_3013_init_verbs,
5326 alc260_hp_3013_unsol_verbs },
df694daa
KY
5327 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5328 .dac_nids = alc260_dac_nids,
5329 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5330 .adc_nids = alc260_hp_adc_nids,
5331 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5332 .channel_mode = alc260_modes,
5333 .input_mux = &alc260_capture_source,
bec15c3a
TI
5334 .unsol_event = alc260_hp_3013_unsol_event,
5335 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5336 },
5337 [ALC260_FUJITSU_S702X] = {
5338 .mixers = { alc260_fujitsu_mixer,
5339 alc260_capture_mixer },
5340 .init_verbs = { alc260_fujitsu_init_verbs },
5341 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5342 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5343 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5344 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5345 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5346 .channel_mode = alc260_modes,
a1e8d2da
JW
5347 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5348 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5349 },
0bfc90e9
JW
5350 [ALC260_ACER] = {
5351 .mixers = { alc260_acer_mixer,
5352 alc260_capture_mixer },
5353 .init_verbs = { alc260_acer_init_verbs },
5354 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5355 .dac_nids = alc260_dac_nids,
5356 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5357 .adc_nids = alc260_dual_adc_nids,
5358 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5359 .channel_mode = alc260_modes,
a1e8d2da
JW
5360 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5361 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5362 },
bc9f98a9
KY
5363 [ALC260_WILL] = {
5364 .mixers = { alc260_will_mixer,
5365 alc260_capture_mixer },
5366 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5367 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5368 .dac_nids = alc260_dac_nids,
5369 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5370 .adc_nids = alc260_adc_nids,
5371 .dig_out_nid = ALC260_DIGOUT_NID,
5372 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5373 .channel_mode = alc260_modes,
5374 .input_mux = &alc260_capture_source,
5375 },
5376 [ALC260_REPLACER_672V] = {
5377 .mixers = { alc260_replacer_672v_mixer,
5378 alc260_capture_mixer },
5379 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5380 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5381 .dac_nids = alc260_dac_nids,
5382 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5383 .adc_nids = alc260_adc_nids,
5384 .dig_out_nid = ALC260_DIGOUT_NID,
5385 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5386 .channel_mode = alc260_modes,
5387 .input_mux = &alc260_capture_source,
5388 .unsol_event = alc260_replacer_672v_unsol_event,
5389 .init_hook = alc260_replacer_672v_automute,
5390 },
7cf51e48
JW
5391#ifdef CONFIG_SND_DEBUG
5392 [ALC260_TEST] = {
5393 .mixers = { alc260_test_mixer,
5394 alc260_capture_mixer },
5395 .init_verbs = { alc260_test_init_verbs },
5396 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5397 .dac_nids = alc260_test_dac_nids,
5398 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5399 .adc_nids = alc260_test_adc_nids,
5400 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5401 .channel_mode = alc260_modes,
a1e8d2da
JW
5402 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5403 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5404 },
5405#endif
df694daa
KY
5406};
5407
5408static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5409{
5410 struct alc_spec *spec;
df694daa 5411 int err, board_config;
1da177e4 5412
e560d8d8 5413 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5414 if (spec == NULL)
5415 return -ENOMEM;
5416
5417 codec->spec = spec;
5418
f5fcc13c
TI
5419 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5420 alc260_models,
5421 alc260_cfg_tbl);
5422 if (board_config < 0) {
9c7f852e
TI
5423 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5424 "trying auto-probe from BIOS...\n");
df694daa 5425 board_config = ALC260_AUTO;
16ded525 5426 }
1da177e4 5427
df694daa
KY
5428 if (board_config == ALC260_AUTO) {
5429 /* automatic parse from the BIOS config */
5430 err = alc260_parse_auto_config(codec);
5431 if (err < 0) {
5432 alc_free(codec);
5433 return err;
f12ab1e0 5434 } else if (!err) {
9c7f852e
TI
5435 printk(KERN_INFO
5436 "hda_codec: Cannot set up configuration "
5437 "from BIOS. Using base mode...\n");
df694daa
KY
5438 board_config = ALC260_BASIC;
5439 }
a9430dd8 5440 }
e9edcee0 5441
df694daa
KY
5442 if (board_config != ALC260_AUTO)
5443 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5444
5445 spec->stream_name_analog = "ALC260 Analog";
5446 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5447 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5448
a3bcba38
TI
5449 spec->stream_name_digital = "ALC260 Digital";
5450 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5451 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5452
2134ea4f
TI
5453 spec->vmaster_nid = 0x08;
5454
1da177e4 5455 codec->patch_ops = alc_patch_ops;
df694daa 5456 if (board_config == ALC260_AUTO)
ae6b813a 5457 spec->init_hook = alc260_auto_init;
cb53c626
TI
5458#ifdef CONFIG_SND_HDA_POWER_SAVE
5459 if (!spec->loopback.amplist)
5460 spec->loopback.amplist = alc260_loopbacks;
5461#endif
1da177e4
LT
5462
5463 return 0;
5464}
5465
e9edcee0 5466
1da177e4
LT
5467/*
5468 * ALC882 support
5469 *
5470 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5471 * configuration. Each pin widget can choose any input DACs and a mixer.
5472 * Each ADC is connected from a mixer of all inputs. This makes possible
5473 * 6-channel independent captures.
5474 *
5475 * In addition, an independent DAC for the multi-playback (not used in this
5476 * driver yet).
5477 */
df694daa
KY
5478#define ALC882_DIGOUT_NID 0x06
5479#define ALC882_DIGIN_NID 0x0a
1da177e4 5480
d2a6d7dc 5481static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5482 { 8, NULL }
5483};
5484
5485static hda_nid_t alc882_dac_nids[4] = {
5486 /* front, rear, clfe, rear_surr */
5487 0x02, 0x03, 0x04, 0x05
5488};
5489
df694daa
KY
5490/* identical with ALC880 */
5491#define alc882_adc_nids alc880_adc_nids
5492#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5493
e1406348
TI
5494static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5495static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5496
1da177e4
LT
5497/* input MUX */
5498/* FIXME: should be a matrix-type input source selection */
5499
5500static struct hda_input_mux alc882_capture_source = {
5501 .num_items = 4,
5502 .items = {
5503 { "Mic", 0x0 },
5504 { "Front Mic", 0x1 },
5505 { "Line", 0x2 },
5506 { "CD", 0x4 },
5507 },
5508};
1da177e4
LT
5509#define alc882_mux_enum_info alc_mux_enum_info
5510#define alc882_mux_enum_get alc_mux_enum_get
5511
f12ab1e0
TI
5512static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5513 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5514{
5515 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5516 struct alc_spec *spec = codec->spec;
5517 const struct hda_input_mux *imux = spec->input_mux;
5518 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
88c71a99
TI
5519 hda_nid_t nid = spec->capsrc_nids ?
5520 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4
LT
5521 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5522 unsigned int i, idx;
5523
5524 idx = ucontrol->value.enumerated.item[0];
5525 if (idx >= imux->num_items)
5526 idx = imux->num_items - 1;
82beb8fd 5527 if (*cur_val == idx)
1da177e4
LT
5528 return 0;
5529 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5530 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5531 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5532 imux->items[i].index,
47fd830a 5533 HDA_AMP_MUTE, v);
1da177e4
LT
5534 }
5535 *cur_val = idx;
5536 return 1;
5537}
5538
272a527c
KY
5539/*
5540 * 2ch mode
5541 */
5542static struct hda_verb alc882_3ST_ch2_init[] = {
5543 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5544 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5545 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5546 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5547 { } /* end */
5548};
5549
5550/*
5551 * 6ch mode
5552 */
5553static struct hda_verb alc882_3ST_ch6_init[] = {
5554 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5555 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5556 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5557 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5558 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5559 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5560 { } /* end */
5561};
5562
5563static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5564 { 2, alc882_3ST_ch2_init },
5565 { 6, alc882_3ST_ch6_init },
5566};
5567
df694daa
KY
5568/*
5569 * 6ch mode
5570 */
5571static struct hda_verb alc882_sixstack_ch6_init[] = {
5572 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5573 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5574 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5575 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5576 { } /* end */
5577};
5578
5579/*
5580 * 8ch mode
5581 */
5582static struct hda_verb alc882_sixstack_ch8_init[] = {
5583 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5584 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5585 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5586 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5587 { } /* end */
5588};
5589
5590static struct hda_channel_mode alc882_sixstack_modes[2] = {
5591 { 6, alc882_sixstack_ch6_init },
5592 { 8, alc882_sixstack_ch8_init },
5593};
5594
87350ad0
TI
5595/*
5596 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5597 */
5598
5599/*
5600 * 2ch mode
5601 */
5602static struct hda_verb alc885_mbp_ch2_init[] = {
5603 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5604 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5605 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5606 { } /* end */
5607};
5608
5609/*
5610 * 6ch mode
5611 */
5612static struct hda_verb alc885_mbp_ch6_init[] = {
5613 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5614 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5615 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5616 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5618 { } /* end */
5619};
5620
5621static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5622 { 2, alc885_mbp_ch2_init },
5623 { 6, alc885_mbp_ch6_init },
5624};
5625
5626
1da177e4
LT
5627/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5628 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5629 */
c8b6bf9b 5630static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5631 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5633 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5634 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5635 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5636 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5637 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5638 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5639 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5640 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5647 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5650 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5652 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5653 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5654 { } /* end */
5655};
5656
87350ad0 5657static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5658 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5659 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5660 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5661 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5662 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5663 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5665 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5666 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5668 { } /* end */
5669};
bdd148a3
KY
5670static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5671 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5672 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5680 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5681 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5682 { } /* end */
5683};
5684
272a527c
KY
5685static struct snd_kcontrol_new alc882_targa_mixer[] = {
5686 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5687 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5689 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5690 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5691 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5692 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5695 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5696 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5699 { } /* end */
5700};
5701
5702/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5703 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5704 */
5705static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5706 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5707 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5708 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5709 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5710 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5711 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5714 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5715 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5718 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5719 { } /* end */
5720};
5721
914759b7
TI
5722static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5723 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5724 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5726 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5727 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5728 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5729 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5731 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5733 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5734 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5735 { } /* end */
5736};
5737
df694daa
KY
5738static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5739 {
5740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5741 .name = "Channel Mode",
5742 .info = alc_ch_mode_info,
5743 .get = alc_ch_mode_get,
5744 .put = alc_ch_mode_put,
5745 },
5746 { } /* end */
5747};
5748
1da177e4
LT
5749static struct hda_verb alc882_init_verbs[] = {
5750 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5754 /* Rear mixer */
05acb863
TI
5755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5757 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5758 /* CLFE mixer */
05acb863
TI
5759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5761 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5762 /* Side mixer */
05acb863
TI
5763 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5766
e9edcee0 5767 /* Front Pin: output 0 (0x0c) */
05acb863 5768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5770 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5771 /* Rear Pin: output 1 (0x0d) */
05acb863 5772 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5773 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5774 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5775 /* CLFE Pin: output 2 (0x0e) */
05acb863 5776 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5777 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5778 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5779 /* Side Pin: output 3 (0x0f) */
05acb863 5780 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5781 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5782 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5783 /* Mic (rear) pin: input vref at 80% */
16ded525 5784 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5786 /* Front Mic pin: input vref at 80% */
16ded525 5787 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5789 /* Line In pin: input */
05acb863 5790 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5791 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5792 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5793 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5794 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5795 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5796 /* CD pin widget for input */
05acb863 5797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5798
5799 /* FIXME: use matrix-type input source selection */
5800 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5801 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5802 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5803 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5806 /* Input mixer2 */
05acb863
TI
5807 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5808 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5810 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5811 /* Input mixer3 */
05acb863
TI
5812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5813 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5816 /* ADC1: mute amp left and right */
5817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5818 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5819 /* ADC2: mute amp left and right */
5820 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5821 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5822 /* ADC3: mute amp left and right */
5823 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5824 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5825
5826 { }
5827};
5828
4b146cb0
TI
5829static struct hda_verb alc882_eapd_verbs[] = {
5830 /* change to EAPD mode */
5831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5832 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5833 { }
4b146cb0
TI
5834};
5835
9102cd1c
TD
5836/* Mac Pro test */
5837static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5838 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5841 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5842 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5843 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5844 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5845 { } /* end */
5846};
5847
5848static struct hda_verb alc882_macpro_init_verbs[] = {
5849 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5853 /* Front Pin: output 0 (0x0c) */
5854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5857 /* Front Mic pin: input vref at 80% */
5858 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5860 /* Speaker: output */
5861 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5863 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5864 /* Headphone output (output 0 - 0x0c) */
5865 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5866 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5867 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5868
5869 /* FIXME: use matrix-type input source selection */
5870 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5871 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5876 /* Input mixer2 */
5877 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5878 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5879 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5881 /* Input mixer3 */
5882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5884 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5886 /* ADC1: mute amp left and right */
5887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5888 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5889 /* ADC2: mute amp left and right */
5890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5891 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5892 /* ADC3: mute amp left and right */
5893 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5894 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5895
5896 { }
5897};
f12ab1e0 5898
87350ad0
TI
5899/* Macbook Pro rev3 */
5900static struct hda_verb alc885_mbp3_init_verbs[] = {
5901 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5905 /* Rear mixer */
5906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5909 /* Front Pin: output 0 (0x0c) */
5910 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5911 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5912 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5913 /* HP Pin: output 0 (0x0d) */
5914 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5915 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5916 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5917 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5918 /* Mic (rear) pin: input vref at 80% */
5919 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5920 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5921 /* Front Mic pin: input vref at 80% */
5922 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5923 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5924 /* Line In pin: use output 1 when in LineOut mode */
5925 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5927 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5928
5929 /* FIXME: use matrix-type input source selection */
5930 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5931 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5932 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5933 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5934 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5935 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5936 /* Input mixer2 */
5937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5939 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5940 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5941 /* Input mixer3 */
5942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5944 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5946 /* ADC1: mute amp left and right */
5947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5948 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5949 /* ADC2: mute amp left and right */
5950 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5951 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5952 /* ADC3: mute amp left and right */
5953 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5954 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5955
5956 { }
5957};
5958
c54728d8
NF
5959/* iMac 24 mixer. */
5960static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5961 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5962 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5963 { } /* end */
5964};
5965
5966/* iMac 24 init verbs. */
5967static struct hda_verb alc885_imac24_init_verbs[] = {
5968 /* Internal speakers: output 0 (0x0c) */
5969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5970 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5971 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5972 /* Internal speakers: output 0 (0x0c) */
5973 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5974 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5975 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5976 /* Headphone: output 0 (0x0c) */
5977 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5979 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5980 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5981 /* Front Mic: input vref at 80% */
5982 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5983 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5984 { }
5985};
5986
5987/* Toggle speaker-output according to the hp-jack state */
5988static void alc885_imac24_automute(struct hda_codec *codec)
5989{
5990 unsigned int present;
5991
5992 present = snd_hda_codec_read(codec, 0x14, 0,
5993 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5994 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5995 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5996 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5997 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5998}
5999
6000/* Processes unsolicited events. */
6001static void alc885_imac24_unsol_event(struct hda_codec *codec,
6002 unsigned int res)
6003{
6004 /* Headphone insertion or removal. */
6005 if ((res >> 26) == ALC880_HP_EVENT)
6006 alc885_imac24_automute(codec);
6007}
6008
87350ad0
TI
6009static void alc885_mbp3_automute(struct hda_codec *codec)
6010{
6011 unsigned int present;
6012
6013 present = snd_hda_codec_read(codec, 0x15, 0,
6014 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6015 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6016 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6017 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6018 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6019
6020}
6021static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6022 unsigned int res)
6023{
6024 /* Headphone insertion or removal. */
6025 if ((res >> 26) == ALC880_HP_EVENT)
6026 alc885_mbp3_automute(codec);
6027}
6028
6029
272a527c
KY
6030static struct hda_verb alc882_targa_verbs[] = {
6031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6033
6034 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6035 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6036
272a527c
KY
6037 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6038 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6039 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6040
6041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6042 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6043 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6044 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6045 { } /* end */
6046};
6047
6048/* toggle speaker-output according to the hp-jack state */
6049static void alc882_targa_automute(struct hda_codec *codec)
6050{
6051 unsigned int present;
ea1fb29a 6052
272a527c
KY
6053 present = snd_hda_codec_read(codec, 0x14, 0,
6054 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6055 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6056 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
6057 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6058 present ? 1 : 3);
272a527c
KY
6059}
6060
6061static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6062{
6063 /* Looks like the unsol event is incompatible with the standard
6064 * definition. 4bit tag is placed at 26 bit!
6065 */
6066 if (((res >> 26) == ALC880_HP_EVENT)) {
6067 alc882_targa_automute(codec);
6068 }
6069}
6070
6071static struct hda_verb alc882_asus_a7j_verbs[] = {
6072 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6074
6075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6076 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6077 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6078
272a527c
KY
6079 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6081 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6082
6083 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6084 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6085 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6086 { } /* end */
6087};
6088
914759b7
TI
6089static struct hda_verb alc882_asus_a7m_verbs[] = {
6090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6092
6093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6094 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6095 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6096
914759b7
TI
6097 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6098 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6099 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6100
6101 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6102 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6104 { } /* end */
6105};
6106
9102cd1c
TD
6107static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6108{
6109 unsigned int gpiostate, gpiomask, gpiodir;
6110
6111 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6112 AC_VERB_GET_GPIO_DATA, 0);
6113
6114 if (!muted)
6115 gpiostate |= (1 << pin);
6116 else
6117 gpiostate &= ~(1 << pin);
6118
6119 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6120 AC_VERB_GET_GPIO_MASK, 0);
6121 gpiomask |= (1 << pin);
6122
6123 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6124 AC_VERB_GET_GPIO_DIRECTION, 0);
6125 gpiodir |= (1 << pin);
6126
6127
6128 snd_hda_codec_write(codec, codec->afg, 0,
6129 AC_VERB_SET_GPIO_MASK, gpiomask);
6130 snd_hda_codec_write(codec, codec->afg, 0,
6131 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6132
6133 msleep(1);
6134
6135 snd_hda_codec_write(codec, codec->afg, 0,
6136 AC_VERB_SET_GPIO_DATA, gpiostate);
6137}
6138
7debbe51
TI
6139/* set up GPIO at initialization */
6140static void alc885_macpro_init_hook(struct hda_codec *codec)
6141{
6142 alc882_gpio_mute(codec, 0, 0);
6143 alc882_gpio_mute(codec, 1, 0);
6144}
6145
6146/* set up GPIO and update auto-muting at initialization */
6147static void alc885_imac24_init_hook(struct hda_codec *codec)
6148{
6149 alc885_macpro_init_hook(codec);
6150 alc885_imac24_automute(codec);
6151}
6152
df694daa
KY
6153/*
6154 * generic initialization of ADC, input mixers and output mixers
6155 */
6156static struct hda_verb alc882_auto_init_verbs[] = {
6157 /*
6158 * Unmute ADC0-2 and set the default input to mic-in
6159 */
6160 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6162 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6163 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6164 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6165 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6166
cb53c626 6167 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6168 * mixer widget
f12ab1e0
TI
6169 * Note: PASD motherboards uses the Line In 2 as the input for
6170 * front panel mic (mic 2)
df694daa
KY
6171 */
6172 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6175 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6176 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6177 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 6178
df694daa
KY
6179 /*
6180 * Set up output mixers (0x0c - 0x0f)
6181 */
6182 /* set vol=0 to output mixers */
6183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6185 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6186 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6187 /* set up input amps for analog loopback */
6188 /* Amp Indices: DAC = 0, mixer = 1 */
6189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6190 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6191 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6192 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6193 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6196 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6197 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6198 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6199
6200 /* FIXME: use matrix-type input source selection */
6201 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6202 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6203 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6207 /* Input mixer2 */
6208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6212 /* Input mixer3 */
6213 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6217
6218 { }
6219};
6220
6221/* capture mixer elements */
6222static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6223 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6224 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6225 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6226 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6227 {
6228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6229 /* The multiple "Capture Source" controls confuse alsamixer
6230 * So call somewhat different..
df694daa
KY
6231 */
6232 /* .name = "Capture Source", */
6233 .name = "Input Source",
6234 .count = 2,
6235 .info = alc882_mux_enum_info,
6236 .get = alc882_mux_enum_get,
6237 .put = alc882_mux_enum_put,
6238 },
6239 { } /* end */
6240};
6241
6242static struct snd_kcontrol_new alc882_capture_mixer[] = {
6243 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6244 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6245 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6246 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6247 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6248 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6249 {
6250 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6251 /* The multiple "Capture Source" controls confuse alsamixer
6252 * So call somewhat different..
df694daa
KY
6253 */
6254 /* .name = "Capture Source", */
6255 .name = "Input Source",
6256 .count = 3,
6257 .info = alc882_mux_enum_info,
6258 .get = alc882_mux_enum_get,
6259 .put = alc882_mux_enum_put,
6260 },
6261 { } /* end */
6262};
6263
cb53c626
TI
6264#ifdef CONFIG_SND_HDA_POWER_SAVE
6265#define alc882_loopbacks alc880_loopbacks
6266#endif
6267
df694daa
KY
6268/* pcm configuration: identiacal with ALC880 */
6269#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6270#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6271#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6272#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6273
6274/*
6275 * configuration and preset
6276 */
f5fcc13c
TI
6277static const char *alc882_models[ALC882_MODEL_LAST] = {
6278 [ALC882_3ST_DIG] = "3stack-dig",
6279 [ALC882_6ST_DIG] = "6stack-dig",
6280 [ALC882_ARIMA] = "arima",
bdd148a3 6281 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6282 [ALC882_TARGA] = "targa",
6283 [ALC882_ASUS_A7J] = "asus-a7j",
6284 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6285 [ALC885_MACPRO] = "macpro",
87350ad0 6286 [ALC885_MBP3] = "mbp3",
c54728d8 6287 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6288 [ALC882_AUTO] = "auto",
6289};
6290
6291static struct snd_pci_quirk alc882_cfg_tbl[] = {
6292 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6293 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6294 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6295 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6296 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6297 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6298 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6299 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6300 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6301 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6302 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6303 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6304 {}
6305};
6306
6307static struct alc_config_preset alc882_presets[] = {
6308 [ALC882_3ST_DIG] = {
6309 .mixers = { alc882_base_mixer },
6310 .init_verbs = { alc882_init_verbs },
6311 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6312 .dac_nids = alc882_dac_nids,
6313 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6314 .dig_in_nid = ALC882_DIGIN_NID,
6315 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6316 .channel_mode = alc882_ch_modes,
4e195a7b 6317 .need_dac_fix = 1,
df694daa
KY
6318 .input_mux = &alc882_capture_source,
6319 },
6320 [ALC882_6ST_DIG] = {
6321 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6322 .init_verbs = { alc882_init_verbs },
6323 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6324 .dac_nids = alc882_dac_nids,
6325 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6326 .dig_in_nid = ALC882_DIGIN_NID,
6327 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6328 .channel_mode = alc882_sixstack_modes,
6329 .input_mux = &alc882_capture_source,
6330 },
4b146cb0
TI
6331 [ALC882_ARIMA] = {
6332 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6333 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6334 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6335 .dac_nids = alc882_dac_nids,
6336 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6337 .channel_mode = alc882_sixstack_modes,
6338 .input_mux = &alc882_capture_source,
6339 },
bdd148a3
KY
6340 [ALC882_W2JC] = {
6341 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6342 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6343 alc880_gpio1_init_verbs },
6344 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6345 .dac_nids = alc882_dac_nids,
6346 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6347 .channel_mode = alc880_threestack_modes,
6348 .need_dac_fix = 1,
6349 .input_mux = &alc882_capture_source,
6350 .dig_out_nid = ALC882_DIGOUT_NID,
6351 },
87350ad0
TI
6352 [ALC885_MBP3] = {
6353 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6354 .init_verbs = { alc885_mbp3_init_verbs,
6355 alc880_gpio1_init_verbs },
6356 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6357 .dac_nids = alc882_dac_nids,
6358 .channel_mode = alc885_mbp_6ch_modes,
6359 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6360 .input_mux = &alc882_capture_source,
6361 .dig_out_nid = ALC882_DIGOUT_NID,
6362 .dig_in_nid = ALC882_DIGIN_NID,
6363 .unsol_event = alc885_mbp3_unsol_event,
6364 .init_hook = alc885_mbp3_automute,
6365 },
9102cd1c
TD
6366 [ALC885_MACPRO] = {
6367 .mixers = { alc882_macpro_mixer },
6368 .init_verbs = { alc882_macpro_init_verbs },
6369 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6370 .dac_nids = alc882_dac_nids,
6371 .dig_out_nid = ALC882_DIGOUT_NID,
6372 .dig_in_nid = ALC882_DIGIN_NID,
6373 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6374 .channel_mode = alc882_ch_modes,
6375 .input_mux = &alc882_capture_source,
7debbe51 6376 .init_hook = alc885_macpro_init_hook,
9102cd1c 6377 },
c54728d8
NF
6378 [ALC885_IMAC24] = {
6379 .mixers = { alc885_imac24_mixer },
6380 .init_verbs = { alc885_imac24_init_verbs },
6381 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6382 .dac_nids = alc882_dac_nids,
6383 .dig_out_nid = ALC882_DIGOUT_NID,
6384 .dig_in_nid = ALC882_DIGIN_NID,
6385 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6386 .channel_mode = alc882_ch_modes,
6387 .input_mux = &alc882_capture_source,
6388 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6389 .init_hook = alc885_imac24_init_hook,
c54728d8 6390 },
272a527c
KY
6391 [ALC882_TARGA] = {
6392 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6393 alc882_capture_mixer },
6394 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6395 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6396 .dac_nids = alc882_dac_nids,
6397 .dig_out_nid = ALC882_DIGOUT_NID,
6398 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6399 .adc_nids = alc882_adc_nids,
e1406348 6400 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6401 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6402 .channel_mode = alc882_3ST_6ch_modes,
6403 .need_dac_fix = 1,
6404 .input_mux = &alc882_capture_source,
6405 .unsol_event = alc882_targa_unsol_event,
6406 .init_hook = alc882_targa_automute,
6407 },
6408 [ALC882_ASUS_A7J] = {
6409 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6410 alc882_capture_mixer },
6411 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6412 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6413 .dac_nids = alc882_dac_nids,
6414 .dig_out_nid = ALC882_DIGOUT_NID,
6415 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6416 .adc_nids = alc882_adc_nids,
e1406348 6417 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6418 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6419 .channel_mode = alc882_3ST_6ch_modes,
6420 .need_dac_fix = 1,
6421 .input_mux = &alc882_capture_source,
ea1fb29a 6422 },
914759b7
TI
6423 [ALC882_ASUS_A7M] = {
6424 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6425 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6426 alc880_gpio1_init_verbs,
6427 alc882_asus_a7m_verbs },
6428 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6429 .dac_nids = alc882_dac_nids,
6430 .dig_out_nid = ALC882_DIGOUT_NID,
6431 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6432 .channel_mode = alc880_threestack_modes,
6433 .need_dac_fix = 1,
6434 .input_mux = &alc882_capture_source,
ea1fb29a 6435 },
df694daa
KY
6436};
6437
6438
f95474ec
TI
6439/*
6440 * Pin config fixes
6441 */
ea1fb29a 6442enum {
f95474ec
TI
6443 PINFIX_ABIT_AW9D_MAX
6444};
6445
6446static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6447 { 0x15, 0x01080104 }, /* side */
6448 { 0x16, 0x01011012 }, /* rear */
6449 { 0x17, 0x01016011 }, /* clfe */
6450 { }
6451};
6452
6453static const struct alc_pincfg *alc882_pin_fixes[] = {
6454 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6455};
6456
6457static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6458 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6459 {}
6460};
6461
df694daa
KY
6462/*
6463 * BIOS auto configuration
6464 */
6465static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6466 hda_nid_t nid, int pin_type,
6467 int dac_idx)
6468{
6469 /* set as output */
6470 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6471 int idx;
6472
f6c7e546 6473 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6474 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6475 idx = 4;
6476 else
6477 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6478 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6479
6480}
6481
6482static void alc882_auto_init_multi_out(struct hda_codec *codec)
6483{
6484 struct alc_spec *spec = codec->spec;
6485 int i;
6486
bc9f98a9 6487 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6488 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6489 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6490 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6491 if (nid)
baba8ee9 6492 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6493 i);
df694daa
KY
6494 }
6495}
6496
6497static void alc882_auto_init_hp_out(struct hda_codec *codec)
6498{
6499 struct alc_spec *spec = codec->spec;
6500 hda_nid_t pin;
6501
eb06ed8f 6502 pin = spec->autocfg.hp_pins[0];
df694daa 6503 if (pin) /* connect to front */
f12ab1e0
TI
6504 /* use dac 0 */
6505 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6506 pin = spec->autocfg.speaker_pins[0];
6507 if (pin)
6508 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6509}
6510
6511#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6512#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6513
6514static void alc882_auto_init_analog_input(struct hda_codec *codec)
6515{
6516 struct alc_spec *spec = codec->spec;
6517 int i;
6518
6519 for (i = 0; i < AUTO_PIN_LAST; i++) {
6520 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
6521 unsigned int vref;
6522 if (!nid)
6523 continue;
6524 vref = PIN_IN;
6525 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
531240ff
KY
6526 unsigned int pincap;
6527 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6528 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
7194cae6
TI
6529 AC_PINCAP_VREF_80)
6530 vref = PIN_VREF80;
df694daa 6531 }
7194cae6
TI
6532 snd_hda_codec_write(codec, nid, 0,
6533 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6534 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6535 snd_hda_codec_write(codec, nid, 0,
6536 AC_VERB_SET_AMP_GAIN_MUTE,
6537 AMP_OUT_MUTE);
df694daa
KY
6538 }
6539}
6540
f511b01c
TI
6541static void alc882_auto_init_input_src(struct hda_codec *codec)
6542{
6543 struct alc_spec *spec = codec->spec;
6544 const struct hda_input_mux *imux = spec->input_mux;
6545 int c;
6546
6547 for (c = 0; c < spec->num_adc_nids; c++) {
6548 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6549 hda_nid_t nid = spec->capsrc_nids[c];
6550 int conns, mute, idx, item;
6551
6552 conns = snd_hda_get_connections(codec, nid, conn_list,
6553 ARRAY_SIZE(conn_list));
6554 if (conns < 0)
6555 continue;
6556 for (idx = 0; idx < conns; idx++) {
6557 /* if the current connection is the selected one,
6558 * unmute it as default - otherwise mute it
6559 */
6560 mute = AMP_IN_MUTE(idx);
6561 for (item = 0; item < imux->num_items; item++) {
6562 if (imux->items[item].index == idx) {
6563 if (spec->cur_mux[c] == item)
6564 mute = AMP_IN_UNMUTE(idx);
6565 break;
6566 }
6567 }
6568 snd_hda_codec_write(codec, nid, 0,
6569 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6570 }
6571 }
6572}
6573
776e184e
TI
6574/* add mic boosts if needed */
6575static int alc_auto_add_mic_boost(struct hda_codec *codec)
6576{
6577 struct alc_spec *spec = codec->spec;
6578 int err;
6579 hda_nid_t nid;
6580
6581 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6582 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6583 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6584 "Mic Boost",
6585 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6586 if (err < 0)
6587 return err;
6588 }
6589 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6590 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6591 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6592 "Front Mic Boost",
6593 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6594 if (err < 0)
6595 return err;
6596 }
6597 return 0;
6598}
6599
df694daa
KY
6600/* almost identical with ALC880 parser... */
6601static int alc882_parse_auto_config(struct hda_codec *codec)
6602{
6603 struct alc_spec *spec = codec->spec;
6604 int err = alc880_parse_auto_config(codec);
6605
6606 if (err < 0)
6607 return err;
776e184e
TI
6608 else if (!err)
6609 return 0; /* no config found */
6610
6611 err = alc_auto_add_mic_boost(codec);
6612 if (err < 0)
6613 return err;
6614
6615 /* hack - override the init verbs */
6616 spec->init_verbs[0] = alc882_auto_init_verbs;
6617
6618 return 1; /* config found */
df694daa
KY
6619}
6620
ae6b813a
TI
6621/* additional initialization for auto-configuration model */
6622static void alc882_auto_init(struct hda_codec *codec)
df694daa 6623{
f6c7e546 6624 struct alc_spec *spec = codec->spec;
df694daa
KY
6625 alc882_auto_init_multi_out(codec);
6626 alc882_auto_init_hp_out(codec);
6627 alc882_auto_init_analog_input(codec);
f511b01c 6628 alc882_auto_init_input_src(codec);
f6c7e546
TI
6629 if (spec->unsol_event)
6630 alc_sku_automute(codec);
df694daa
KY
6631}
6632
7943a8ab
TI
6633static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6634
df694daa
KY
6635static int patch_alc882(struct hda_codec *codec)
6636{
6637 struct alc_spec *spec;
6638 int err, board_config;
6639
6640 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6641 if (spec == NULL)
6642 return -ENOMEM;
6643
6644 codec->spec = spec;
6645
f5fcc13c
TI
6646 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6647 alc882_models,
6648 alc882_cfg_tbl);
df694daa
KY
6649
6650 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6651 /* Pick up systems that don't supply PCI SSID */
6652 switch (codec->subsystem_id) {
6653 case 0x106b0c00: /* Mac Pro */
6654 board_config = ALC885_MACPRO;
6655 break;
c54728d8
NF
6656 case 0x106b1000: /* iMac 24 */
6657 board_config = ALC885_IMAC24;
6658 break;
c7e0757a 6659 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
87350ad0 6660 case 0x106b2c00: /* Macbook Pro rev3 */
c7e0757a 6661 case 0x106b3600: /* Macbook 3.1 */
87350ad0
TI
6662 board_config = ALC885_MBP3;
6663 break;
081d17c4 6664 default:
7943a8ab
TI
6665 /* ALC889A is handled better as ALC888-compatible */
6666 if (codec->revision_id == 0x100103) {
6667 alc_free(codec);
6668 return patch_alc883(codec);
6669 }
081d17c4
TD
6670 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6671 "trying auto-probe from BIOS...\n");
6672 board_config = ALC882_AUTO;
6673 }
df694daa
KY
6674 }
6675
f95474ec
TI
6676 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6677
df694daa
KY
6678 if (board_config == ALC882_AUTO) {
6679 /* automatic parse from the BIOS config */
6680 err = alc882_parse_auto_config(codec);
6681 if (err < 0) {
6682 alc_free(codec);
6683 return err;
f12ab1e0 6684 } else if (!err) {
9c7f852e
TI
6685 printk(KERN_INFO
6686 "hda_codec: Cannot set up configuration "
6687 "from BIOS. Using base mode...\n");
df694daa
KY
6688 board_config = ALC882_3ST_DIG;
6689 }
6690 }
6691
6692 if (board_config != ALC882_AUTO)
6693 setup_preset(spec, &alc882_presets[board_config]);
1da177e4 6694
2f893286
KY
6695 if (codec->vendor_id == 0x10ec0885) {
6696 spec->stream_name_analog = "ALC885 Analog";
6697 spec->stream_name_digital = "ALC885 Digital";
6698 } else {
6699 spec->stream_name_analog = "ALC882 Analog";
6700 spec->stream_name_digital = "ALC882 Digital";
6701 }
6702
df694daa
KY
6703 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6704 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6705 /* FIXME: setup DAC5 */
6706 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6707 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6708
df694daa
KY
6709 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6710 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6711
f12ab1e0 6712 if (!spec->adc_nids && spec->input_mux) {
df694daa 6713 /* check whether NID 0x07 is valid */
4a471b7d 6714 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6715 /* get type */
6716 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6717 if (wcap != AC_WID_AUD_IN) {
6718 spec->adc_nids = alc882_adc_nids_alt;
6719 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6720 spec->capsrc_nids = alc882_capsrc_nids_alt;
f12ab1e0
TI
6721 spec->mixers[spec->num_mixers] =
6722 alc882_capture_alt_mixer;
df694daa
KY
6723 spec->num_mixers++;
6724 } else {
6725 spec->adc_nids = alc882_adc_nids;
6726 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6727 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
6728 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6729 spec->num_mixers++;
6730 }
6731 }
1da177e4 6732
2134ea4f
TI
6733 spec->vmaster_nid = 0x0c;
6734
1da177e4 6735 codec->patch_ops = alc_patch_ops;
df694daa 6736 if (board_config == ALC882_AUTO)
ae6b813a 6737 spec->init_hook = alc882_auto_init;
cb53c626
TI
6738#ifdef CONFIG_SND_HDA_POWER_SAVE
6739 if (!spec->loopback.amplist)
6740 spec->loopback.amplist = alc882_loopbacks;
6741#endif
df694daa
KY
6742
6743 return 0;
6744}
6745
6746/*
9c7f852e
TI
6747 * ALC883 support
6748 *
6749 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6750 * configuration. Each pin widget can choose any input DACs and a mixer.
6751 * Each ADC is connected from a mixer of all inputs. This makes possible
6752 * 6-channel independent captures.
6753 *
6754 * In addition, an independent DAC for the multi-playback (not used in this
6755 * driver yet).
df694daa 6756 */
9c7f852e
TI
6757#define ALC883_DIGOUT_NID 0x06
6758#define ALC883_DIGIN_NID 0x0a
df694daa 6759
9c7f852e
TI
6760static hda_nid_t alc883_dac_nids[4] = {
6761 /* front, rear, clfe, rear_surr */
f32a19e3 6762 0x02, 0x03, 0x04, 0x05
9c7f852e 6763};
df694daa 6764
9c7f852e
TI
6765static hda_nid_t alc883_adc_nids[2] = {
6766 /* ADC1-2 */
6767 0x08, 0x09,
6768};
f12ab1e0 6769
e1406348
TI
6770static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6771
9c7f852e
TI
6772/* input MUX */
6773/* FIXME: should be a matrix-type input source selection */
df694daa 6774
9c7f852e
TI
6775static struct hda_input_mux alc883_capture_source = {
6776 .num_items = 4,
6777 .items = {
6778 { "Mic", 0x0 },
6779 { "Front Mic", 0x1 },
6780 { "Line", 0x2 },
6781 { "CD", 0x4 },
6782 },
6783};
bc9f98a9 6784
17bba1b7
J
6785static struct hda_input_mux alc883_3stack_6ch_intel = {
6786 .num_items = 4,
6787 .items = {
6788 { "Mic", 0x1 },
6789 { "Front Mic", 0x0 },
6790 { "Line", 0x2 },
6791 { "CD", 0x4 },
6792 },
6793};
6794
bc9f98a9
KY
6795static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6796 .num_items = 2,
6797 .items = {
6798 { "Mic", 0x1 },
6799 { "Line", 0x2 },
6800 },
6801};
6802
272a527c
KY
6803static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6804 .num_items = 4,
6805 .items = {
6806 { "Mic", 0x0 },
6807 { "iMic", 0x1 },
6808 { "Line", 0x2 },
6809 { "CD", 0x4 },
6810 },
6811};
6812
fb97dc67
J
6813static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6814 .num_items = 2,
6815 .items = {
6816 { "Mic", 0x0 },
6817 { "Int Mic", 0x1 },
6818 },
6819};
6820
e2757d5e
KY
6821static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6822 .num_items = 3,
6823 .items = {
6824 { "Mic", 0x0 },
6825 { "Front Mic", 0x1 },
6826 { "Line", 0x4 },
6827 },
6828};
6829
6830static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6831 .num_items = 2,
6832 .items = {
6833 { "Mic", 0x0 },
6834 { "Line", 0x2 },
6835 },
6836};
6837
9c7f852e
TI
6838#define alc883_mux_enum_info alc_mux_enum_info
6839#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6840/* ALC883 has the ALC882-type input selection */
6841#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6842
9c7f852e
TI
6843/*
6844 * 2ch mode
6845 */
6846static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6847 { 2, NULL }
6848};
6849
6850/*
6851 * 2ch mode
6852 */
6853static struct hda_verb alc883_3ST_ch2_init[] = {
6854 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6855 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6858 { } /* end */
6859};
6860
b201131c
TD
6861/*
6862 * 4ch mode
6863 */
6864static struct hda_verb alc883_3ST_ch4_init[] = {
6865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6868 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6869 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6870 { } /* end */
6871};
6872
9c7f852e
TI
6873/*
6874 * 6ch mode
6875 */
6876static struct hda_verb alc883_3ST_ch6_init[] = {
6877 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6878 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6879 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6882 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6883 { } /* end */
6884};
6885
b201131c 6886static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6887 { 2, alc883_3ST_ch2_init },
b201131c 6888 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6889 { 6, alc883_3ST_ch6_init },
6890};
6891
17bba1b7
J
6892/*
6893 * 2ch mode
6894 */
6895static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6896 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6897 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6898 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6899 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6900 { } /* end */
6901};
6902
6903/*
6904 * 4ch mode
6905 */
6906static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6907 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6908 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6909 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6910 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6911 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6912 { } /* end */
6913};
6914
6915/*
6916 * 6ch mode
6917 */
6918static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6919 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6920 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6921 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6922 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6923 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6924 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6925 { } /* end */
6926};
6927
6928static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6929 { 2, alc883_3ST_ch2_intel_init },
6930 { 4, alc883_3ST_ch4_intel_init },
6931 { 6, alc883_3ST_ch6_intel_init },
6932};
6933
9c7f852e
TI
6934/*
6935 * 6ch mode
6936 */
6937static struct hda_verb alc883_sixstack_ch6_init[] = {
6938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6942 { } /* end */
6943};
6944
6945/*
6946 * 8ch mode
6947 */
6948static struct hda_verb alc883_sixstack_ch8_init[] = {
6949 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6950 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6951 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6952 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6953 { } /* end */
6954};
6955
6956static struct hda_channel_mode alc883_sixstack_modes[2] = {
6957 { 6, alc883_sixstack_ch6_init },
6958 { 8, alc883_sixstack_ch8_init },
6959};
6960
b373bdeb
AN
6961static struct hda_verb alc883_medion_eapd_verbs[] = {
6962 /* eanable EAPD on medion laptop */
6963 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6964 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6965 { }
6966};
6967
9c7f852e
TI
6968/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6969 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6970 */
6971
6972static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6974 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6976 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6977 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6978 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6979 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6980 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6981 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6984 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6985 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6986 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6987 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6989 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6992 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6993 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6994 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6995 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6996 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6997 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6998 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6999 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7000 {
7001 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7002 /* .name = "Capture Source", */
7003 .name = "Input Source",
7004 .count = 2,
7005 .info = alc883_mux_enum_info,
7006 .get = alc883_mux_enum_get,
7007 .put = alc883_mux_enum_put,
7008 },
df694daa 7009 { } /* end */
834be88d
TI
7010};
7011
a8848bd6
AS
7012static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7013 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7014 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7015 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7016 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7017 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7018 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7021 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7023 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7024 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7025 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7026 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7027 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7028 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7029 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7030 {
7031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7032 /* .name = "Capture Source", */
7033 .name = "Input Source",
7034 .count = 2,
7035 .info = alc883_mux_enum_info,
7036 .get = alc883_mux_enum_get,
7037 .put = alc883_mux_enum_put,
7038 },
7039 { } /* end */
7040};
7041
0c4cc443 7042static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7044 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7045 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7046 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7048 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7050 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7051 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7052 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7053 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7054 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7055 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7056 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7057 {
7058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7059 /* .name = "Capture Source", */
7060 .name = "Input Source",
7061 .count = 2,
7062 .info = alc883_mux_enum_info,
7063 .get = alc883_mux_enum_get,
7064 .put = alc883_mux_enum_put,
7065 },
7066 { } /* end */
7067};
7068
fb97dc67
J
7069static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7071 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7072 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7073 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7075 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7077 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7078 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7079 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7082 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7083 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7084 {
7085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7086 /* .name = "Capture Source", */
7087 .name = "Input Source",
7088 .count = 2,
7089 .info = alc883_mux_enum_info,
7090 .get = alc883_mux_enum_get,
7091 .put = alc883_mux_enum_put,
7092 },
7093 { } /* end */
7094};
7095
9c7f852e
TI
7096static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7098 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7100 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7101 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7102 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7103 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7105 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7107 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7108 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7109 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7110 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7111 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7112 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7113 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7114 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7115 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7116 {
7117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7118 /* .name = "Capture Source", */
7119 .name = "Input Source",
7120 .count = 2,
7121 .info = alc883_mux_enum_info,
7122 .get = alc883_mux_enum_get,
7123 .put = alc883_mux_enum_put,
7124 },
7125 { } /* end */
7126};
df694daa 7127
9c7f852e
TI
7128static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7129 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7130 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7131 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7132 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7133 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7134 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7135 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7136 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7143 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7146 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7148 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7149 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7150 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7151 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9c7f852e
TI
7152 {
7153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7154 /* .name = "Capture Source", */
7155 .name = "Input Source",
e2757d5e 7156 .count = 1,
9c7f852e
TI
7157 .info = alc883_mux_enum_info,
7158 .get = alc883_mux_enum_get,
7159 .put = alc883_mux_enum_put,
7160 },
7161 { } /* end */
7162};
7163
17bba1b7
J
7164static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7165 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7166 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7167 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7168 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7169 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7170 HDA_OUTPUT),
7171 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7172 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7173 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7180 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7182 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7183 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7184 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7185 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7186 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7187 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7188 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7189 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7190 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7191 {
7192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7193 /* .name = "Capture Source", */
7194 .name = "Input Source",
7195 .count = 2,
7196 .info = alc883_mux_enum_info,
7197 .get = alc883_mux_enum_get,
7198 .put = alc883_mux_enum_put,
7199 },
7200 { } /* end */
7201};
7202
d1d985f0 7203static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7210 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7211 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7218 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7220 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7221 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
7222 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7223 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7224 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7225 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7226 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7227
7228 {
7229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7230 /* .name = "Capture Source", */
7231 .name = "Input Source",
7232 .count = 1,
7233 .info = alc883_mux_enum_info,
7234 .get = alc883_mux_enum_get,
7235 .put = alc883_mux_enum_put,
7236 },
7237 { } /* end */
7238};
7239
ccc656ce
KY
7240static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7241 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7243 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7244 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7246 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7247 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7248 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7249 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7250 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7251 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7252 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7253 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7255 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
7256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7257 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7258 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7259 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7260 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7261 {
7262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7263 /* .name = "Capture Source", */
7264 .name = "Input Source",
7265 .count = 2,
7266 .info = alc883_mux_enum_info,
7267 .get = alc883_mux_enum_get,
7268 .put = alc883_mux_enum_put,
7269 },
7270 { } /* end */
f12ab1e0 7271};
ccc656ce
KY
7272
7273static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7274 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7276 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7277 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7278 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7280 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7282 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7284 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
7285 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7286 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7287 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7288 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7289 {
7290 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7291 /* .name = "Capture Source", */
7292 .name = "Input Source",
7293 .count = 2,
7294 .info = alc883_mux_enum_info,
7295 .get = alc883_mux_enum_get,
7296 .put = alc883_mux_enum_put,
7297 },
7298 { } /* end */
f12ab1e0 7299};
ccc656ce 7300
bc9f98a9
KY
7301static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7303 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7304 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7305 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7307 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7308 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7309 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7312 {
7313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7314 /* .name = "Capture Source", */
7315 .name = "Input Source",
7316 .count = 1,
7317 .info = alc883_mux_enum_info,
7318 .get = alc883_mux_enum_get,
7319 .put = alc883_mux_enum_put,
7320 },
7321 { } /* end */
f12ab1e0 7322};
bc9f98a9 7323
272a527c
KY
7324static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7325 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7326 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7332 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7333 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7334 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7335 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7336 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7337 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7338 {
7339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7340 /* .name = "Capture Source", */
7341 .name = "Input Source",
7342 .count = 2,
7343 .info = alc883_mux_enum_info,
7344 .get = alc883_mux_enum_get,
7345 .put = alc883_mux_enum_put,
7346 },
7347 { } /* end */
7348};
7349
7350static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7351 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7353 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7354 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7355 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7360 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7361 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7362 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7363 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7364 {
7365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7366 /* .name = "Capture Source", */
7367 .name = "Input Source",
7368 .count = 2,
7369 .info = alc883_mux_enum_info,
7370 .get = alc883_mux_enum_get,
7371 .put = alc883_mux_enum_put,
7372 },
7373 { } /* end */
ea1fb29a 7374};
272a527c 7375
2880a867 7376static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7378 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7379 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7385 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7386 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7387 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7388 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7389 {
7390 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7391 /* .name = "Capture Source", */
7392 .name = "Input Source",
7393 .count = 2,
7394 .info = alc883_mux_enum_info,
7395 .get = alc883_mux_enum_get,
7396 .put = alc883_mux_enum_put,
7397 },
7398 { } /* end */
d1a991a6 7399};
2880a867 7400
e2757d5e
KY
7401static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7402 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7403 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7404 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7405 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7406 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7407 0x0d, 1, 0x0, HDA_OUTPUT),
7408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7411 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7412 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7414 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7421 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7422 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7423 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7426 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7427 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7428 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7429 {
7430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7431 /* .name = "Capture Source", */
7432 .name = "Input Source",
7433 .count = 2,
7434 .info = alc883_mux_enum_info,
7435 .get = alc883_mux_enum_get,
7436 .put = alc883_mux_enum_put,
7437 },
7438 { } /* end */
7439};
7440
7441static struct hda_bind_ctls alc883_bind_cap_vol = {
7442 .ops = &snd_hda_bind_vol,
7443 .values = {
7444 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7445 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7446 0
7447 },
7448};
7449
7450static struct hda_bind_ctls alc883_bind_cap_switch = {
7451 .ops = &snd_hda_bind_sw,
7452 .values = {
7453 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7454 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7455 0
7456 },
7457};
7458
7459static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7460 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7461 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7463 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7464 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7466 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7468 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7469 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7470 {
7471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7472 /* .name = "Capture Source", */
7473 .name = "Input Source",
7474 .count = 1,
7475 .info = alc883_mux_enum_info,
7476 .get = alc883_mux_enum_get,
7477 .put = alc883_mux_enum_put,
7478 },
7479 { } /* end */
7480};
7481
9c7f852e
TI
7482static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7483 {
7484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7485 .name = "Channel Mode",
7486 .info = alc_ch_mode_info,
7487 .get = alc_ch_mode_get,
7488 .put = alc_ch_mode_put,
7489 },
7490 { } /* end */
7491};
7492
7493static struct hda_verb alc883_init_verbs[] = {
7494 /* ADC1: mute amp left and right */
e2757d5e 7495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
df694daa 7496 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7497 /* ADC2: mute amp left and right */
7498 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7499 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7500 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7504 /* Rear mixer */
7505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7508 /* CLFE mixer */
7509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7512 /* Side mixer */
7513 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7516
cb53c626
TI
7517 /* mute analog input loopbacks */
7518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7523
9c7f852e
TI
7524 /* Front Pin: output 0 (0x0c) */
7525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7527 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7528 /* Rear Pin: output 1 (0x0d) */
7529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7531 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7532 /* CLFE Pin: output 2 (0x0e) */
7533 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7534 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7535 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7536 /* Side Pin: output 3 (0x0f) */
7537 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7538 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7539 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7540 /* Mic (rear) pin: input vref at 80% */
7541 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7542 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7543 /* Front Mic pin: input vref at 80% */
7544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7545 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7546 /* Line In pin: input */
7547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7549 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7550 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7551 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7552 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7553 /* CD pin widget for input */
7554 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7555
7556 /* FIXME: use matrix-type input source selection */
7557 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7558 /* Input mixer2 */
7559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7563 /* Input mixer3 */
7564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7568 { }
7569};
7570
a8848bd6
AS
7571/* toggle speaker-output according to the hp-jack state */
7572static void alc883_mitac_hp_automute(struct hda_codec *codec)
7573{
7574 unsigned int present;
7575
7576 present = snd_hda_codec_read(codec, 0x15, 0,
7577 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7578 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7579 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7580 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7581 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7582}
7583
7584/* auto-toggle front mic */
7585/*
7586static void alc883_mitac_mic_automute(struct hda_codec *codec)
7587{
7588 unsigned int present;
7589 unsigned char bits;
7590
7591 present = snd_hda_codec_read(codec, 0x18, 0,
7592 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7593 bits = present ? HDA_AMP_MUTE : 0;
7594 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7595}
7596*/
7597
7598static void alc883_mitac_automute(struct hda_codec *codec)
7599{
7600 alc883_mitac_hp_automute(codec);
7601 /* alc883_mitac_mic_automute(codec); */
7602}
7603
7604static void alc883_mitac_unsol_event(struct hda_codec *codec,
7605 unsigned int res)
7606{
7607 switch (res >> 26) {
7608 case ALC880_HP_EVENT:
7609 alc883_mitac_hp_automute(codec);
7610 break;
7611 case ALC880_MIC_EVENT:
7612 /* alc883_mitac_mic_automute(codec); */
7613 break;
7614 }
7615}
7616
7617static struct hda_verb alc883_mitac_verbs[] = {
7618 /* HP */
7619 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7621 /* Subwoofer */
7622 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7623 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7624
7625 /* enable unsolicited event */
7626 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7627 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7628
7629 { } /* end */
7630};
7631
0c4cc443 7632static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
7633 /* HP */
7634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7636 /* Int speaker */
7637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7639
7640 /* enable unsolicited event */
7641 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 7642 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
7643
7644 { } /* end */
7645};
7646
fb97dc67
J
7647static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7648 /* HP */
7649 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7651 /* Subwoofer */
7652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7654
7655 /* enable unsolicited event */
7656 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7657
7658 { } /* end */
7659};
7660
ccc656ce
KY
7661static struct hda_verb alc883_tagra_verbs[] = {
7662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7664
7665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7667
ccc656ce
KY
7668 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7669 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7670 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7671
7672 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7673 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7674 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7675 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7676
7677 { } /* end */
7678};
7679
bc9f98a9
KY
7680static struct hda_verb alc883_lenovo_101e_verbs[] = {
7681 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7682 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7683 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7684 { } /* end */
7685};
7686
272a527c
KY
7687static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7688 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7690 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7692 { } /* end */
7693};
7694
7695static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7698 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7700 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7701 { } /* end */
7702};
7703
189609ae
KY
7704static struct hda_verb alc883_haier_w66_verbs[] = {
7705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7707
7708 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7709
7710 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7711 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7712 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7713 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7714 { } /* end */
7715};
7716
e2757d5e
KY
7717static struct hda_verb alc888_lenovo_sky_verbs[] = {
7718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7721 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7722 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7724 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7725 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7726 { } /* end */
7727};
7728
4723c022 7729static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 7730 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
7731 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7732 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8341de60
CM
7733 { }
7734};
7735
5795b9e6 7736static struct hda_verb alc888_6st_dell_verbs[] = {
5795b9e6
CM
7737 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7738 { }
7739};
7740
4723c022 7741static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7744 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7745 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7746 { }
7747};
7748
4723c022 7749static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7750 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7752 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7753 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7754 { }
7755};
7756
4723c022
CM
7757static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7758 { 2, alc888_3st_hp_2ch_init },
7759 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7760};
7761
272a527c
KY
7762/* toggle front-jack and RCA according to the hp-jack state */
7763static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7764{
7765 unsigned int present;
ea1fb29a 7766
272a527c
KY
7767 present = snd_hda_codec_read(codec, 0x1b, 0,
7768 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7769 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7770 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7771 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7772 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7773}
7774
7775/* toggle RCA according to the front-jack state */
7776static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7777{
7778 unsigned int present;
ea1fb29a 7779
272a527c
KY
7780 present = snd_hda_codec_read(codec, 0x14, 0,
7781 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7782 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7783 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7784}
47fd830a 7785
272a527c
KY
7786static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7787 unsigned int res)
7788{
7789 if ((res >> 26) == ALC880_HP_EVENT)
7790 alc888_lenovo_ms7195_front_automute(codec);
7791 if ((res >> 26) == ALC880_FRONT_EVENT)
7792 alc888_lenovo_ms7195_rca_automute(codec);
7793}
7794
7795static struct hda_verb alc883_medion_md2_verbs[] = {
7796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7798
7799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7800
7801 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7802 { } /* end */
7803};
7804
7805/* toggle speaker-output according to the hp-jack state */
7806static void alc883_medion_md2_automute(struct hda_codec *codec)
7807{
7808 unsigned int present;
ea1fb29a 7809
272a527c
KY
7810 present = snd_hda_codec_read(codec, 0x14, 0,
7811 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7812 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7813 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7814}
7815
7816static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7817 unsigned int res)
7818{
7819 if ((res >> 26) == ALC880_HP_EVENT)
7820 alc883_medion_md2_automute(codec);
7821}
7822
ccc656ce
KY
7823/* toggle speaker-output according to the hp-jack state */
7824static void alc883_tagra_automute(struct hda_codec *codec)
7825{
7826 unsigned int present;
f12ab1e0 7827 unsigned char bits;
ccc656ce
KY
7828
7829 present = snd_hda_codec_read(codec, 0x14, 0,
7830 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7831 bits = present ? HDA_AMP_MUTE : 0;
7832 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7833 HDA_AMP_MUTE, bits);
82beb8fd
TI
7834 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7835 present ? 1 : 3);
ccc656ce
KY
7836}
7837
7838static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7839{
7840 if ((res >> 26) == ALC880_HP_EVENT)
7841 alc883_tagra_automute(codec);
7842}
7843
368c7a95 7844/* toggle speaker-output according to the hp-jack state */
0c4cc443 7845static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
368c7a95
J
7846{
7847 unsigned int present;
7848 unsigned char bits;
7849
7850 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7851 & AC_PINSENSE_PRESENCE;
7852 bits = present ? HDA_AMP_MUTE : 0;
7853 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7854 HDA_AMP_MUTE, bits);
7855}
7856
0c4cc443
HRK
7857static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7858{
7859 unsigned int present;
7860
7861 present = snd_hda_codec_read(codec, 0x18, 0,
7862 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7863 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7864 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7865}
7866
7867static void alc883_clevo_m720_automute(struct hda_codec *codec)
7868{
7869 alc883_clevo_m720_hp_automute(codec);
7870 alc883_clevo_m720_mic_automute(codec);
7871}
7872
7873static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
7874 unsigned int res)
7875{
0c4cc443
HRK
7876 switch (res >> 26) {
7877 case ALC880_HP_EVENT:
7878 alc883_clevo_m720_hp_automute(codec);
7879 break;
7880 case ALC880_MIC_EVENT:
7881 alc883_clevo_m720_mic_automute(codec);
7882 break;
7883 }
368c7a95
J
7884}
7885
fb97dc67
J
7886/* toggle speaker-output according to the hp-jack state */
7887static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7888{
7889 unsigned int present;
7890 unsigned char bits;
7891
7892 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7893 & AC_PINSENSE_PRESENCE;
7894 bits = present ? HDA_AMP_MUTE : 0;
7895 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7896 HDA_AMP_MUTE, bits);
7897}
7898
7899static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7900 unsigned int res)
7901{
7902 if ((res >> 26) == ALC880_HP_EVENT)
7903 alc883_2ch_fujitsu_pi2515_automute(codec);
7904}
7905
189609ae
KY
7906static void alc883_haier_w66_automute(struct hda_codec *codec)
7907{
7908 unsigned int present;
7909 unsigned char bits;
7910
7911 present = snd_hda_codec_read(codec, 0x1b, 0,
7912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7913 bits = present ? 0x80 : 0;
7914 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7915 0x80, bits);
7916}
7917
7918static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7919 unsigned int res)
7920{
7921 if ((res >> 26) == ALC880_HP_EVENT)
7922 alc883_haier_w66_automute(codec);
7923}
7924
bc9f98a9
KY
7925static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7926{
7927 unsigned int present;
f12ab1e0 7928 unsigned char bits;
bc9f98a9
KY
7929
7930 present = snd_hda_codec_read(codec, 0x14, 0,
7931 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7932 bits = present ? HDA_AMP_MUTE : 0;
7933 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7934 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7935}
7936
7937static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7938{
7939 unsigned int present;
f12ab1e0 7940 unsigned char bits;
bc9f98a9
KY
7941
7942 present = snd_hda_codec_read(codec, 0x1b, 0,
7943 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7944 bits = present ? HDA_AMP_MUTE : 0;
7945 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7946 HDA_AMP_MUTE, bits);
7947 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7948 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7949}
7950
7951static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7952 unsigned int res)
7953{
7954 if ((res >> 26) == ALC880_HP_EVENT)
7955 alc883_lenovo_101e_all_automute(codec);
7956 if ((res >> 26) == ALC880_FRONT_EVENT)
7957 alc883_lenovo_101e_ispeaker_automute(codec);
7958}
7959
676a9b53
TI
7960/* toggle speaker-output according to the hp-jack state */
7961static void alc883_acer_aspire_automute(struct hda_codec *codec)
7962{
7963 unsigned int present;
ea1fb29a 7964
676a9b53
TI
7965 present = snd_hda_codec_read(codec, 0x14, 0,
7966 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7967 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7968 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7969 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7970 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7971}
7972
7973static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7974 unsigned int res)
7975{
7976 if ((res >> 26) == ALC880_HP_EVENT)
7977 alc883_acer_aspire_automute(codec);
7978}
7979
d1a991a6
KY
7980static struct hda_verb alc883_acer_eapd_verbs[] = {
7981 /* HP Pin: output 0 (0x0c) */
7982 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7983 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7985 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7987 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7988 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7989 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7990 /* eanable EAPD on medion laptop */
7991 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7992 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7993 /* enable unsolicited event */
7994 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7995 { }
7996};
7997
5795b9e6
CM
7998static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7999{
8000 unsigned int present;
ea1fb29a 8001
5795b9e6
CM
8002 present = snd_hda_codec_read(codec, 0x1b, 0,
8003 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8004 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8005 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8006 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8007 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8008 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8009 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8010 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8011 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8012}
8013
8014static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8015 unsigned int res)
8016{
8017 switch (res >> 26) {
8018 case ALC880_HP_EVENT:
8019 printk("hp_event\n");
8020 alc888_6st_dell_front_automute(codec);
8021 break;
8022 }
8023}
8024
e2757d5e
KY
8025static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8026{
8027 unsigned int mute;
8028 unsigned int present;
8029
8030 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8031 present = snd_hda_codec_read(codec, 0x1b, 0,
8032 AC_VERB_GET_PIN_SENSE, 0);
8033 present = (present & 0x80000000) != 0;
8034 if (present) {
8035 /* mute internal speaker */
8036 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8037 HDA_AMP_MUTE, HDA_AMP_MUTE);
8038 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8039 HDA_AMP_MUTE, HDA_AMP_MUTE);
8040 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8041 HDA_AMP_MUTE, HDA_AMP_MUTE);
8042 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8043 HDA_AMP_MUTE, HDA_AMP_MUTE);
8044 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8045 HDA_AMP_MUTE, HDA_AMP_MUTE);
8046 } else {
8047 /* unmute internal speaker if necessary */
8048 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8049 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8050 HDA_AMP_MUTE, mute);
8051 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8052 HDA_AMP_MUTE, mute);
8053 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8054 HDA_AMP_MUTE, mute);
8055 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8056 HDA_AMP_MUTE, mute);
8057 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8058 HDA_AMP_MUTE, mute);
8059 }
8060}
8061
8062static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8063 unsigned int res)
8064{
8065 if ((res >> 26) == ALC880_HP_EVENT)
8066 alc888_lenovo_sky_front_automute(codec);
8067}
8068
9c7f852e
TI
8069/*
8070 * generic initialization of ADC, input mixers and output mixers
8071 */
8072static struct hda_verb alc883_auto_init_verbs[] = {
8073 /*
8074 * Unmute ADC0-2 and set the default input to mic-in
8075 */
8076 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8077 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8078 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8080
cb53c626 8081 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8082 * mixer widget
f12ab1e0
TI
8083 * Note: PASD motherboards uses the Line In 2 as the input for
8084 * front panel mic (mic 2)
9c7f852e
TI
8085 */
8086 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8092
8093 /*
8094 * Set up output mixers (0x0c - 0x0f)
8095 */
8096 /* set vol=0 to output mixers */
8097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8098 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8099 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8100 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 /* set up input amps for analog loopback */
8102 /* Amp Indices: DAC = 0, mixer = 1 */
8103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8109 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8110 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8111 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8112 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8113
8114 /* FIXME: use matrix-type input source selection */
8115 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8116 /* Input mixer1 */
8117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8120 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
8121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8122 /* Input mixer2 */
8123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8126 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 8127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
8128
8129 { }
8130};
8131
8132/* capture mixer elements */
8133static struct snd_kcontrol_new alc883_capture_mixer[] = {
8134 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8135 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8136 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8137 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8138 {
8139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8140 /* The multiple "Capture Source" controls confuse alsamixer
8141 * So call somewhat different..
9c7f852e
TI
8142 */
8143 /* .name = "Capture Source", */
8144 .name = "Input Source",
8145 .count = 2,
8146 .info = alc882_mux_enum_info,
8147 .get = alc882_mux_enum_get,
8148 .put = alc882_mux_enum_put,
8149 },
8150 { } /* end */
8151};
8152
e2757d5e
KY
8153static struct hda_verb alc888_asus_m90v_verbs[] = {
8154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8157 /* enable unsolicited event */
8158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8160 { } /* end */
8161};
8162
8163static void alc883_nb_mic_automute(struct hda_codec *codec)
8164{
8165 unsigned int present;
8166
8167 present = snd_hda_codec_read(codec, 0x18, 0,
8168 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8169 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8170 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8171 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8172 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8173}
8174
8175static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8176{
8177 unsigned int present;
8178 unsigned char bits;
8179
8180 present = snd_hda_codec_read(codec, 0x1b, 0,
8181 AC_VERB_GET_PIN_SENSE, 0)
8182 & AC_PINSENSE_PRESENCE;
8183 bits = present ? 0 : PIN_OUT;
8184 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8185 bits);
8186 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8187 bits);
8188 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8189 bits);
8190}
8191
8192static void alc883_mode2_unsol_event(struct hda_codec *codec,
8193 unsigned int res)
8194{
8195 switch (res >> 26) {
8196 case ALC880_HP_EVENT:
8197 alc883_M90V_speaker_automute(codec);
8198 break;
8199 case ALC880_MIC_EVENT:
8200 alc883_nb_mic_automute(codec);
8201 break;
8202 }
8203}
8204
8205static void alc883_mode2_inithook(struct hda_codec *codec)
8206{
8207 alc883_M90V_speaker_automute(codec);
8208 alc883_nb_mic_automute(codec);
8209}
8210
8211static struct hda_verb alc888_asus_eee1601_verbs[] = {
8212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8213 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8217 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8218 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8219 /* enable unsolicited event */
8220 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8221 { } /* end */
8222};
8223
8224static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8225{
8226 unsigned int present;
8227 unsigned char bits;
8228
8229 present = snd_hda_codec_read(codec, 0x14, 0,
8230 AC_VERB_GET_PIN_SENSE, 0)
8231 & AC_PINSENSE_PRESENCE;
8232 bits = present ? 0 : PIN_OUT;
8233 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8234 bits);
8235}
8236
8237static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8238 unsigned int res)
8239{
8240 switch (res >> 26) {
8241 case ALC880_HP_EVENT:
8242 alc883_eee1601_speaker_automute(codec);
8243 break;
8244 }
8245}
8246
8247static void alc883_eee1601_inithook(struct hda_codec *codec)
8248{
8249 alc883_eee1601_speaker_automute(codec);
8250}
8251
cb53c626
TI
8252#ifdef CONFIG_SND_HDA_POWER_SAVE
8253#define alc883_loopbacks alc880_loopbacks
8254#endif
8255
9c7f852e
TI
8256/* pcm configuration: identiacal with ALC880 */
8257#define alc883_pcm_analog_playback alc880_pcm_analog_playback
8258#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 8259#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
8260#define alc883_pcm_digital_playback alc880_pcm_digital_playback
8261#define alc883_pcm_digital_capture alc880_pcm_digital_capture
8262
8263/*
8264 * configuration and preset
8265 */
f5fcc13c
TI
8266static const char *alc883_models[ALC883_MODEL_LAST] = {
8267 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8268 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8269 [ALC883_3ST_6ch] = "3stack-6ch",
8270 [ALC883_6ST_DIG] = "6stack-dig",
8271 [ALC883_TARGA_DIG] = "targa-dig",
8272 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 8273 [ALC883_ACER] = "acer",
2880a867 8274 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 8275 [ALC883_MEDION] = "medion",
272a527c 8276 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8277 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8278 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8279 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8280 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8281 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8282 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8283 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8284 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8285 [ALC883_MITAC] = "mitac",
0c4cc443 8286 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8287 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
17bba1b7 8288 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
f5fcc13c
TI
8289 [ALC883_AUTO] = "auto",
8290};
8291
8292static struct snd_pci_quirk alc883_cfg_tbl[] = {
8293 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8294 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8295 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8296 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8297 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
ac3e3741 8298 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 8299 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 8300 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8301 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8302 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8303 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
ac3e3741 8304 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
e2757d5e
KY
8305 SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8306 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
97ec710c 8307 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 8308 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
8309 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8310 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8311 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8312 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 8313 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 8314 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8315 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8316 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 8317 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 8318 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8319 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8320 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8321 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8322 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8323 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8324 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8325 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8326 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8327 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8328 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
8329 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8330 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8331 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
86d34b7e 8332 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8333 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8334 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 8335 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8336 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8337 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8338 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
ac3e3741 8339 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8340 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 8341 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
fb97dc67 8342 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
272a527c 8343 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8344 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8345 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8346 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8347 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8348 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 8349 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8350 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
17bba1b7
J
8351 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8352 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
ac3e3741 8353 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
8354 {}
8355};
8356
8357static struct alc_config_preset alc883_presets[] = {
8358 [ALC883_3ST_2ch_DIG] = {
8359 .mixers = { alc883_3ST_2ch_mixer },
8360 .init_verbs = { alc883_init_verbs },
8361 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8362 .dac_nids = alc883_dac_nids,
8363 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8364 .dig_in_nid = ALC883_DIGIN_NID,
8365 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8366 .channel_mode = alc883_3ST_2ch_modes,
8367 .input_mux = &alc883_capture_source,
8368 },
8369 [ALC883_3ST_6ch_DIG] = {
8370 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8371 .init_verbs = { alc883_init_verbs },
8372 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8373 .dac_nids = alc883_dac_nids,
8374 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8375 .dig_in_nid = ALC883_DIGIN_NID,
8376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8377 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8378 .need_dac_fix = 1,
9c7f852e 8379 .input_mux = &alc883_capture_source,
f12ab1e0 8380 },
9c7f852e
TI
8381 [ALC883_3ST_6ch] = {
8382 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8383 .init_verbs = { alc883_init_verbs },
8384 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8385 .dac_nids = alc883_dac_nids,
9c7f852e
TI
8386 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8387 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8388 .need_dac_fix = 1,
9c7f852e 8389 .input_mux = &alc883_capture_source,
f12ab1e0 8390 },
17bba1b7
J
8391 [ALC883_3ST_6ch_INTEL] = {
8392 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8393 .init_verbs = { alc883_init_verbs },
8394 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8395 .dac_nids = alc883_dac_nids,
8396 .dig_out_nid = ALC883_DIGOUT_NID,
8397 .dig_in_nid = ALC883_DIGIN_NID,
8398 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8399 .channel_mode = alc883_3ST_6ch_intel_modes,
8400 .need_dac_fix = 1,
8401 .input_mux = &alc883_3stack_6ch_intel,
8402 },
9c7f852e
TI
8403 [ALC883_6ST_DIG] = {
8404 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8405 .init_verbs = { alc883_init_verbs },
8406 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8407 .dac_nids = alc883_dac_nids,
8408 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8409 .dig_in_nid = ALC883_DIGIN_NID,
8410 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8411 .channel_mode = alc883_sixstack_modes,
8412 .input_mux = &alc883_capture_source,
8413 },
ccc656ce
KY
8414 [ALC883_TARGA_DIG] = {
8415 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8416 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8417 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8418 .dac_nids = alc883_dac_nids,
8419 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8420 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8421 .channel_mode = alc883_3ST_6ch_modes,
8422 .need_dac_fix = 1,
8423 .input_mux = &alc883_capture_source,
8424 .unsol_event = alc883_tagra_unsol_event,
8425 .init_hook = alc883_tagra_automute,
8426 },
8427 [ALC883_TARGA_2ch_DIG] = {
8428 .mixers = { alc883_tagra_2ch_mixer},
8429 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8431 .dac_nids = alc883_dac_nids,
8432 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8433 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8434 .channel_mode = alc883_3ST_2ch_modes,
8435 .input_mux = &alc883_capture_source,
8436 .unsol_event = alc883_tagra_unsol_event,
8437 .init_hook = alc883_tagra_automute,
8438 },
bab282b9 8439 [ALC883_ACER] = {
676a9b53 8440 .mixers = { alc883_base_mixer },
bab282b9
VA
8441 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8442 * and the headphone jack. Turn this on and rely on the
8443 * standard mute methods whenever the user wants to turn
8444 * these outputs off.
8445 */
8446 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8447 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8448 .dac_nids = alc883_dac_nids,
bab282b9
VA
8449 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8450 .channel_mode = alc883_3ST_2ch_modes,
8451 .input_mux = &alc883_capture_source,
8452 },
2880a867 8453 [ALC883_ACER_ASPIRE] = {
676a9b53 8454 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 8455 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
8456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8457 .dac_nids = alc883_dac_nids,
8458 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
8459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8460 .channel_mode = alc883_3ST_2ch_modes,
8461 .input_mux = &alc883_capture_source,
676a9b53
TI
8462 .unsol_event = alc883_acer_aspire_unsol_event,
8463 .init_hook = alc883_acer_aspire_automute,
d1a991a6 8464 },
c07584c8
TD
8465 [ALC883_MEDION] = {
8466 .mixers = { alc883_fivestack_mixer,
8467 alc883_chmode_mixer },
8468 .init_verbs = { alc883_init_verbs,
b373bdeb 8469 alc883_medion_eapd_verbs },
c07584c8
TD
8470 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8471 .dac_nids = alc883_dac_nids,
c07584c8
TD
8472 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8473 .channel_mode = alc883_sixstack_modes,
8474 .input_mux = &alc883_capture_source,
b373bdeb 8475 },
272a527c
KY
8476 [ALC883_MEDION_MD2] = {
8477 .mixers = { alc883_medion_md2_mixer},
8478 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8479 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8480 .dac_nids = alc883_dac_nids,
8481 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8483 .channel_mode = alc883_3ST_2ch_modes,
8484 .input_mux = &alc883_capture_source,
8485 .unsol_event = alc883_medion_md2_unsol_event,
8486 .init_hook = alc883_medion_md2_automute,
ea1fb29a 8487 },
b373bdeb 8488 [ALC883_LAPTOP_EAPD] = {
676a9b53 8489 .mixers = { alc883_base_mixer },
b373bdeb
AN
8490 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8491 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8492 .dac_nids = alc883_dac_nids,
b373bdeb
AN
8493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8494 .channel_mode = alc883_3ST_2ch_modes,
8495 .input_mux = &alc883_capture_source,
8496 },
0c4cc443
HRK
8497 [ALC883_CLEVO_M720] = {
8498 .mixers = { alc883_clevo_m720_mixer },
8499 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
8500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8501 .dac_nids = alc883_dac_nids,
8502 .dig_out_nid = ALC883_DIGOUT_NID,
8503 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8504 .channel_mode = alc883_3ST_2ch_modes,
8505 .input_mux = &alc883_capture_source,
0c4cc443
HRK
8506 .unsol_event = alc883_clevo_m720_unsol_event,
8507 .init_hook = alc883_clevo_m720_automute,
368c7a95 8508 },
bc9f98a9
KY
8509 [ALC883_LENOVO_101E_2ch] = {
8510 .mixers = { alc883_lenovo_101e_2ch_mixer},
8511 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8512 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8513 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
8514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8515 .channel_mode = alc883_3ST_2ch_modes,
8516 .input_mux = &alc883_lenovo_101e_capture_source,
8517 .unsol_event = alc883_lenovo_101e_unsol_event,
8518 .init_hook = alc883_lenovo_101e_all_automute,
8519 },
272a527c
KY
8520 [ALC883_LENOVO_NB0763] = {
8521 .mixers = { alc883_lenovo_nb0763_mixer },
8522 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8523 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8524 .dac_nids = alc883_dac_nids,
272a527c
KY
8525 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8526 .channel_mode = alc883_3ST_2ch_modes,
8527 .need_dac_fix = 1,
8528 .input_mux = &alc883_lenovo_nb0763_capture_source,
8529 .unsol_event = alc883_medion_md2_unsol_event,
8530 .init_hook = alc883_medion_md2_automute,
8531 },
8532 [ALC888_LENOVO_MS7195_DIG] = {
8533 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8534 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8535 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8536 .dac_nids = alc883_dac_nids,
8537 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8538 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8539 .channel_mode = alc883_3ST_6ch_modes,
8540 .need_dac_fix = 1,
8541 .input_mux = &alc883_capture_source,
8542 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8543 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
8544 },
8545 [ALC883_HAIER_W66] = {
8546 .mixers = { alc883_tagra_2ch_mixer},
8547 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8549 .dac_nids = alc883_dac_nids,
8550 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
8551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8552 .channel_mode = alc883_3ST_2ch_modes,
8553 .input_mux = &alc883_capture_source,
8554 .unsol_event = alc883_haier_w66_unsol_event,
8555 .init_hook = alc883_haier_w66_automute,
eea6419e 8556 },
4723c022 8557 [ALC888_3ST_HP] = {
eea6419e 8558 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 8559 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
8560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8561 .dac_nids = alc883_dac_nids,
4723c022
CM
8562 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8563 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
8564 .need_dac_fix = 1,
8565 .input_mux = &alc883_capture_source,
8566 },
5795b9e6 8567 [ALC888_6ST_DELL] = {
f24dbdc6 8568 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
8569 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8571 .dac_nids = alc883_dac_nids,
8572 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
8573 .dig_in_nid = ALC883_DIGIN_NID,
8574 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8575 .channel_mode = alc883_sixstack_modes,
8576 .input_mux = &alc883_capture_source,
8577 .unsol_event = alc888_6st_dell_unsol_event,
8578 .init_hook = alc888_6st_dell_front_automute,
8579 },
a8848bd6
AS
8580 [ALC883_MITAC] = {
8581 .mixers = { alc883_mitac_mixer },
8582 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8583 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8584 .dac_nids = alc883_dac_nids,
a8848bd6
AS
8585 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8586 .channel_mode = alc883_3ST_2ch_modes,
8587 .input_mux = &alc883_capture_source,
8588 .unsol_event = alc883_mitac_unsol_event,
8589 .init_hook = alc883_mitac_automute,
8590 },
fb97dc67
J
8591 [ALC883_FUJITSU_PI2515] = {
8592 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8593 .init_verbs = { alc883_init_verbs,
8594 alc883_2ch_fujitsu_pi2515_verbs},
8595 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8596 .dac_nids = alc883_dac_nids,
8597 .dig_out_nid = ALC883_DIGOUT_NID,
8598 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8599 .channel_mode = alc883_3ST_2ch_modes,
8600 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8601 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8602 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8603 },
e2757d5e
KY
8604 [ALC888_LENOVO_SKY] = {
8605 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8606 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8607 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8608 .dac_nids = alc883_dac_nids,
8609 .dig_out_nid = ALC883_DIGOUT_NID,
8610 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8611 .adc_nids = alc883_adc_nids,
8612 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8613 .channel_mode = alc883_sixstack_modes,
8614 .need_dac_fix = 1,
8615 .input_mux = &alc883_lenovo_sky_capture_source,
8616 .unsol_event = alc883_lenovo_sky_unsol_event,
8617 .init_hook = alc888_lenovo_sky_front_automute,
8618 },
8619 [ALC888_ASUS_M90V] = {
8620 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8621 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8622 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8623 .dac_nids = alc883_dac_nids,
8624 .dig_out_nid = ALC883_DIGOUT_NID,
8625 .dig_in_nid = ALC883_DIGIN_NID,
8626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8627 .channel_mode = alc883_3ST_6ch_modes,
8628 .need_dac_fix = 1,
8629 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8630 .unsol_event = alc883_mode2_unsol_event,
8631 .init_hook = alc883_mode2_inithook,
8632 },
8633 [ALC888_ASUS_EEE1601] = {
8634 .mixers = { alc883_asus_eee1601_mixer },
8635 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8636 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8637 .dac_nids = alc883_dac_nids,
8638 .dig_out_nid = ALC883_DIGOUT_NID,
8639 .dig_in_nid = ALC883_DIGIN_NID,
8640 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8641 .channel_mode = alc883_3ST_2ch_modes,
8642 .need_dac_fix = 1,
8643 .input_mux = &alc883_asus_eee1601_capture_source,
8644 .unsol_event = alc883_eee1601_unsol_event,
8645 .init_hook = alc883_eee1601_inithook,
8646 },
9c7f852e
TI
8647};
8648
8649
8650/*
8651 * BIOS auto configuration
8652 */
8653static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8654 hda_nid_t nid, int pin_type,
8655 int dac_idx)
8656{
8657 /* set as output */
8658 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
8659 int idx;
8660
f6c7e546 8661 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
8662 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8663 idx = 4;
8664 else
8665 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
8666 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8667
8668}
8669
8670static void alc883_auto_init_multi_out(struct hda_codec *codec)
8671{
8672 struct alc_spec *spec = codec->spec;
8673 int i;
8674
bc9f98a9 8675 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 8676 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 8677 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 8678 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 8679 if (nid)
baba8ee9 8680 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 8681 i);
9c7f852e
TI
8682 }
8683}
8684
8685static void alc883_auto_init_hp_out(struct hda_codec *codec)
8686{
8687 struct alc_spec *spec = codec->spec;
8688 hda_nid_t pin;
8689
eb06ed8f 8690 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
8691 if (pin) /* connect to front */
8692 /* use dac 0 */
8693 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
8694 pin = spec->autocfg.speaker_pins[0];
8695 if (pin)
8696 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
8697}
8698
8699#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8700#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8701
8702static void alc883_auto_init_analog_input(struct hda_codec *codec)
8703{
8704 struct alc_spec *spec = codec->spec;
8705 int i;
8706
8707 for (i = 0; i < AUTO_PIN_LAST; i++) {
8708 hda_nid_t nid = spec->autocfg.input_pins[i];
8709 if (alc883_is_input_pin(nid)) {
8710 snd_hda_codec_write(codec, nid, 0,
8711 AC_VERB_SET_PIN_WIDGET_CONTROL,
8712 (i <= AUTO_PIN_FRONT_MIC ?
8713 PIN_VREF80 : PIN_IN));
8714 if (nid != ALC883_PIN_CD_NID)
8715 snd_hda_codec_write(codec, nid, 0,
8716 AC_VERB_SET_AMP_GAIN_MUTE,
8717 AMP_OUT_MUTE);
8718 }
8719 }
8720}
8721
f511b01c
TI
8722#define alc883_auto_init_input_src alc882_auto_init_input_src
8723
9c7f852e
TI
8724/* almost identical with ALC880 parser... */
8725static int alc883_parse_auto_config(struct hda_codec *codec)
8726{
8727 struct alc_spec *spec = codec->spec;
8728 int err = alc880_parse_auto_config(codec);
8729
8730 if (err < 0)
8731 return err;
776e184e
TI
8732 else if (!err)
8733 return 0; /* no config found */
8734
8735 err = alc_auto_add_mic_boost(codec);
8736 if (err < 0)
8737 return err;
8738
8739 /* hack - override the init verbs */
8740 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
8741 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8742 spec->num_mixers++;
776e184e
TI
8743
8744 return 1; /* config found */
9c7f852e
TI
8745}
8746
8747/* additional initialization for auto-configuration model */
8748static void alc883_auto_init(struct hda_codec *codec)
8749{
f6c7e546 8750 struct alc_spec *spec = codec->spec;
9c7f852e
TI
8751 alc883_auto_init_multi_out(codec);
8752 alc883_auto_init_hp_out(codec);
8753 alc883_auto_init_analog_input(codec);
f511b01c 8754 alc883_auto_init_input_src(codec);
f6c7e546
TI
8755 if (spec->unsol_event)
8756 alc_sku_automute(codec);
9c7f852e
TI
8757}
8758
8759static int patch_alc883(struct hda_codec *codec)
8760{
8761 struct alc_spec *spec;
8762 int err, board_config;
8763
8764 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8765 if (spec == NULL)
8766 return -ENOMEM;
8767
8768 codec->spec = spec;
8769
2c3bf9ab
TI
8770 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8771
f5fcc13c
TI
8772 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8773 alc883_models,
8774 alc883_cfg_tbl);
8775 if (board_config < 0) {
9c7f852e
TI
8776 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8777 "trying auto-probe from BIOS...\n");
8778 board_config = ALC883_AUTO;
8779 }
8780
8781 if (board_config == ALC883_AUTO) {
8782 /* automatic parse from the BIOS config */
8783 err = alc883_parse_auto_config(codec);
8784 if (err < 0) {
8785 alc_free(codec);
8786 return err;
f12ab1e0 8787 } else if (!err) {
9c7f852e
TI
8788 printk(KERN_INFO
8789 "hda_codec: Cannot set up configuration "
8790 "from BIOS. Using base mode...\n");
8791 board_config = ALC883_3ST_2ch_DIG;
8792 }
8793 }
8794
8795 if (board_config != ALC883_AUTO)
8796 setup_preset(spec, &alc883_presets[board_config]);
8797
2f893286
KY
8798 switch (codec->vendor_id) {
8799 case 0x10ec0888:
8800 spec->stream_name_analog = "ALC888 Analog";
8801 spec->stream_name_digital = "ALC888 Digital";
8802 break;
8803 case 0x10ec0889:
8804 spec->stream_name_analog = "ALC889 Analog";
8805 spec->stream_name_digital = "ALC889 Digital";
8806 break;
8807 default:
8808 spec->stream_name_analog = "ALC883 Analog";
8809 spec->stream_name_digital = "ALC883 Digital";
8810 break;
8811 }
8812
9c7f852e
TI
8813 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8814 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8815 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e 8816
9c7f852e
TI
8817 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8818 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8819
e1406348
TI
8820 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8821 spec->adc_nids = alc883_adc_nids;
8822 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8823
2134ea4f
TI
8824 spec->vmaster_nid = 0x0c;
8825
9c7f852e
TI
8826 codec->patch_ops = alc_patch_ops;
8827 if (board_config == ALC883_AUTO)
8828 spec->init_hook = alc883_auto_init;
f9423e7a 8829
cb53c626
TI
8830#ifdef CONFIG_SND_HDA_POWER_SAVE
8831 if (!spec->loopback.amplist)
8832 spec->loopback.amplist = alc883_loopbacks;
8833#endif
9c7f852e
TI
8834
8835 return 0;
8836}
8837
8838/*
8839 * ALC262 support
8840 */
8841
8842#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8843#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8844
8845#define alc262_dac_nids alc260_dac_nids
8846#define alc262_adc_nids alc882_adc_nids
8847#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
8848#define alc262_capsrc_nids alc882_capsrc_nids
8849#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
8850
8851#define alc262_modes alc260_modes
8852#define alc262_capture_source alc882_capture_source
8853
4e555fe5
KY
8854static hda_nid_t alc262_dmic_adc_nids[1] = {
8855 /* ADC0 */
8856 0x09
8857};
8858
8859static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8860
9c7f852e
TI
8861static struct snd_kcontrol_new alc262_base_mixer[] = {
8862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8863 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8864 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8865 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8866 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8867 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8870 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8871 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8872 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8873 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8874 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8875 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
8876 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8878 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8879 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8880 { } /* end */
8881};
8882
ccc656ce
KY
8883static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8885 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8886 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8887 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8888 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8889 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8892 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
8893 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8895 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 8896 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8897 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
8898 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8899 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8900 { } /* end */
8901};
8902
ce875f07
TI
8903/* update HP, line and mono-out pins according to the master switch */
8904static void alc262_hp_master_update(struct hda_codec *codec)
8905{
8906 struct alc_spec *spec = codec->spec;
8907 int val = spec->master_sw;
8908
8909 /* HP & line-out */
8910 snd_hda_codec_write_cache(codec, 0x1b, 0,
8911 AC_VERB_SET_PIN_WIDGET_CONTROL,
8912 val ? PIN_HP : 0);
8913 snd_hda_codec_write_cache(codec, 0x15, 0,
8914 AC_VERB_SET_PIN_WIDGET_CONTROL,
8915 val ? PIN_HP : 0);
8916 /* mono (speaker) depending on the HP jack sense */
8917 val = val && !spec->jack_present;
8918 snd_hda_codec_write_cache(codec, 0x16, 0,
8919 AC_VERB_SET_PIN_WIDGET_CONTROL,
8920 val ? PIN_OUT : 0);
8921}
8922
8923static void alc262_hp_bpc_automute(struct hda_codec *codec)
8924{
8925 struct alc_spec *spec = codec->spec;
8926 unsigned int presence;
8927 presence = snd_hda_codec_read(codec, 0x1b, 0,
8928 AC_VERB_GET_PIN_SENSE, 0);
8929 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8930 alc262_hp_master_update(codec);
8931}
8932
8933static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8934{
8935 if ((res >> 26) != ALC880_HP_EVENT)
8936 return;
8937 alc262_hp_bpc_automute(codec);
8938}
8939
8940static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8941{
8942 struct alc_spec *spec = codec->spec;
8943 unsigned int presence;
8944 presence = snd_hda_codec_read(codec, 0x15, 0,
8945 AC_VERB_GET_PIN_SENSE, 0);
8946 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8947 alc262_hp_master_update(codec);
8948}
8949
8950static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8951 unsigned int res)
8952{
8953 if ((res >> 26) != ALC880_HP_EVENT)
8954 return;
8955 alc262_hp_wildwest_automute(codec);
8956}
8957
8958static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8959 struct snd_ctl_elem_value *ucontrol)
8960{
8961 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8962 struct alc_spec *spec = codec->spec;
8963 *ucontrol->value.integer.value = spec->master_sw;
8964 return 0;
8965}
8966
8967static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8968 struct snd_ctl_elem_value *ucontrol)
8969{
8970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8971 struct alc_spec *spec = codec->spec;
8972 int val = !!*ucontrol->value.integer.value;
8973
8974 if (val == spec->master_sw)
8975 return 0;
8976 spec->master_sw = val;
8977 alc262_hp_master_update(codec);
8978 return 1;
8979}
8980
9c7f852e 8981static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
8982 {
8983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8984 .name = "Master Playback Switch",
8985 .info = snd_ctl_boolean_mono_info,
8986 .get = alc262_hp_master_sw_get,
8987 .put = alc262_hp_master_sw_put,
8988 },
9c7f852e
TI
8989 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
8992 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8993 HDA_OUTPUT),
8994 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8995 HDA_OUTPUT),
9c7f852e
TI
8996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8998 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9001 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9005 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9006 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9007 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9008 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9009 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9010 { } /* end */
9011};
9012
cd7509a4 9013static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
9014 {
9015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9016 .name = "Master Playback Switch",
9017 .info = snd_ctl_boolean_mono_info,
9018 .get = alc262_hp_master_sw_get,
9019 .put = alc262_hp_master_sw_put,
9020 },
cd7509a4
KY
9021 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9022 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9023 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9024 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9025 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9026 HDA_OUTPUT),
9027 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9028 HDA_OUTPUT),
cd7509a4
KY
9029 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9031 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9032 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9033 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9036 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9037 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9038 { } /* end */
9039};
9040
9041static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9042 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9043 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9044 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9045 { } /* end */
9046};
9047
66d2a9d6
KY
9048/* mute/unmute internal speaker according to the hp jack and mute state */
9049static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9050{
9051 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
9052
9053 if (force || !spec->sense_updated) {
9054 unsigned int present;
9055 present = snd_hda_codec_read(codec, 0x15, 0,
9056 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 9057 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
9058 spec->sense_updated = 1;
9059 }
4bb26130
TI
9060 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9061 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
9062}
9063
9064static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9065 unsigned int res)
9066{
9067 if ((res >> 26) != ALC880_HP_EVENT)
9068 return;
9069 alc262_hp_t5735_automute(codec, 1);
9070}
9071
9072static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9073{
9074 alc262_hp_t5735_automute(codec, 1);
9075}
9076
9077static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9078 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9081 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9085 { } /* end */
9086};
9087
9088static struct hda_verb alc262_hp_t5735_verbs[] = {
9089 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9091
9092 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9093 { }
9094};
9095
8c427226 9096static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9099 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9103 { } /* end */
9104};
9105
9106static struct hda_verb alc262_hp_rp5700_verbs[] = {
9107 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9108 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9110 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9111 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9112 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9114 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9117 {}
9118};
9119
9120static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9121 .num_items = 1,
9122 .items = {
9123 { "Line", 0x1 },
9124 },
9125};
9126
0724ea2a
TI
9127/* bind hp and internal speaker mute (with plug check) */
9128static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9129 struct snd_ctl_elem_value *ucontrol)
9130{
9131 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9132 long *valp = ucontrol->value.integer.value;
9133 int change;
9134
9135 /* change hp mute */
9136 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9137 HDA_AMP_MUTE,
9138 valp[0] ? 0 : HDA_AMP_MUTE);
9139 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9140 HDA_AMP_MUTE,
9141 valp[1] ? 0 : HDA_AMP_MUTE);
9142 if (change) {
9143 /* change speaker according to HP jack state */
9144 struct alc_spec *spec = codec->spec;
9145 unsigned int mute;
9146 if (spec->jack_present)
9147 mute = HDA_AMP_MUTE;
9148 else
9149 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9150 HDA_OUTPUT, 0);
9151 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9152 HDA_AMP_MUTE, mute);
9153 }
9154 return change;
9155}
5b31954e 9156
272a527c 9157static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
9158 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9159 {
9160 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9161 .name = "Master Playback Switch",
9162 .info = snd_hda_mixer_amp_switch_info,
9163 .get = snd_hda_mixer_amp_switch_get,
9164 .put = alc262_sony_master_sw_put,
9165 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9166 },
272a527c
KY
9167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9169 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9170 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9171 { } /* end */
9172};
9173
83c34218
KY
9174static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9175 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9176 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9180 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9181 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9182 { } /* end */
9183};
272a527c 9184
9c7f852e
TI
9185#define alc262_capture_mixer alc882_capture_mixer
9186#define alc262_capture_alt_mixer alc882_capture_alt_mixer
9187
9188/*
9189 * generic initialization of ADC, input mixers and output mixers
9190 */
9191static struct hda_verb alc262_init_verbs[] = {
9192 /*
9193 * Unmute ADC0-2 and set the default input to mic-in
9194 */
9195 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9197 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9199 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9201
cb53c626 9202 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9203 * mixer widget
f12ab1e0
TI
9204 * Note: PASD motherboards uses the Line In 2 as the input for
9205 * front panel mic (mic 2)
9c7f852e
TI
9206 */
9207 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
9213
9214 /*
df694daa
KY
9215 * Set up output mixers (0x0c - 0x0e)
9216 */
9217 /* set vol=0 to output mixers */
9218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9221 /* set up input amps for analog loopback */
9222 /* Amp Indices: DAC = 0, mixer = 1 */
9223 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9227 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229
9230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9232 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9233 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9234 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9235 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9236
9237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9239 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9240 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 9242
df694daa
KY
9243 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9244 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 9245
df694daa
KY
9246 /* FIXME: use matrix-type input source selection */
9247 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9248 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9253 /* Input mixer2 */
9254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9256 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9257 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9258 /* Input mixer3 */
9259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 9262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
9263
9264 { }
9265};
1da177e4 9266
4e555fe5
KY
9267static struct hda_verb alc262_eapd_verbs[] = {
9268 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9269 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9270 { }
9271};
9272
ccc656ce
KY
9273static struct hda_verb alc262_hippo_unsol_verbs[] = {
9274 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9276 {}
9277};
9278
9279static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9280 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9281 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9282 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9283
9284 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9286 {}
9287};
9288
272a527c
KY
9289static struct hda_verb alc262_sony_unsol_verbs[] = {
9290 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9291 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9292 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9293
9294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 9296 {}
272a527c
KY
9297};
9298
4e555fe5
KY
9299static struct hda_input_mux alc262_dmic_capture_source = {
9300 .num_items = 2,
9301 .items = {
9302 { "Int DMic", 0x9 },
9303 { "Mic", 0x0 },
9304 },
9305};
9306
9307static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9308 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9309 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9313 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9314 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9315 {
9316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9317 /* The multiple "Capture Source" controls confuse alsamixer
9318 * So call somewhat different..
9319 */
9320 /* .name = "Capture Source", */
9321 .name = "Input Source",
9322 .count = 1,
9323 .info = alc_mux_enum_info,
9324 .get = alc_mux_enum_get,
9325 .put = alc_mux_enum_put,
9326 },
9327 { } /* end */
9328};
9329
9330static struct hda_verb alc262_toshiba_s06_verbs[] = {
9331 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9334 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9335 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9337 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9339 {}
9340};
9341
9342static void alc262_dmic_automute(struct hda_codec *codec)
9343{
9344 unsigned int present;
9345
9346 present = snd_hda_codec_read(codec, 0x18, 0,
9347 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9348 snd_hda_codec_write(codec, 0x22, 0,
9349 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9350}
9351
9352/* toggle speaker-output according to the hp-jack state */
9353static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9354{
9355 unsigned int present;
9356 unsigned char bits;
9357
9358 present = snd_hda_codec_read(codec, 0x15, 0,
9359 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9360 bits = present ? 0 : PIN_OUT;
9361 snd_hda_codec_write(codec, 0x14, 0,
9362 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9363}
9364
9365
9366
9367/* unsolicited event for HP jack sensing */
9368static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9369 unsigned int res)
9370{
9371 if ((res >> 26) == ALC880_HP_EVENT)
9372 alc262_toshiba_s06_speaker_automute(codec);
9373 if ((res >> 26) == ALC880_MIC_EVENT)
9374 alc262_dmic_automute(codec);
9375
9376}
9377
9378static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9379{
9380 alc262_toshiba_s06_speaker_automute(codec);
9381 alc262_dmic_automute(codec);
9382}
9383
ccc656ce 9384/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 9385static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
9386{
9387 struct alc_spec *spec = codec->spec;
9388 unsigned int mute;
5b31954e 9389 unsigned int present;
ccc656ce 9390
5b31954e
TI
9391 /* need to execute and sync at first */
9392 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9393 present = snd_hda_codec_read(codec, 0x15, 0,
9394 AC_VERB_GET_PIN_SENSE, 0);
9395 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
9396 if (spec->jack_present) {
9397 /* mute internal speaker */
47fd830a
TI
9398 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9399 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9400 } else {
9401 /* unmute internal speaker if necessary */
9402 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
9403 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9404 HDA_AMP_MUTE, mute);
ccc656ce
KY
9405 }
9406}
9407
9408/* unsolicited event for HP jack sensing */
9409static void alc262_hippo_unsol_event(struct hda_codec *codec,
9410 unsigned int res)
9411{
9412 if ((res >> 26) != ALC880_HP_EVENT)
9413 return;
5b31954e 9414 alc262_hippo_automute(codec);
ccc656ce
KY
9415}
9416
5b31954e 9417static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 9418{
ccc656ce 9419 unsigned int mute;
5b31954e 9420 unsigned int present;
ccc656ce 9421
5b31954e
TI
9422 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9423 present = snd_hda_codec_read(codec, 0x1b, 0,
9424 AC_VERB_GET_PIN_SENSE, 0);
9425 present = (present & 0x80000000) != 0;
9426 if (present) {
ccc656ce 9427 /* mute internal speaker */
47fd830a
TI
9428 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9429 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9430 } else {
9431 /* unmute internal speaker if necessary */
9432 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
9433 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9434 HDA_AMP_MUTE, mute);
ccc656ce
KY
9435 }
9436}
9437
9438/* unsolicited event for HP jack sensing */
9439static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9440 unsigned int res)
9441{
9442 if ((res >> 26) != ALC880_HP_EVENT)
9443 return;
5b31954e 9444 alc262_hippo1_automute(codec);
ccc656ce
KY
9445}
9446
e8f9ae2a
PT
9447/*
9448 * nec model
9449 * 0x15 = headphone
9450 * 0x16 = internal speaker
9451 * 0x18 = external mic
9452 */
9453
9454static struct snd_kcontrol_new alc262_nec_mixer[] = {
9455 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9456 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9457
9458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9460 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9461
9462 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9464 { } /* end */
9465};
9466
9467static struct hda_verb alc262_nec_verbs[] = {
9468 /* Unmute Speaker */
9469 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9470
9471 /* Headphone */
9472 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9473 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9474
9475 /* External mic to headphone */
9476 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9477 /* External mic to speaker */
9478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9479 {}
9480};
9481
834be88d
TI
9482/*
9483 * fujitsu model
5d9fab2d
TV
9484 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9485 * 0x1b = port replicator headphone out
834be88d
TI
9486 */
9487
9488#define ALC_HP_EVENT 0x37
9489
9490static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9491 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
9493 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9494 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
9495 {}
9496};
9497
0e31daf7
J
9498static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9499 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9501 {}
9502};
9503
834be88d 9504static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 9505 .num_items = 3,
834be88d
TI
9506 .items = {
9507 { "Mic", 0x0 },
39d3ed38 9508 { "Int Mic", 0x1 },
834be88d
TI
9509 { "CD", 0x4 },
9510 },
9511};
9512
9c7f852e
TI
9513static struct hda_input_mux alc262_HP_capture_source = {
9514 .num_items = 5,
9515 .items = {
9516 { "Mic", 0x0 },
accbe498 9517 { "Front Mic", 0x1 },
9c7f852e
TI
9518 { "Line", 0x2 },
9519 { "CD", 0x4 },
9520 { "AUX IN", 0x6 },
9521 },
9522};
9523
accbe498 9524static struct hda_input_mux alc262_HP_D7000_capture_source = {
9525 .num_items = 4,
9526 .items = {
9527 { "Mic", 0x0 },
9528 { "Front Mic", 0x2 },
9529 { "Line", 0x1 },
9530 { "CD", 0x4 },
9531 },
9532};
9533
ebc7a406 9534/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
9535static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9536{
9537 struct alc_spec *spec = codec->spec;
9538 unsigned int mute;
9539
f12ab1e0 9540 if (force || !spec->sense_updated) {
ebc7a406 9541 unsigned int present;
834be88d
TI
9542 /* need to execute and sync at first */
9543 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
9544 /* check laptop HP jack */
9545 present = snd_hda_codec_read(codec, 0x14, 0,
9546 AC_VERB_GET_PIN_SENSE, 0);
9547 /* need to execute and sync at first */
9548 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9549 /* check docking HP jack */
9550 present |= snd_hda_codec_read(codec, 0x1b, 0,
9551 AC_VERB_GET_PIN_SENSE, 0);
9552 if (present & AC_PINSENSE_PRESENCE)
9553 spec->jack_present = 1;
9554 else
9555 spec->jack_present = 0;
834be88d
TI
9556 spec->sense_updated = 1;
9557 }
ebc7a406
TI
9558 /* unmute internal speaker only if both HPs are unplugged and
9559 * master switch is on
9560 */
9561 if (spec->jack_present)
9562 mute = HDA_AMP_MUTE;
9563 else
834be88d 9564 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
9565 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9566 HDA_AMP_MUTE, mute);
834be88d
TI
9567}
9568
9569/* unsolicited event for HP jack sensing */
9570static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9571 unsigned int res)
9572{
9573 if ((res >> 26) != ALC_HP_EVENT)
9574 return;
9575 alc262_fujitsu_automute(codec, 1);
9576}
9577
ebc7a406
TI
9578static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9579{
9580 alc262_fujitsu_automute(codec, 1);
9581}
9582
834be88d 9583/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
9584static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9585 .ops = &snd_hda_bind_vol,
9586 .values = {
9587 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9588 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9589 0
9590 },
9591};
834be88d 9592
0e31daf7
J
9593/* mute/unmute internal speaker according to the hp jack and mute state */
9594static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9595{
9596 struct alc_spec *spec = codec->spec;
9597 unsigned int mute;
9598
9599 if (force || !spec->sense_updated) {
9600 unsigned int present_int_hp;
9601 /* need to execute and sync at first */
9602 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9603 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9604 AC_VERB_GET_PIN_SENSE, 0);
9605 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9606 spec->sense_updated = 1;
9607 }
9608 if (spec->jack_present) {
9609 /* mute internal speaker */
9610 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9611 HDA_AMP_MUTE, HDA_AMP_MUTE);
9612 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9613 HDA_AMP_MUTE, HDA_AMP_MUTE);
9614 } else {
9615 /* unmute internal speaker if necessary */
9616 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9617 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9618 HDA_AMP_MUTE, mute);
9619 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9620 HDA_AMP_MUTE, mute);
9621 }
9622}
9623
9624/* unsolicited event for HP jack sensing */
9625static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9626 unsigned int res)
9627{
9628 if ((res >> 26) != ALC_HP_EVENT)
9629 return;
9630 alc262_lenovo_3000_automute(codec, 1);
9631}
9632
834be88d
TI
9633/* bind hp and internal speaker mute (with plug check) */
9634static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9635 struct snd_ctl_elem_value *ucontrol)
9636{
9637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9638 long *valp = ucontrol->value.integer.value;
9639 int change;
9640
5d9fab2d
TV
9641 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9642 HDA_AMP_MUTE,
9643 valp ? 0 : HDA_AMP_MUTE);
9644 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9645 HDA_AMP_MUTE,
9646 valp ? 0 : HDA_AMP_MUTE);
9647
82beb8fd
TI
9648 if (change)
9649 alc262_fujitsu_automute(codec, 0);
834be88d
TI
9650 return change;
9651}
9652
9653static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 9654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
9655 {
9656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9657 .name = "Master Playback Switch",
9658 .info = snd_hda_mixer_amp_switch_info,
9659 .get = snd_hda_mixer_amp_switch_get,
9660 .put = alc262_fujitsu_master_sw_put,
9661 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9662 },
9663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
06a9c30c
TV
9665 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9666 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
834be88d
TI
9667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
9670 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9671 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9672 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
9673 { } /* end */
9674};
9675
0e31daf7
J
9676/* bind hp and internal speaker mute (with plug check) */
9677static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9678 struct snd_ctl_elem_value *ucontrol)
9679{
9680 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9681 long *valp = ucontrol->value.integer.value;
9682 int change;
9683
9684 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9685 HDA_AMP_MUTE,
9686 valp ? 0 : HDA_AMP_MUTE);
9687
9688 if (change)
9689 alc262_lenovo_3000_automute(codec, 0);
9690 return change;
9691}
9692
9693static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9694 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9695 {
9696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9697 .name = "Master Playback Switch",
9698 .info = snd_hda_mixer_amp_switch_info,
9699 .get = snd_hda_mixer_amp_switch_get,
9700 .put = alc262_lenovo_3000_master_sw_put,
9701 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9702 },
9703 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9704 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9705 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9708 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9710 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9711 { } /* end */
9712};
9713
304dcaac
TI
9714/* additional init verbs for Benq laptops */
9715static struct hda_verb alc262_EAPD_verbs[] = {
9716 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9717 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9718 {}
9719};
9720
83c34218
KY
9721static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9723 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9724
9725 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9726 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9727 {}
9728};
9729
f651b50b
TD
9730/* Samsung Q1 Ultra Vista model setup */
9731static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
9732 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9733 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
9734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9736 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 9737 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
9738 { } /* end */
9739};
9740
9741static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
9742 /* output mixer */
9743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9746 /* speaker */
9747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9748 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9750 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9751 /* HP */
f651b50b 9752 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
9753 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9756 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9757 /* internal mic */
9758 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9760 /* ADC, choose mic */
9761 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
9771 {}
9772};
9773
f651b50b
TD
9774/* mute/unmute internal speaker according to the hp jack and mute state */
9775static void alc262_ultra_automute(struct hda_codec *codec)
9776{
9777 struct alc_spec *spec = codec->spec;
9778 unsigned int mute;
f651b50b 9779
bb9f76cd
TI
9780 mute = 0;
9781 /* auto-mute only when HP is used as HP */
9782 if (!spec->cur_mux[0]) {
9783 unsigned int present;
9784 /* need to execute and sync at first */
9785 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9786 present = snd_hda_codec_read(codec, 0x15, 0,
9787 AC_VERB_GET_PIN_SENSE, 0);
9788 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9789 if (spec->jack_present)
9790 mute = HDA_AMP_MUTE;
f651b50b 9791 }
bb9f76cd
TI
9792 /* mute/unmute internal speaker */
9793 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9794 HDA_AMP_MUTE, mute);
9795 /* mute/unmute HP */
9796 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9797 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
9798}
9799
9800/* unsolicited event for HP jack sensing */
9801static void alc262_ultra_unsol_event(struct hda_codec *codec,
9802 unsigned int res)
9803{
9804 if ((res >> 26) != ALC880_HP_EVENT)
9805 return;
9806 alc262_ultra_automute(codec);
9807}
9808
bb9f76cd
TI
9809static struct hda_input_mux alc262_ultra_capture_source = {
9810 .num_items = 2,
9811 .items = {
9812 { "Mic", 0x1 },
9813 { "Headphone", 0x7 },
9814 },
9815};
9816
9817static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9818 struct snd_ctl_elem_value *ucontrol)
9819{
9820 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9821 struct alc_spec *spec = codec->spec;
9822 int ret;
9823
9824 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9825 if (!ret)
9826 return 0;
9827 /* reprogram the HP pin as mic or HP according to the input source */
9828 snd_hda_codec_write_cache(codec, 0x15, 0,
9829 AC_VERB_SET_PIN_WIDGET_CONTROL,
9830 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9831 alc262_ultra_automute(codec); /* mute/unmute HP */
9832 return ret;
9833}
9834
9835static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9836 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9837 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9838 {
9839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9840 .name = "Capture Source",
9841 .info = alc882_mux_enum_info,
9842 .get = alc882_mux_enum_get,
9843 .put = alc262_ultra_mux_enum_put,
9844 },
9845 { } /* end */
9846};
9847
df694daa 9848/* add playback controls from the parsed DAC table */
f12ab1e0
TI
9849static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9850 const struct auto_pin_cfg *cfg)
df694daa
KY
9851{
9852 hda_nid_t nid;
9853 int err;
9854
9855 spec->multiout.num_dacs = 1; /* only use one dac */
9856 spec->multiout.dac_nids = spec->private_dac_nids;
9857 spec->multiout.dac_nids[0] = 2;
9858
9859 nid = cfg->line_out_pins[0];
9860 if (nid) {
f12ab1e0
TI
9861 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9862 "Front Playback Volume",
9863 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9864 if (err < 0)
df694daa 9865 return err;
f12ab1e0
TI
9866 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9867 "Front Playback Switch",
9868 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9869 if (err < 0)
df694daa
KY
9870 return err;
9871 }
9872
82bc955f 9873 nid = cfg->speaker_pins[0];
df694daa
KY
9874 if (nid) {
9875 if (nid == 0x16) {
f12ab1e0
TI
9876 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9877 "Speaker Playback Volume",
9878 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9879 HDA_OUTPUT));
9880 if (err < 0)
df694daa 9881 return err;
f12ab1e0
TI
9882 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9883 "Speaker Playback Switch",
9884 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9885 HDA_OUTPUT));
9886 if (err < 0)
df694daa
KY
9887 return err;
9888 } else {
f12ab1e0
TI
9889 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9890 "Speaker Playback Switch",
9891 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9892 HDA_OUTPUT));
9893 if (err < 0)
df694daa
KY
9894 return err;
9895 }
9896 }
eb06ed8f 9897 nid = cfg->hp_pins[0];
df694daa
KY
9898 if (nid) {
9899 /* spec->multiout.hp_nid = 2; */
9900 if (nid == 0x16) {
f12ab1e0
TI
9901 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9902 "Headphone Playback Volume",
9903 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9904 HDA_OUTPUT));
9905 if (err < 0)
df694daa 9906 return err;
f12ab1e0
TI
9907 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9908 "Headphone Playback Switch",
9909 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9910 HDA_OUTPUT));
9911 if (err < 0)
df694daa
KY
9912 return err;
9913 } else {
f12ab1e0
TI
9914 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9915 "Headphone Playback Switch",
9916 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9917 HDA_OUTPUT));
9918 if (err < 0)
df694daa
KY
9919 return err;
9920 }
9921 }
f12ab1e0 9922 return 0;
df694daa
KY
9923}
9924
9925/* identical with ALC880 */
f12ab1e0
TI
9926#define alc262_auto_create_analog_input_ctls \
9927 alc880_auto_create_analog_input_ctls
df694daa
KY
9928
9929/*
9930 * generic initialization of ADC, input mixers and output mixers
9931 */
9932static struct hda_verb alc262_volume_init_verbs[] = {
9933 /*
9934 * Unmute ADC0-2 and set the default input to mic-in
9935 */
9936 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9937 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9938 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9939 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9940 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9941 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9942
cb53c626 9943 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 9944 * mixer widget
f12ab1e0
TI
9945 * Note: PASD motherboards uses the Line In 2 as the input for
9946 * front panel mic (mic 2)
df694daa
KY
9947 */
9948 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9951 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9952 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
9954
9955 /*
9956 * Set up output mixers (0x0c - 0x0f)
9957 */
9958 /* set vol=0 to output mixers */
9959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 9962
df694daa
KY
9963 /* set up input amps for analog loopback */
9964 /* Amp Indices: DAC = 0, mixer = 1 */
9965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9968 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9971
9972 /* FIXME: use matrix-type input source selection */
9973 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9974 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9979 /* Input mixer2 */
9980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9982 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9984 /* Input mixer3 */
9985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9989
9990 { }
9991};
9992
9c7f852e
TI
9993static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9994 /*
9995 * Unmute ADC0-2 and set the default input to mic-in
9996 */
9997 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9999 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10000 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10001 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10003
cb53c626 10004 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10005 * mixer widget
f12ab1e0
TI
10006 * Note: PASD motherboards uses the Line In 2 as the input for
10007 * front panel mic (mic 2)
9c7f852e
TI
10008 */
10009 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10017
9c7f852e
TI
10018 /*
10019 * Set up output mixers (0x0c - 0x0e)
10020 */
10021 /* set vol=0 to output mixers */
10022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10023 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10024 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10025
10026 /* set up input amps for analog loopback */
10027 /* Amp Indices: DAC = 0, mixer = 1 */
10028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10034
ce875f07 10035 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10037 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10038
10039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10041
10042 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10043 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10044
10045 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10046 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10047 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10048 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10049 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10050
10051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10053 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10055 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10056 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10057
10058
10059 /* FIXME: use matrix-type input source selection */
10060 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10061 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10064 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10066 /* Input mixer2 */
10067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10071 /* Input mixer3 */
10072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10076
ce875f07
TI
10077 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10078
9c7f852e
TI
10079 { }
10080};
10081
cd7509a4
KY
10082static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10083 /*
10084 * Unmute ADC0-2 and set the default input to mic-in
10085 */
10086 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10090 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10092
cb53c626 10093 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10094 * mixer widget
10095 * Note: PASD motherboards uses the Line In 2 as the input for front
10096 * panel mic (mic 2)
10097 */
10098 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10107 /*
10108 * Set up output mixers (0x0c - 0x0e)
10109 */
10110 /* set vol=0 to output mixers */
10111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10114
10115 /* set up input amps for analog loopback */
10116 /* Amp Indices: DAC = 0, mixer = 1 */
10117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10123
10124
10125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10129 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10130 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10131 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10132
10133 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10135
10136 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10137 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10138
10139 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10140 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10141 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10142 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10143 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10144 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10145
10146 /* FIXME: use matrix-type input source selection */
10147 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10148 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10152 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10154 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10156 /* Input mixer2 */
10157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10162 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10164 /* Input mixer3 */
10165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10170 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10171 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10172
ce875f07
TI
10173 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10174
cd7509a4
KY
10175 { }
10176};
10177
cb53c626
TI
10178#ifdef CONFIG_SND_HDA_POWER_SAVE
10179#define alc262_loopbacks alc880_loopbacks
10180#endif
10181
df694daa
KY
10182/* pcm configuration: identiacal with ALC880 */
10183#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10184#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10185#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10186#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10187
10188/*
10189 * BIOS auto configuration
10190 */
10191static int alc262_parse_auto_config(struct hda_codec *codec)
10192{
10193 struct alc_spec *spec = codec->spec;
10194 int err;
10195 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10196
f12ab1e0
TI
10197 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10198 alc262_ignore);
10199 if (err < 0)
df694daa 10200 return err;
f12ab1e0 10201 if (!spec->autocfg.line_outs)
df694daa 10202 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
10203 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10204 if (err < 0)
10205 return err;
10206 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10207 if (err < 0)
df694daa
KY
10208 return err;
10209
10210 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10211
10212 if (spec->autocfg.dig_out_pin)
10213 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10214 if (spec->autocfg.dig_in_pin)
10215 spec->dig_in_nid = ALC262_DIGIN_NID;
10216
10217 if (spec->kctl_alloc)
10218 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10219
10220 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 10221 spec->num_mux_defs = 1;
df694daa
KY
10222 spec->input_mux = &spec->private_imux;
10223
776e184e
TI
10224 err = alc_auto_add_mic_boost(codec);
10225 if (err < 0)
10226 return err;
10227
df694daa
KY
10228 return 1;
10229}
10230
10231#define alc262_auto_init_multi_out alc882_auto_init_multi_out
10232#define alc262_auto_init_hp_out alc882_auto_init_hp_out
10233#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 10234#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
10235
10236
10237/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 10238static void alc262_auto_init(struct hda_codec *codec)
df694daa 10239{
f6c7e546 10240 struct alc_spec *spec = codec->spec;
df694daa
KY
10241 alc262_auto_init_multi_out(codec);
10242 alc262_auto_init_hp_out(codec);
10243 alc262_auto_init_analog_input(codec);
f511b01c 10244 alc262_auto_init_input_src(codec);
f6c7e546
TI
10245 if (spec->unsol_event)
10246 alc_sku_automute(codec);
df694daa
KY
10247}
10248
10249/*
10250 * configuration and preset
10251 */
f5fcc13c
TI
10252static const char *alc262_models[ALC262_MODEL_LAST] = {
10253 [ALC262_BASIC] = "basic",
10254 [ALC262_HIPPO] = "hippo",
10255 [ALC262_HIPPO_1] = "hippo_1",
10256 [ALC262_FUJITSU] = "fujitsu",
10257 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 10258 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 10259 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 10260 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 10261 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
10262 [ALC262_BENQ_T31] = "benq-t31",
10263 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 10264 [ALC262_ULTRA] = "ultra",
0e31daf7 10265 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 10266 [ALC262_NEC] = "nec",
f5fcc13c
TI
10267 [ALC262_AUTO] = "auto",
10268};
10269
10270static struct snd_pci_quirk alc262_cfg_tbl[] = {
10271 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 10272 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
f5fcc13c 10273 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 10274 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
10275 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10276 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 10277 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 10278 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 10279 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 10280 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 10281 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10282 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10283 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10284 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10285 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10286 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10287 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10288 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
10289 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10290 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10291 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
10292 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10293 ALC262_HP_TC_T5735),
8c427226 10294 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 10295 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 10296 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 10297 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 10298 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741 10299 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
36ca6e13
AI
10300 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10301 ALC262_SONY_ASSAMD),
4e555fe5 10302 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 10303 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 10304 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 10305 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
bb9f76cd 10306 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
0e31daf7 10307 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
10308 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10309 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10310 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
10311 {}
10312};
10313
10314static struct alc_config_preset alc262_presets[] = {
10315 [ALC262_BASIC] = {
10316 .mixers = { alc262_base_mixer },
10317 .init_verbs = { alc262_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10319 .dac_nids = alc262_dac_nids,
10320 .hp_nid = 0x03,
10321 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10322 .channel_mode = alc262_modes,
a3bcba38 10323 .input_mux = &alc262_capture_source,
df694daa 10324 },
ccc656ce
KY
10325 [ALC262_HIPPO] = {
10326 .mixers = { alc262_base_mixer },
10327 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10329 .dac_nids = alc262_dac_nids,
10330 .hp_nid = 0x03,
10331 .dig_out_nid = ALC262_DIGOUT_NID,
10332 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10333 .channel_mode = alc262_modes,
10334 .input_mux = &alc262_capture_source,
10335 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10336 .init_hook = alc262_hippo_automute,
ccc656ce
KY
10337 },
10338 [ALC262_HIPPO_1] = {
10339 .mixers = { alc262_hippo1_mixer },
10340 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10342 .dac_nids = alc262_dac_nids,
10343 .hp_nid = 0x02,
10344 .dig_out_nid = ALC262_DIGOUT_NID,
10345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10346 .channel_mode = alc262_modes,
10347 .input_mux = &alc262_capture_source,
10348 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 10349 .init_hook = alc262_hippo1_automute,
ccc656ce 10350 },
834be88d
TI
10351 [ALC262_FUJITSU] = {
10352 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
10353 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10354 alc262_fujitsu_unsol_verbs },
834be88d
TI
10355 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10356 .dac_nids = alc262_dac_nids,
10357 .hp_nid = 0x03,
10358 .dig_out_nid = ALC262_DIGOUT_NID,
10359 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10360 .channel_mode = alc262_modes,
10361 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 10362 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 10363 .init_hook = alc262_fujitsu_init_hook,
834be88d 10364 },
9c7f852e
TI
10365 [ALC262_HP_BPC] = {
10366 .mixers = { alc262_HP_BPC_mixer },
10367 .init_verbs = { alc262_HP_BPC_init_verbs },
10368 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10369 .dac_nids = alc262_dac_nids,
10370 .hp_nid = 0x03,
10371 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10372 .channel_mode = alc262_modes,
10373 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
10374 .unsol_event = alc262_hp_bpc_unsol_event,
10375 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 10376 },
cd7509a4
KY
10377 [ALC262_HP_BPC_D7000_WF] = {
10378 .mixers = { alc262_HP_BPC_WildWest_mixer },
10379 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10380 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10381 .dac_nids = alc262_dac_nids,
10382 .hp_nid = 0x03,
10383 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10384 .channel_mode = alc262_modes,
accbe498 10385 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10386 .unsol_event = alc262_hp_wildwest_unsol_event,
10387 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10388 },
cd7509a4
KY
10389 [ALC262_HP_BPC_D7000_WL] = {
10390 .mixers = { alc262_HP_BPC_WildWest_mixer,
10391 alc262_HP_BPC_WildWest_option_mixer },
10392 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10393 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10394 .dac_nids = alc262_dac_nids,
10395 .hp_nid = 0x03,
10396 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10397 .channel_mode = alc262_modes,
accbe498 10398 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10399 .unsol_event = alc262_hp_wildwest_unsol_event,
10400 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10401 },
66d2a9d6
KY
10402 [ALC262_HP_TC_T5735] = {
10403 .mixers = { alc262_hp_t5735_mixer },
10404 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10405 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10406 .dac_nids = alc262_dac_nids,
10407 .hp_nid = 0x03,
10408 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10409 .channel_mode = alc262_modes,
10410 .input_mux = &alc262_capture_source,
10411 .unsol_event = alc262_hp_t5735_unsol_event,
10412 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
10413 },
10414 [ALC262_HP_RP5700] = {
10415 .mixers = { alc262_hp_rp5700_mixer },
10416 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10417 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10418 .dac_nids = alc262_dac_nids,
10419 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10420 .channel_mode = alc262_modes,
10421 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 10422 },
304dcaac
TI
10423 [ALC262_BENQ_ED8] = {
10424 .mixers = { alc262_base_mixer },
10425 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10426 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10427 .dac_nids = alc262_dac_nids,
10428 .hp_nid = 0x03,
10429 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10430 .channel_mode = alc262_modes,
10431 .input_mux = &alc262_capture_source,
f12ab1e0 10432 },
272a527c
KY
10433 [ALC262_SONY_ASSAMD] = {
10434 .mixers = { alc262_sony_mixer },
10435 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10436 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10437 .dac_nids = alc262_dac_nids,
10438 .hp_nid = 0x02,
10439 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10440 .channel_mode = alc262_modes,
10441 .input_mux = &alc262_capture_source,
10442 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10443 .init_hook = alc262_hippo_automute,
83c34218
KY
10444 },
10445 [ALC262_BENQ_T31] = {
10446 .mixers = { alc262_benq_t31_mixer },
10447 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10448 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10449 .dac_nids = alc262_dac_nids,
10450 .hp_nid = 0x03,
10451 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10452 .channel_mode = alc262_modes,
10453 .input_mux = &alc262_capture_source,
10454 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10455 .init_hook = alc262_hippo_automute,
ea1fb29a 10456 },
f651b50b 10457 [ALC262_ULTRA] = {
bb9f76cd
TI
10458 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10459 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
10460 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10461 .dac_nids = alc262_dac_nids,
f651b50b
TD
10462 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10463 .channel_mode = alc262_modes,
10464 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
10465 .adc_nids = alc262_adc_nids, /* ADC0 */
10466 .capsrc_nids = alc262_capsrc_nids,
10467 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
10468 .unsol_event = alc262_ultra_unsol_event,
10469 .init_hook = alc262_ultra_automute,
10470 },
0e31daf7
J
10471 [ALC262_LENOVO_3000] = {
10472 .mixers = { alc262_lenovo_3000_mixer },
10473 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10474 alc262_lenovo_3000_unsol_verbs },
10475 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10476 .dac_nids = alc262_dac_nids,
10477 .hp_nid = 0x03,
10478 .dig_out_nid = ALC262_DIGOUT_NID,
10479 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10480 .channel_mode = alc262_modes,
10481 .input_mux = &alc262_fujitsu_capture_source,
10482 .unsol_event = alc262_lenovo_3000_unsol_event,
10483 },
e8f9ae2a
PT
10484 [ALC262_NEC] = {
10485 .mixers = { alc262_nec_mixer },
10486 .init_verbs = { alc262_nec_verbs },
10487 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10488 .dac_nids = alc262_dac_nids,
10489 .hp_nid = 0x03,
10490 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10491 .channel_mode = alc262_modes,
10492 .input_mux = &alc262_capture_source,
10493 },
4e555fe5
KY
10494 [ALC262_TOSHIBA_S06] = {
10495 .mixers = { alc262_toshiba_s06_mixer },
10496 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10497 alc262_eapd_verbs },
10498 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10499 .capsrc_nids = alc262_dmic_capsrc_nids,
10500 .dac_nids = alc262_dac_nids,
10501 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10502 .dig_out_nid = ALC262_DIGOUT_NID,
10503 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10504 .channel_mode = alc262_modes,
10505 .input_mux = &alc262_dmic_capture_source,
10506 .unsol_event = alc262_toshiba_s06_unsol_event,
10507 .init_hook = alc262_toshiba_s06_init_hook,
10508 },
df694daa
KY
10509};
10510
10511static int patch_alc262(struct hda_codec *codec)
10512{
10513 struct alc_spec *spec;
10514 int board_config;
10515 int err;
10516
dc041e0b 10517 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
10518 if (spec == NULL)
10519 return -ENOMEM;
10520
10521 codec->spec = spec;
10522#if 0
f12ab1e0
TI
10523 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10524 * under-run
10525 */
df694daa
KY
10526 {
10527 int tmp;
10528 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10529 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10530 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10531 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10532 }
10533#endif
10534
2c3bf9ab
TI
10535 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10536
f5fcc13c
TI
10537 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10538 alc262_models,
10539 alc262_cfg_tbl);
cd7509a4 10540
f5fcc13c 10541 if (board_config < 0) {
9c7f852e
TI
10542 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10543 "trying auto-probe from BIOS...\n");
df694daa
KY
10544 board_config = ALC262_AUTO;
10545 }
10546
10547 if (board_config == ALC262_AUTO) {
10548 /* automatic parse from the BIOS config */
10549 err = alc262_parse_auto_config(codec);
10550 if (err < 0) {
10551 alc_free(codec);
10552 return err;
f12ab1e0 10553 } else if (!err) {
9c7f852e
TI
10554 printk(KERN_INFO
10555 "hda_codec: Cannot set up configuration "
10556 "from BIOS. Using base mode...\n");
df694daa
KY
10557 board_config = ALC262_BASIC;
10558 }
10559 }
10560
10561 if (board_config != ALC262_AUTO)
10562 setup_preset(spec, &alc262_presets[board_config]);
10563
10564 spec->stream_name_analog = "ALC262 Analog";
10565 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10566 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 10567
df694daa
KY
10568 spec->stream_name_digital = "ALC262 Digital";
10569 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10570 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10571
f12ab1e0 10572 if (!spec->adc_nids && spec->input_mux) {
df694daa 10573 /* check whether NID 0x07 is valid */
4a471b7d
TI
10574 unsigned int wcap = get_wcaps(codec, 0x07);
10575
f12ab1e0
TI
10576 /* get type */
10577 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
10578 if (wcap != AC_WID_AUD_IN) {
10579 spec->adc_nids = alc262_adc_nids_alt;
10580 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 10581 spec->capsrc_nids = alc262_capsrc_nids_alt;
f12ab1e0
TI
10582 spec->mixers[spec->num_mixers] =
10583 alc262_capture_alt_mixer;
df694daa
KY
10584 spec->num_mixers++;
10585 } else {
10586 spec->adc_nids = alc262_adc_nids;
10587 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 10588 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
10589 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10590 spec->num_mixers++;
10591 }
10592 }
10593
2134ea4f
TI
10594 spec->vmaster_nid = 0x0c;
10595
df694daa
KY
10596 codec->patch_ops = alc_patch_ops;
10597 if (board_config == ALC262_AUTO)
ae6b813a 10598 spec->init_hook = alc262_auto_init;
cb53c626
TI
10599#ifdef CONFIG_SND_HDA_POWER_SAVE
10600 if (!spec->loopback.amplist)
10601 spec->loopback.amplist = alc262_loopbacks;
10602#endif
ea1fb29a 10603
df694daa
KY
10604 return 0;
10605}
10606
a361d84b
KY
10607/*
10608 * ALC268 channel source setting (2 channel)
10609 */
10610#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10611#define alc268_modes alc260_modes
ea1fb29a 10612
a361d84b
KY
10613static hda_nid_t alc268_dac_nids[2] = {
10614 /* front, hp */
10615 0x02, 0x03
10616};
10617
10618static hda_nid_t alc268_adc_nids[2] = {
10619 /* ADC0-1 */
10620 0x08, 0x07
10621};
10622
10623static hda_nid_t alc268_adc_nids_alt[1] = {
10624 /* ADC0 */
10625 0x08
10626};
10627
e1406348
TI
10628static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10629
a361d84b
KY
10630static struct snd_kcontrol_new alc268_base_mixer[] = {
10631 /* output mixer control */
10632 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10633 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10634 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
10636 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10637 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10638 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
10639 { }
10640};
10641
aef9d318
TI
10642/* bind Beep switches of both NID 0x0f and 0x10 */
10643static struct hda_bind_ctls alc268_bind_beep_sw = {
10644 .ops = &snd_hda_bind_sw,
10645 .values = {
10646 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10647 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10648 0
10649 },
10650};
10651
10652static struct snd_kcontrol_new alc268_beep_mixer[] = {
10653 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10654 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10655 { }
10656};
10657
d1a991a6
KY
10658static struct hda_verb alc268_eapd_verbs[] = {
10659 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10660 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10661 { }
10662};
10663
d273809e
TI
10664/* Toshiba specific */
10665#define alc268_toshiba_automute alc262_hippo_automute
10666
10667static struct hda_verb alc268_toshiba_verbs[] = {
10668 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10669 { } /* end */
10670};
10671
8ef355da
KY
10672static struct hda_input_mux alc268_acer_lc_capture_source = {
10673 .num_items = 2,
10674 .items = {
10675 { "i-Mic", 0x6 },
10676 { "E-Mic", 0x0 },
10677 },
10678};
10679
d273809e 10680/* Acer specific */
889c4395 10681/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
10682static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10683 .ops = &snd_hda_bind_vol,
10684 .values = {
10685 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10686 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10687 0
10688 },
10689};
10690
889c4395
TI
10691/* mute/unmute internal speaker according to the hp jack and mute state */
10692static void alc268_acer_automute(struct hda_codec *codec, int force)
10693{
10694 struct alc_spec *spec = codec->spec;
10695 unsigned int mute;
10696
10697 if (force || !spec->sense_updated) {
10698 unsigned int present;
10699 present = snd_hda_codec_read(codec, 0x14, 0,
10700 AC_VERB_GET_PIN_SENSE, 0);
10701 spec->jack_present = (present & 0x80000000) != 0;
10702 spec->sense_updated = 1;
10703 }
10704 if (spec->jack_present)
10705 mute = HDA_AMP_MUTE; /* mute internal speaker */
10706 else /* unmute internal speaker if necessary */
10707 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10708 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10709 HDA_AMP_MUTE, mute);
10710}
10711
10712
10713/* bind hp and internal speaker mute (with plug check) */
10714static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10715 struct snd_ctl_elem_value *ucontrol)
10716{
10717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10718 long *valp = ucontrol->value.integer.value;
10719 int change;
10720
10721 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10722 HDA_AMP_MUTE,
10723 valp[0] ? 0 : HDA_AMP_MUTE);
10724 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10725 HDA_AMP_MUTE,
10726 valp[1] ? 0 : HDA_AMP_MUTE);
10727 if (change)
10728 alc268_acer_automute(codec, 0);
10729 return change;
10730}
d273809e 10731
8ef355da
KY
10732static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10733 /* output mixer control */
10734 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10735 {
10736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10737 .name = "Master Playback Switch",
10738 .info = snd_hda_mixer_amp_switch_info,
10739 .get = snd_hda_mixer_amp_switch_get,
10740 .put = alc268_acer_master_sw_put,
10741 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10742 },
10743 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10744 { }
10745};
10746
d273809e
TI
10747static struct snd_kcontrol_new alc268_acer_mixer[] = {
10748 /* output mixer control */
10749 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10750 {
10751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10752 .name = "Master Playback Switch",
10753 .info = snd_hda_mixer_amp_switch_info,
10754 .get = snd_hda_mixer_amp_switch_get,
10755 .put = alc268_acer_master_sw_put,
10756 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10757 },
33bf17ab
TI
10758 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10759 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10760 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
10761 { }
10762};
10763
8ef355da
KY
10764static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10765 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10768 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10769 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10770 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10771 { }
10772};
10773
d273809e 10774static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
10775 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10776 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
10777 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
10779 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
10781 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10782 { }
10783};
10784
10785/* unsolicited event for HP jack sensing */
10786static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10787 unsigned int res)
10788{
889c4395 10789 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
10790 return;
10791 alc268_toshiba_automute(codec);
10792}
10793
10794static void alc268_acer_unsol_event(struct hda_codec *codec,
10795 unsigned int res)
10796{
889c4395 10797 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
10798 return;
10799 alc268_acer_automute(codec, 1);
10800}
10801
889c4395
TI
10802static void alc268_acer_init_hook(struct hda_codec *codec)
10803{
10804 alc268_acer_automute(codec, 1);
10805}
10806
8ef355da
KY
10807/* toggle speaker-output according to the hp-jack state */
10808static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10809{
10810 unsigned int present;
10811 unsigned char bits;
10812
10813 present = snd_hda_codec_read(codec, 0x15, 0,
10814 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10815 bits = present ? AMP_IN_MUTE(0) : 0;
10816 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10817 AMP_IN_MUTE(0), bits);
10818 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10819 AMP_IN_MUTE(0), bits);
10820}
10821
10822
10823static void alc268_acer_mic_automute(struct hda_codec *codec)
10824{
10825 unsigned int present;
10826
10827 present = snd_hda_codec_read(codec, 0x18, 0,
10828 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10829 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10830 present ? 0x0 : 0x6);
10831}
10832
10833static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10834 unsigned int res)
10835{
10836 if ((res >> 26) == ALC880_HP_EVENT)
10837 alc268_aspire_one_speaker_automute(codec);
10838 if ((res >> 26) == ALC880_MIC_EVENT)
10839 alc268_acer_mic_automute(codec);
10840}
10841
10842static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10843{
10844 alc268_aspire_one_speaker_automute(codec);
10845 alc268_acer_mic_automute(codec);
10846}
10847
3866f0b0
TI
10848static struct snd_kcontrol_new alc268_dell_mixer[] = {
10849 /* output mixer control */
10850 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10851 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10855 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10856 { }
10857};
10858
10859static struct hda_verb alc268_dell_verbs[] = {
10860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10863 { }
10864};
10865
10866/* mute/unmute internal speaker according to the hp jack and mute state */
10867static void alc268_dell_automute(struct hda_codec *codec)
10868{
10869 unsigned int present;
10870 unsigned int mute;
10871
10872 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10873 if (present & 0x80000000)
10874 mute = HDA_AMP_MUTE;
10875 else
10876 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10877 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10878 HDA_AMP_MUTE, mute);
10879}
10880
10881static void alc268_dell_unsol_event(struct hda_codec *codec,
10882 unsigned int res)
10883{
10884 if ((res >> 26) != ALC880_HP_EVENT)
10885 return;
10886 alc268_dell_automute(codec);
10887}
10888
10889#define alc268_dell_init_hook alc268_dell_automute
10890
eb5a6621
HRK
10891static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10892 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10893 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10894 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10896 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10897 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10898 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10899 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10900 { }
10901};
10902
10903static struct hda_verb alc267_quanta_il1_verbs[] = {
10904 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10905 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10906 { }
10907};
10908
10909static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10910{
10911 unsigned int present;
10912
10913 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10914 & AC_PINSENSE_PRESENCE;
10915 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10916 present ? 0 : PIN_OUT);
10917}
10918
10919static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10920{
10921 unsigned int present;
10922
10923 present = snd_hda_codec_read(codec, 0x18, 0,
10924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10925 snd_hda_codec_write(codec, 0x23, 0,
10926 AC_VERB_SET_CONNECT_SEL,
10927 present ? 0x00 : 0x01);
10928}
10929
10930static void alc267_quanta_il1_automute(struct hda_codec *codec)
10931{
10932 alc267_quanta_il1_hp_automute(codec);
10933 alc267_quanta_il1_mic_automute(codec);
10934}
10935
10936static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10937 unsigned int res)
10938{
10939 switch (res >> 26) {
10940 case ALC880_HP_EVENT:
10941 alc267_quanta_il1_hp_automute(codec);
10942 break;
10943 case ALC880_MIC_EVENT:
10944 alc267_quanta_il1_mic_automute(codec);
10945 break;
10946 }
10947}
10948
a361d84b
KY
10949/*
10950 * generic initialization of ADC, input mixers and output mixers
10951 */
10952static struct hda_verb alc268_base_init_verbs[] = {
10953 /* Unmute DAC0-1 and set vol = 0 */
10954 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10955 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10956 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10957 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10958 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10959 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10960
10961 /*
10962 * Set up output mixers (0x0c - 0x0e)
10963 */
10964 /* set vol=0 to output mixers */
10965 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10966 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10968 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10969
10970 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10971 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10972
10973 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10975 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10976 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10977 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10978 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10979 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10980 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10981
10982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10984 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10985 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10986 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10987 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10988 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
10989
10990 /* set PCBEEP vol = 0, mute connections */
10991 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10992 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10993 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 10994
a9b3aa8a 10995 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 10996
a9b3aa8a
JZ
10997 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10998 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10999 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11000 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11001
a361d84b
KY
11002 { }
11003};
11004
11005/*
11006 * generic initialization of ADC, input mixers and output mixers
11007 */
11008static struct hda_verb alc268_volume_init_verbs[] = {
11009 /* set output DAC */
11010 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11011 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11012 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11013 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11014
11015 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11016 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11017 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11018 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11019 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11020
11021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11024 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11025 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11026
11027 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11028 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11029 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11030 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11031
aef9d318
TI
11032 /* set PCBEEP vol = 0, mute connections */
11033 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11036
11037 { }
11038};
11039
11040#define alc268_mux_enum_info alc_mux_enum_info
11041#define alc268_mux_enum_get alc_mux_enum_get
e1406348 11042#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
11043
11044static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11045 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11046 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11047 {
11048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11049 /* The multiple "Capture Source" controls confuse alsamixer
11050 * So call somewhat different..
a361d84b
KY
11051 */
11052 /* .name = "Capture Source", */
11053 .name = "Input Source",
11054 .count = 1,
11055 .info = alc268_mux_enum_info,
11056 .get = alc268_mux_enum_get,
11057 .put = alc268_mux_enum_put,
11058 },
11059 { } /* end */
11060};
11061
11062static struct snd_kcontrol_new alc268_capture_mixer[] = {
11063 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11064 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11065 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11066 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11067 {
11068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11069 /* The multiple "Capture Source" controls confuse alsamixer
11070 * So call somewhat different..
a361d84b
KY
11071 */
11072 /* .name = "Capture Source", */
11073 .name = "Input Source",
11074 .count = 2,
11075 .info = alc268_mux_enum_info,
11076 .get = alc268_mux_enum_get,
11077 .put = alc268_mux_enum_put,
11078 },
11079 { } /* end */
11080};
11081
11082static struct hda_input_mux alc268_capture_source = {
11083 .num_items = 4,
11084 .items = {
11085 { "Mic", 0x0 },
11086 { "Front Mic", 0x1 },
11087 { "Line", 0x2 },
11088 { "CD", 0x3 },
11089 },
11090};
11091
0ccb541c
TI
11092static struct hda_input_mux alc268_acer_capture_source = {
11093 .num_items = 3,
11094 .items = {
11095 { "Mic", 0x0 },
11096 { "Internal Mic", 0x6 },
11097 { "Line", 0x2 },
11098 },
11099};
11100
86c53bd2
JW
11101#ifdef CONFIG_SND_DEBUG
11102static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11103 /* Volume widgets */
11104 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11105 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11106 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11107 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11108 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11109 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11110 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11111 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11112 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11113 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11114 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11116 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11117 /* The below appears problematic on some hardwares */
11118 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11119 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11120 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11121 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11122 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11123
11124 /* Modes for retasking pin widgets */
11125 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11126 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11127 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11128 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11129
11130 /* Controls for GPIO pins, assuming they are configured as outputs */
11131 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11132 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11133 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11134 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11135
11136 /* Switches to allow the digital SPDIF output pin to be enabled.
11137 * The ALC268 does not have an SPDIF input.
11138 */
11139 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11140
11141 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11142 * this output to turn on an external amplifier.
11143 */
11144 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11145 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11146
11147 { } /* end */
11148};
11149#endif
11150
a361d84b
KY
11151/* create input playback/capture controls for the given pin */
11152static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11153 const char *ctlname, int idx)
11154{
11155 char name[32];
11156 int err;
11157
11158 sprintf(name, "%s Playback Volume", ctlname);
11159 if (nid == 0x14) {
11160 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11161 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11162 HDA_OUTPUT));
11163 if (err < 0)
11164 return err;
11165 } else if (nid == 0x15) {
11166 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11167 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11168 HDA_OUTPUT));
11169 if (err < 0)
11170 return err;
11171 } else
11172 return -1;
11173 sprintf(name, "%s Playback Switch", ctlname);
11174 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11175 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11176 if (err < 0)
11177 return err;
11178 return 0;
11179}
11180
11181/* add playback controls from the parsed DAC table */
11182static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11183 const struct auto_pin_cfg *cfg)
11184{
11185 hda_nid_t nid;
11186 int err;
11187
11188 spec->multiout.num_dacs = 2; /* only use one dac */
11189 spec->multiout.dac_nids = spec->private_dac_nids;
11190 spec->multiout.dac_nids[0] = 2;
11191 spec->multiout.dac_nids[1] = 3;
11192
11193 nid = cfg->line_out_pins[0];
11194 if (nid)
ea1fb29a 11195 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
11196
11197 nid = cfg->speaker_pins[0];
11198 if (nid == 0x1d) {
11199 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11200 "Speaker Playback Volume",
11201 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11202 if (err < 0)
11203 return err;
11204 }
11205 nid = cfg->hp_pins[0];
11206 if (nid)
11207 alc268_new_analog_output(spec, nid, "Headphone", 0);
11208
11209 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11210 if (nid == 0x16) {
11211 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11212 "Mono Playback Switch",
11213 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11214 if (err < 0)
11215 return err;
11216 }
ea1fb29a 11217 return 0;
a361d84b
KY
11218}
11219
11220/* create playback/capture controls for input pins */
11221static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11222 const struct auto_pin_cfg *cfg)
11223{
11224 struct hda_input_mux *imux = &spec->private_imux;
11225 int i, idx1;
11226
11227 for (i = 0; i < AUTO_PIN_LAST; i++) {
11228 switch(cfg->input_pins[i]) {
11229 case 0x18:
11230 idx1 = 0; /* Mic 1 */
11231 break;
11232 case 0x19:
11233 idx1 = 1; /* Mic 2 */
11234 break;
11235 case 0x1a:
11236 idx1 = 2; /* Line In */
11237 break;
ea1fb29a 11238 case 0x1c:
a361d84b
KY
11239 idx1 = 3; /* CD */
11240 break;
7194cae6
TI
11241 case 0x12:
11242 case 0x13:
11243 idx1 = 6; /* digital mics */
11244 break;
a361d84b
KY
11245 default:
11246 continue;
11247 }
11248 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11249 imux->items[imux->num_items].index = idx1;
ea1fb29a 11250 imux->num_items++;
a361d84b
KY
11251 }
11252 return 0;
11253}
11254
11255static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11256{
11257 struct alc_spec *spec = codec->spec;
11258 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11259 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11260 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11261 unsigned int dac_vol1, dac_vol2;
11262
11263 if (speaker_nid) {
11264 snd_hda_codec_write(codec, speaker_nid, 0,
11265 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11266 snd_hda_codec_write(codec, 0x0f, 0,
11267 AC_VERB_SET_AMP_GAIN_MUTE,
11268 AMP_IN_UNMUTE(1));
11269 snd_hda_codec_write(codec, 0x10, 0,
11270 AC_VERB_SET_AMP_GAIN_MUTE,
11271 AMP_IN_UNMUTE(1));
11272 } else {
11273 snd_hda_codec_write(codec, 0x0f, 0,
11274 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11275 snd_hda_codec_write(codec, 0x10, 0,
11276 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11277 }
11278
11279 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 11280 if (line_nid == 0x14)
a361d84b
KY
11281 dac_vol2 = AMP_OUT_ZERO;
11282 else if (line_nid == 0x15)
11283 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 11284 if (hp_nid == 0x14)
a361d84b
KY
11285 dac_vol2 = AMP_OUT_ZERO;
11286 else if (hp_nid == 0x15)
11287 dac_vol1 = AMP_OUT_ZERO;
11288 if (line_nid != 0x16 || hp_nid != 0x16 ||
11289 spec->autocfg.line_out_pins[1] != 0x16 ||
11290 spec->autocfg.line_out_pins[2] != 0x16)
11291 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11292
11293 snd_hda_codec_write(codec, 0x02, 0,
11294 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11295 snd_hda_codec_write(codec, 0x03, 0,
11296 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11297}
11298
11299/* pcm configuration: identiacal with ALC880 */
11300#define alc268_pcm_analog_playback alc880_pcm_analog_playback
11301#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 11302#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
11303#define alc268_pcm_digital_playback alc880_pcm_digital_playback
11304
11305/*
11306 * BIOS auto configuration
11307 */
11308static int alc268_parse_auto_config(struct hda_codec *codec)
11309{
11310 struct alc_spec *spec = codec->spec;
11311 int err;
11312 static hda_nid_t alc268_ignore[] = { 0 };
11313
11314 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11315 alc268_ignore);
11316 if (err < 0)
11317 return err;
11318 if (!spec->autocfg.line_outs)
11319 return 0; /* can't find valid BIOS pin config */
11320
11321 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11322 if (err < 0)
11323 return err;
11324 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11325 if (err < 0)
11326 return err;
11327
11328 spec->multiout.max_channels = 2;
11329
11330 /* digital only support output */
11331 if (spec->autocfg.dig_out_pin)
11332 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11333
11334 if (spec->kctl_alloc)
11335 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11336
aef9d318
TI
11337 if (spec->autocfg.speaker_pins[0] != 0x1d)
11338 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11339
a361d84b
KY
11340 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11341 spec->num_mux_defs = 1;
11342 spec->input_mux = &spec->private_imux;
11343
776e184e
TI
11344 err = alc_auto_add_mic_boost(codec);
11345 if (err < 0)
11346 return err;
11347
a361d84b
KY
11348 return 1;
11349}
11350
11351#define alc268_auto_init_multi_out alc882_auto_init_multi_out
11352#define alc268_auto_init_hp_out alc882_auto_init_hp_out
11353#define alc268_auto_init_analog_input alc882_auto_init_analog_input
11354
11355/* init callback for auto-configuration model -- overriding the default init */
11356static void alc268_auto_init(struct hda_codec *codec)
11357{
f6c7e546 11358 struct alc_spec *spec = codec->spec;
a361d84b
KY
11359 alc268_auto_init_multi_out(codec);
11360 alc268_auto_init_hp_out(codec);
11361 alc268_auto_init_mono_speaker_out(codec);
11362 alc268_auto_init_analog_input(codec);
f6c7e546
TI
11363 if (spec->unsol_event)
11364 alc_sku_automute(codec);
a361d84b
KY
11365}
11366
11367/*
11368 * configuration and preset
11369 */
11370static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 11371 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 11372 [ALC268_3ST] = "3stack",
983f8ae4 11373 [ALC268_TOSHIBA] = "toshiba",
d273809e 11374 [ALC268_ACER] = "acer",
8ef355da 11375 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 11376 [ALC268_DELL] = "dell",
f12462c5 11377 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
11378#ifdef CONFIG_SND_DEBUG
11379 [ALC268_TEST] = "test",
11380#endif
a361d84b
KY
11381 [ALC268_AUTO] = "auto",
11382};
11383
11384static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 11385 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 11386 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 11387 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 11388 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 11389 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
11390 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11391 ALC268_ACER_ASPIRE_ONE),
3866f0b0 11392 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 11393 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 11394 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 11395 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 11396 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
378bd6a5 11397 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 11398 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 11399 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
f12462c5 11400 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
11401 {}
11402};
11403
11404static struct alc_config_preset alc268_presets[] = {
eb5a6621
HRK
11405 [ALC267_QUANTA_IL1] = {
11406 .mixers = { alc267_quanta_il1_mixer },
11407 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11408 alc267_quanta_il1_verbs },
11409 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11410 .dac_nids = alc268_dac_nids,
11411 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11412 .adc_nids = alc268_adc_nids_alt,
11413 .hp_nid = 0x03,
11414 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11415 .channel_mode = alc268_modes,
11416 .input_mux = &alc268_capture_source,
11417 .unsol_event = alc267_quanta_il1_unsol_event,
11418 .init_hook = alc267_quanta_il1_automute,
11419 },
a361d84b 11420 [ALC268_3ST] = {
aef9d318
TI
11421 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11422 alc268_beep_mixer },
a361d84b
KY
11423 .init_verbs = { alc268_base_init_verbs },
11424 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11425 .dac_nids = alc268_dac_nids,
11426 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11427 .adc_nids = alc268_adc_nids_alt,
e1406348 11428 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
11429 .hp_nid = 0x03,
11430 .dig_out_nid = ALC268_DIGOUT_NID,
11431 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11432 .channel_mode = alc268_modes,
11433 .input_mux = &alc268_capture_source,
11434 },
d1a991a6 11435 [ALC268_TOSHIBA] = {
aef9d318
TI
11436 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11437 alc268_beep_mixer },
d273809e
TI
11438 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11439 alc268_toshiba_verbs },
d1a991a6
KY
11440 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11441 .dac_nids = alc268_dac_nids,
11442 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11443 .adc_nids = alc268_adc_nids_alt,
e1406348 11444 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
11445 .hp_nid = 0x03,
11446 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11447 .channel_mode = alc268_modes,
11448 .input_mux = &alc268_capture_source,
d273809e
TI
11449 .unsol_event = alc268_toshiba_unsol_event,
11450 .init_hook = alc268_toshiba_automute,
11451 },
11452 [ALC268_ACER] = {
aef9d318
TI
11453 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11454 alc268_beep_mixer },
d273809e
TI
11455 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11456 alc268_acer_verbs },
11457 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11458 .dac_nids = alc268_dac_nids,
11459 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11460 .adc_nids = alc268_adc_nids_alt,
e1406348 11461 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
11462 .hp_nid = 0x02,
11463 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11464 .channel_mode = alc268_modes,
0ccb541c 11465 .input_mux = &alc268_acer_capture_source,
d273809e 11466 .unsol_event = alc268_acer_unsol_event,
889c4395 11467 .init_hook = alc268_acer_init_hook,
d1a991a6 11468 },
8ef355da
KY
11469 [ALC268_ACER_ASPIRE_ONE] = {
11470 .mixers = { alc268_acer_aspire_one_mixer,
11471 alc268_capture_alt_mixer },
11472 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11473 alc268_acer_aspire_one_verbs },
11474 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11475 .dac_nids = alc268_dac_nids,
11476 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11477 .adc_nids = alc268_adc_nids_alt,
11478 .capsrc_nids = alc268_capsrc_nids,
11479 .hp_nid = 0x03,
11480 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11481 .channel_mode = alc268_modes,
11482 .input_mux = &alc268_acer_lc_capture_source,
11483 .unsol_event = alc268_acer_lc_unsol_event,
11484 .init_hook = alc268_acer_lc_init_hook,
11485 },
3866f0b0 11486 [ALC268_DELL] = {
aef9d318 11487 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
11488 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11489 alc268_dell_verbs },
11490 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11491 .dac_nids = alc268_dac_nids,
11492 .hp_nid = 0x02,
11493 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11494 .channel_mode = alc268_modes,
11495 .unsol_event = alc268_dell_unsol_event,
11496 .init_hook = alc268_dell_init_hook,
11497 .input_mux = &alc268_capture_source,
11498 },
f12462c5 11499 [ALC268_ZEPTO] = {
aef9d318
TI
11500 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11501 alc268_beep_mixer },
f12462c5
MT
11502 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11503 alc268_toshiba_verbs },
11504 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11505 .dac_nids = alc268_dac_nids,
11506 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11507 .adc_nids = alc268_adc_nids_alt,
e1406348 11508 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
11509 .hp_nid = 0x03,
11510 .dig_out_nid = ALC268_DIGOUT_NID,
11511 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11512 .channel_mode = alc268_modes,
11513 .input_mux = &alc268_capture_source,
11514 .unsol_event = alc268_toshiba_unsol_event,
11515 .init_hook = alc268_toshiba_automute
11516 },
86c53bd2
JW
11517#ifdef CONFIG_SND_DEBUG
11518 [ALC268_TEST] = {
11519 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11520 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11521 alc268_volume_init_verbs },
11522 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11523 .dac_nids = alc268_dac_nids,
11524 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11525 .adc_nids = alc268_adc_nids_alt,
e1406348 11526 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
11527 .hp_nid = 0x03,
11528 .dig_out_nid = ALC268_DIGOUT_NID,
11529 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11530 .channel_mode = alc268_modes,
11531 .input_mux = &alc268_capture_source,
11532 },
11533#endif
a361d84b
KY
11534};
11535
11536static int patch_alc268(struct hda_codec *codec)
11537{
11538 struct alc_spec *spec;
11539 int board_config;
11540 int err;
11541
11542 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11543 if (spec == NULL)
11544 return -ENOMEM;
11545
11546 codec->spec = spec;
11547
11548 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11549 alc268_models,
11550 alc268_cfg_tbl);
11551
11552 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11553 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11554 "trying auto-probe from BIOS...\n");
11555 board_config = ALC268_AUTO;
11556 }
11557
11558 if (board_config == ALC268_AUTO) {
11559 /* automatic parse from the BIOS config */
11560 err = alc268_parse_auto_config(codec);
11561 if (err < 0) {
11562 alc_free(codec);
11563 return err;
11564 } else if (!err) {
11565 printk(KERN_INFO
11566 "hda_codec: Cannot set up configuration "
11567 "from BIOS. Using base mode...\n");
11568 board_config = ALC268_3ST;
11569 }
11570 }
11571
11572 if (board_config != ALC268_AUTO)
11573 setup_preset(spec, &alc268_presets[board_config]);
11574
2f893286
KY
11575 if (codec->vendor_id == 0x10ec0267) {
11576 spec->stream_name_analog = "ALC267 Analog";
11577 spec->stream_name_digital = "ALC267 Digital";
11578 } else {
11579 spec->stream_name_analog = "ALC268 Analog";
11580 spec->stream_name_digital = "ALC268 Digital";
11581 }
11582
a361d84b
KY
11583 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11584 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 11585 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 11586
a361d84b
KY
11587 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11588
aef9d318
TI
11589 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11590 /* override the amp caps for beep generator */
11591 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11592 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11593 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11594 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11595 (0 << AC_AMPCAP_MUTE_SHIFT));
11596
3866f0b0
TI
11597 if (!spec->adc_nids && spec->input_mux) {
11598 /* check whether NID 0x07 is valid */
11599 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 11600 int i;
3866f0b0
TI
11601
11602 /* get type */
11603 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 11604 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
11605 spec->adc_nids = alc268_adc_nids_alt;
11606 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11607 spec->mixers[spec->num_mixers] =
a361d84b 11608 alc268_capture_alt_mixer;
3866f0b0
TI
11609 spec->num_mixers++;
11610 } else {
11611 spec->adc_nids = alc268_adc_nids;
11612 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11613 spec->mixers[spec->num_mixers] =
11614 alc268_capture_mixer;
11615 spec->num_mixers++;
a361d84b 11616 }
e1406348 11617 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
11618 /* set default input source */
11619 for (i = 0; i < spec->num_adc_nids; i++)
11620 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11621 0, AC_VERB_SET_CONNECT_SEL,
11622 spec->input_mux->items[0].index);
a361d84b 11623 }
2134ea4f
TI
11624
11625 spec->vmaster_nid = 0x02;
11626
a361d84b
KY
11627 codec->patch_ops = alc_patch_ops;
11628 if (board_config == ALC268_AUTO)
11629 spec->init_hook = alc268_auto_init;
ea1fb29a 11630
a361d84b
KY
11631 return 0;
11632}
11633
f6a92248
KY
11634/*
11635 * ALC269 channel source setting (2 channel)
11636 */
11637#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11638
11639#define alc269_dac_nids alc260_dac_nids
11640
11641static hda_nid_t alc269_adc_nids[1] = {
11642 /* ADC1 */
f53281e6
KY
11643 0x08,
11644};
11645
e01bf509
TI
11646static hda_nid_t alc269_capsrc_nids[1] = {
11647 0x23,
11648};
11649
11650/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11651 * not a mux!
11652 */
11653
f53281e6
KY
11654static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11655 .num_items = 2,
11656 .items = {
11657 { "i-Mic", 0x5 },
11658 { "e-Mic", 0x0 },
11659 },
11660};
11661
11662static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11663 .num_items = 2,
11664 .items = {
11665 { "i-Mic", 0x1 },
11666 { "e-Mic", 0x0 },
11667 },
f6a92248
KY
11668};
11669
11670#define alc269_modes alc260_modes
11671#define alc269_capture_source alc880_lg_lw_capture_source
11672
11673static struct snd_kcontrol_new alc269_base_mixer[] = {
11674 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11675 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11676 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11677 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2005af24
TI
11680 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11681 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
f6a92248
KY
11682 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11685 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11686 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11687 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11688 { } /* end */
11689};
11690
60db6b53
KY
11691static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11692 /* output mixer control */
11693 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11694 {
11695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11696 .name = "Master Playback Switch",
11697 .info = snd_hda_mixer_amp_switch_info,
11698 .get = snd_hda_mixer_amp_switch_get,
11699 .put = alc268_acer_master_sw_put,
11700 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11701 },
11702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11706 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11707 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11708 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11709 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11710 { }
11711};
11712
f53281e6
KY
11713/* bind volumes of both NID 0x0c and 0x0d */
11714static struct hda_bind_ctls alc269_epc_bind_vol = {
11715 .ops = &snd_hda_bind_vol,
11716 .values = {
11717 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11718 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11719 0
11720 },
11721};
11722
11723static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11724 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11725 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11726 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11727 { } /* end */
11728};
11729
f6a92248
KY
11730/* capture mixer elements */
11731static struct snd_kcontrol_new alc269_capture_mixer[] = {
f53281e6
KY
11732 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11733 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
f6a92248
KY
11734 {
11735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11736 /* The multiple "Capture Source" controls confuse alsamixer
11737 * So call somewhat different..
f6a92248
KY
11738 */
11739 /* .name = "Capture Source", */
11740 .name = "Input Source",
11741 .count = 1,
11742 .info = alc_mux_enum_info,
11743 .get = alc_mux_enum_get,
11744 .put = alc_mux_enum_put,
11745 },
11746 { } /* end */
11747};
11748
f53281e6
KY
11749/* capture mixer elements */
11750static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11751 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11752 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11753 { } /* end */
11754};
11755
2005af24
TI
11756/* beep control */
11757static struct snd_kcontrol_new alc269_beep_mixer[] = {
11758 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11759 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11760 { } /* end */
11761};
11762
60db6b53
KY
11763static struct hda_verb alc269_quanta_fl1_verbs[] = {
11764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11765 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11768 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11769 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11770 { }
11771};
f6a92248 11772
60db6b53
KY
11773/* toggle speaker-output according to the hp-jack state */
11774static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11775{
11776 unsigned int present;
11777 unsigned char bits;
f6a92248 11778
60db6b53
KY
11779 present = snd_hda_codec_read(codec, 0x15, 0,
11780 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11781 bits = present ? AMP_IN_MUTE(0) : 0;
11782 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11783 AMP_IN_MUTE(0), bits);
11784 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11785 AMP_IN_MUTE(0), bits);
f6a92248 11786
60db6b53
KY
11787 snd_hda_codec_write(codec, 0x20, 0,
11788 AC_VERB_SET_COEF_INDEX, 0x0c);
11789 snd_hda_codec_write(codec, 0x20, 0,
11790 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 11791
60db6b53
KY
11792 snd_hda_codec_write(codec, 0x20, 0,
11793 AC_VERB_SET_COEF_INDEX, 0x0c);
11794 snd_hda_codec_write(codec, 0x20, 0,
11795 AC_VERB_SET_PROC_COEF, 0x480);
11796}
f6a92248 11797
60db6b53
KY
11798static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11799{
11800 unsigned int present;
f6a92248 11801
60db6b53
KY
11802 present = snd_hda_codec_read(codec, 0x18, 0,
11803 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11804 snd_hda_codec_write(codec, 0x23, 0,
11805 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11806}
f6a92248 11807
60db6b53
KY
11808static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11809 unsigned int res)
11810{
11811 if ((res >> 26) == ALC880_HP_EVENT)
11812 alc269_quanta_fl1_speaker_automute(codec);
11813 if ((res >> 26) == ALC880_MIC_EVENT)
11814 alc269_quanta_fl1_mic_automute(codec);
11815}
f6a92248 11816
60db6b53
KY
11817static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11818{
11819 alc269_quanta_fl1_speaker_automute(codec);
11820 alc269_quanta_fl1_mic_automute(codec);
11821}
f6a92248 11822
f53281e6
KY
11823static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11825 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11826 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11828 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11829 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11830 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11831 {}
11832};
11833
11834static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11836 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11837 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11838 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11839 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11840 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11841 {}
11842};
11843
11844/* toggle speaker-output according to the hp-jack state */
11845static void alc269_speaker_automute(struct hda_codec *codec)
11846{
11847 unsigned int present;
60db6b53 11848 unsigned char bits;
f53281e6
KY
11849
11850 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 11851 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
11852 bits = present ? AMP_IN_MUTE(0) : 0;
11853 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 11854 AMP_IN_MUTE(0), bits);
f53281e6 11855 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 11856 AMP_IN_MUTE(0), bits);
f53281e6
KY
11857}
11858
11859static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11860{
11861 unsigned int present;
11862
60db6b53
KY
11863 present = snd_hda_codec_read(codec, 0x18, 0,
11864 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11865 snd_hda_codec_write(codec, 0x23, 0,
11866 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
11867}
11868
11869static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11870{
11871 unsigned int present;
11872
60db6b53
KY
11873 present = snd_hda_codec_read(codec, 0x18, 0,
11874 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 11875 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 11876 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 11877 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 11878 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
11879}
11880
11881/* unsolicited event for HP jack sensing */
11882static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 11883 unsigned int res)
f53281e6
KY
11884{
11885 if ((res >> 26) == ALC880_HP_EVENT)
11886 alc269_speaker_automute(codec);
11887
11888 if ((res >> 26) == ALC880_MIC_EVENT)
11889 alc269_eeepc_dmic_automute(codec);
11890}
11891
11892static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11893{
11894 alc269_speaker_automute(codec);
11895 alc269_eeepc_dmic_automute(codec);
11896}
11897
11898/* unsolicited event for HP jack sensing */
11899static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 11900 unsigned int res)
f53281e6
KY
11901{
11902 if ((res >> 26) == ALC880_HP_EVENT)
11903 alc269_speaker_automute(codec);
11904
11905 if ((res >> 26) == ALC880_MIC_EVENT)
11906 alc269_eeepc_amic_automute(codec);
11907}
11908
11909static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11910{
11911 alc269_speaker_automute(codec);
11912 alc269_eeepc_amic_automute(codec);
11913}
11914
60db6b53
KY
11915/*
11916 * generic initialization of ADC, input mixers and output mixers
11917 */
11918static struct hda_verb alc269_init_verbs[] = {
11919 /*
11920 * Unmute ADC0 and set the default input to mic-in
11921 */
11922 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11923
11924 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11925 * analog-loopback mixer widget
11926 * Note: PASD motherboards uses the Line In 2 as the input for
11927 * front panel mic (mic 2)
11928 */
11929 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11933 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11934 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11935
11936 /*
11937 * Set up output mixers (0x0c - 0x0e)
11938 */
11939 /* set vol=0 to output mixers */
11940 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11941 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11942
11943 /* set up input amps for analog loopback */
11944 /* Amp Indices: DAC = 0, mixer = 1 */
11945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11948 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11951
11952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11954 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11955 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11956 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11958 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11959
11960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11962 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11963 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11964 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11965 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11966 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11967
11968 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11969 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11970
11971 /* FIXME: use matrix-type input source selection */
11972 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11973 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11978
11979 /* set EAPD */
11980 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11981 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11982 { }
11983};
11984
f6a92248
KY
11985/* add playback controls from the parsed DAC table */
11986static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11987 const struct auto_pin_cfg *cfg)
11988{
11989 hda_nid_t nid;
11990 int err;
11991
11992 spec->multiout.num_dacs = 1; /* only use one dac */
11993 spec->multiout.dac_nids = spec->private_dac_nids;
11994 spec->multiout.dac_nids[0] = 2;
11995
11996 nid = cfg->line_out_pins[0];
11997 if (nid) {
11998 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11999 "Front Playback Volume",
12000 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12001 if (err < 0)
12002 return err;
12003 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12004 "Front Playback Switch",
12005 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12006 if (err < 0)
12007 return err;
12008 }
12009
12010 nid = cfg->speaker_pins[0];
12011 if (nid) {
12012 if (!cfg->line_out_pins[0]) {
12013 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12014 "Speaker Playback Volume",
12015 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12016 HDA_OUTPUT));
12017 if (err < 0)
12018 return err;
12019 }
12020 if (nid == 0x16) {
12021 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12022 "Speaker Playback Switch",
12023 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12024 HDA_OUTPUT));
12025 if (err < 0)
12026 return err;
12027 } else {
12028 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12029 "Speaker Playback Switch",
12030 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12031 HDA_OUTPUT));
12032 if (err < 0)
12033 return err;
12034 }
12035 }
12036 nid = cfg->hp_pins[0];
12037 if (nid) {
12038 /* spec->multiout.hp_nid = 2; */
12039 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12040 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12041 "Headphone Playback Volume",
12042 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12043 HDA_OUTPUT));
12044 if (err < 0)
12045 return err;
12046 }
12047 if (nid == 0x16) {
12048 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12049 "Headphone Playback Switch",
12050 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12051 HDA_OUTPUT));
12052 if (err < 0)
12053 return err;
12054 } else {
12055 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12056 "Headphone Playback Switch",
12057 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12058 HDA_OUTPUT));
12059 if (err < 0)
12060 return err;
12061 }
12062 }
12063 return 0;
12064}
12065
12066#define alc269_auto_create_analog_input_ctls \
12067 alc880_auto_create_analog_input_ctls
12068
12069#ifdef CONFIG_SND_HDA_POWER_SAVE
12070#define alc269_loopbacks alc880_loopbacks
12071#endif
12072
12073/* pcm configuration: identiacal with ALC880 */
12074#define alc269_pcm_analog_playback alc880_pcm_analog_playback
12075#define alc269_pcm_analog_capture alc880_pcm_analog_capture
12076#define alc269_pcm_digital_playback alc880_pcm_digital_playback
12077#define alc269_pcm_digital_capture alc880_pcm_digital_capture
12078
12079/*
12080 * BIOS auto configuration
12081 */
12082static int alc269_parse_auto_config(struct hda_codec *codec)
12083{
12084 struct alc_spec *spec = codec->spec;
2005af24 12085 int i, err;
f6a92248
KY
12086 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12087
12088 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12089 alc269_ignore);
12090 if (err < 0)
12091 return err;
12092
12093 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12094 if (err < 0)
12095 return err;
12096 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12097 if (err < 0)
12098 return err;
12099
12100 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12101
12102 if (spec->autocfg.dig_out_pin)
12103 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12104
12105 if (spec->kctl_alloc)
12106 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12107
2005af24
TI
12108 /* create a beep mixer control if the pin 0x1d isn't assigned */
12109 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12110 if (spec->autocfg.input_pins[i] == 0x1d)
12111 break;
12112 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12113 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12114
f6a92248
KY
12115 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12116 spec->num_mux_defs = 1;
12117 spec->input_mux = &spec->private_imux;
e01bf509
TI
12118 /* set default input source */
12119 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12120 0, AC_VERB_SET_CONNECT_SEL,
12121 spec->input_mux->items[0].index);
f6a92248
KY
12122
12123 err = alc_auto_add_mic_boost(codec);
12124 if (err < 0)
12125 return err;
12126
f53281e6
KY
12127 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12128 spec->num_mixers++;
12129
f6a92248
KY
12130 return 1;
12131}
12132
12133#define alc269_auto_init_multi_out alc882_auto_init_multi_out
12134#define alc269_auto_init_hp_out alc882_auto_init_hp_out
12135#define alc269_auto_init_analog_input alc882_auto_init_analog_input
12136
12137
12138/* init callback for auto-configuration model -- overriding the default init */
12139static void alc269_auto_init(struct hda_codec *codec)
12140{
f6c7e546 12141 struct alc_spec *spec = codec->spec;
f6a92248
KY
12142 alc269_auto_init_multi_out(codec);
12143 alc269_auto_init_hp_out(codec);
12144 alc269_auto_init_analog_input(codec);
f6c7e546
TI
12145 if (spec->unsol_event)
12146 alc_sku_automute(codec);
f6a92248
KY
12147}
12148
12149/*
12150 * configuration and preset
12151 */
12152static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53
KY
12153 [ALC269_BASIC] = "basic",
12154 [ALC269_QUANTA_FL1] = "Quanta",
12155 [ALC269_ASUS_EEEPC_P901] = "Asus_Epc_Dmic"
f6a92248
KY
12156};
12157
12158static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 12159 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
12160 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12161 ALC269_ASUS_EEEPC_P703),
12162 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12163 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
12164 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12165 ALC269_ASUS_EEEPC_P901),
f6a92248
KY
12166 {}
12167};
12168
12169static struct alc_config_preset alc269_presets[] = {
12170 [ALC269_BASIC] = {
f53281e6 12171 .mixers = { alc269_base_mixer, alc269_capture_mixer },
f6a92248
KY
12172 .init_verbs = { alc269_init_verbs },
12173 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12174 .dac_nids = alc269_dac_nids,
12175 .hp_nid = 0x03,
12176 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12177 .channel_mode = alc269_modes,
12178 .input_mux = &alc269_capture_source,
12179 },
60db6b53
KY
12180 [ALC269_QUANTA_FL1] = {
12181 .mixers = { alc269_quanta_fl1_mixer },
12182 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12183 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12184 .dac_nids = alc269_dac_nids,
12185 .hp_nid = 0x03,
12186 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12187 .channel_mode = alc269_modes,
12188 .input_mux = &alc269_capture_source,
12189 .unsol_event = alc269_quanta_fl1_unsol_event,
12190 .init_hook = alc269_quanta_fl1_init_hook,
12191 },
f53281e6
KY
12192 [ALC269_ASUS_EEEPC_P703] = {
12193 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12194 .init_verbs = { alc269_init_verbs,
12195 alc269_eeepc_amic_init_verbs },
12196 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12197 .dac_nids = alc269_dac_nids,
12198 .hp_nid = 0x03,
12199 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12200 .channel_mode = alc269_modes,
12201 .input_mux = &alc269_eeepc_amic_capture_source,
12202 .unsol_event = alc269_eeepc_amic_unsol_event,
12203 .init_hook = alc269_eeepc_amic_inithook,
12204 },
12205 [ALC269_ASUS_EEEPC_P901] = {
12206 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12207 .init_verbs = { alc269_init_verbs,
12208 alc269_eeepc_dmic_init_verbs },
12209 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12210 .dac_nids = alc269_dac_nids,
12211 .hp_nid = 0x03,
12212 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12213 .channel_mode = alc269_modes,
12214 .input_mux = &alc269_eeepc_dmic_capture_source,
12215 .unsol_event = alc269_eeepc_dmic_unsol_event,
12216 .init_hook = alc269_eeepc_dmic_inithook,
12217 },
f6a92248
KY
12218};
12219
12220static int patch_alc269(struct hda_codec *codec)
12221{
12222 struct alc_spec *spec;
12223 int board_config;
12224 int err;
12225
12226 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12227 if (spec == NULL)
12228 return -ENOMEM;
12229
12230 codec->spec = spec;
12231
2c3bf9ab
TI
12232 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12233
f6a92248
KY
12234 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12235 alc269_models,
12236 alc269_cfg_tbl);
12237
12238 if (board_config < 0) {
12239 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12240 "trying auto-probe from BIOS...\n");
12241 board_config = ALC269_AUTO;
12242 }
12243
12244 if (board_config == ALC269_AUTO) {
12245 /* automatic parse from the BIOS config */
12246 err = alc269_parse_auto_config(codec);
12247 if (err < 0) {
12248 alc_free(codec);
12249 return err;
12250 } else if (!err) {
12251 printk(KERN_INFO
12252 "hda_codec: Cannot set up configuration "
12253 "from BIOS. Using base mode...\n");
12254 board_config = ALC269_BASIC;
12255 }
12256 }
12257
12258 if (board_config != ALC269_AUTO)
12259 setup_preset(spec, &alc269_presets[board_config]);
12260
12261 spec->stream_name_analog = "ALC269 Analog";
12262 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12263 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12264
12265 spec->stream_name_digital = "ALC269 Digital";
12266 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12267 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12268
12269 spec->adc_nids = alc269_adc_nids;
12270 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 12271 spec->capsrc_nids = alc269_capsrc_nids;
f6a92248
KY
12272
12273 codec->patch_ops = alc_patch_ops;
12274 if (board_config == ALC269_AUTO)
12275 spec->init_hook = alc269_auto_init;
12276#ifdef CONFIG_SND_HDA_POWER_SAVE
12277 if (!spec->loopback.amplist)
12278 spec->loopback.amplist = alc269_loopbacks;
12279#endif
12280
12281 return 0;
12282}
12283
df694daa
KY
12284/*
12285 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12286 */
12287
12288/*
12289 * set the path ways for 2 channel output
12290 * need to set the codec line out and mic 1 pin widgets to inputs
12291 */
12292static struct hda_verb alc861_threestack_ch2_init[] = {
12293 /* set pin widget 1Ah (line in) for input */
12294 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
12295 /* set pin widget 18h (mic1/2) for input, for mic also enable
12296 * the vref
12297 */
df694daa
KY
12298 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12299
9c7f852e
TI
12300 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12301#if 0
12302 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12303 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12304#endif
df694daa
KY
12305 { } /* end */
12306};
12307/*
12308 * 6ch mode
12309 * need to set the codec line out and mic 1 pin widgets to outputs
12310 */
12311static struct hda_verb alc861_threestack_ch6_init[] = {
12312 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12313 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12314 /* set pin widget 18h (mic1) for output (CLFE)*/
12315 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12316
12317 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 12318 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 12319
9c7f852e
TI
12320 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12321#if 0
12322 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12323 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12324#endif
df694daa
KY
12325 { } /* end */
12326};
12327
12328static struct hda_channel_mode alc861_threestack_modes[2] = {
12329 { 2, alc861_threestack_ch2_init },
12330 { 6, alc861_threestack_ch6_init },
12331};
22309c3e
TI
12332/* Set mic1 as input and unmute the mixer */
12333static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12334 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12336 { } /* end */
12337};
12338/* Set mic1 as output and mute mixer */
12339static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12340 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12341 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12342 { } /* end */
12343};
12344
12345static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12346 { 2, alc861_uniwill_m31_ch2_init },
12347 { 4, alc861_uniwill_m31_ch4_init },
12348};
df694daa 12349
7cdbff94
MD
12350/* Set mic1 and line-in as input and unmute the mixer */
12351static struct hda_verb alc861_asus_ch2_init[] = {
12352 /* set pin widget 1Ah (line in) for input */
12353 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
12354 /* set pin widget 18h (mic1/2) for input, for mic also enable
12355 * the vref
12356 */
7cdbff94
MD
12357 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12358
12359 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12360#if 0
12361 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12363#endif
12364 { } /* end */
12365};
12366/* Set mic1 nad line-in as output and mute mixer */
12367static struct hda_verb alc861_asus_ch6_init[] = {
12368 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12369 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12370 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12371 /* set pin widget 18h (mic1) for output (CLFE)*/
12372 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12373 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12374 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12375 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12376
12377 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12378#if 0
12379 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12380 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12381#endif
12382 { } /* end */
12383};
12384
12385static struct hda_channel_mode alc861_asus_modes[2] = {
12386 { 2, alc861_asus_ch2_init },
12387 { 6, alc861_asus_ch6_init },
12388};
12389
df694daa
KY
12390/* patch-ALC861 */
12391
12392static struct snd_kcontrol_new alc861_base_mixer[] = {
12393 /* output mixer control */
12394 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12395 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12396 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12397 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12398 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12399
12400 /*Input mixer control */
12401 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12402 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12403 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12404 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12405 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12406 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12408 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12409 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12410 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 12411
df694daa
KY
12412 /* Capture mixer control */
12413 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12414 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12415 {
12416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12417 .name = "Capture Source",
12418 .count = 1,
12419 .info = alc_mux_enum_info,
12420 .get = alc_mux_enum_get,
12421 .put = alc_mux_enum_put,
12422 },
12423 { } /* end */
12424};
12425
12426static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12427 /* output mixer control */
12428 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12429 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12430 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12431 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12432 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12433
12434 /* Input mixer control */
12435 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12437 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12438 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12439 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12440 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12442 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12443 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 12445
df694daa
KY
12446 /* Capture mixer control */
12447 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12448 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12449 {
12450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12451 .name = "Capture Source",
12452 .count = 1,
12453 .info = alc_mux_enum_info,
12454 .get = alc_mux_enum_get,
12455 .put = alc_mux_enum_put,
12456 },
12457 {
12458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12459 .name = "Channel Mode",
12460 .info = alc_ch_mode_info,
12461 .get = alc_ch_mode_get,
12462 .put = alc_ch_mode_put,
12463 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12464 },
12465 { } /* end */
a53d1aec
TD
12466};
12467
d1d985f0 12468static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
12469 /* output mixer control */
12470 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 12473
a53d1aec
TD
12474 /*Capture mixer control */
12475 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12476 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12477 {
12478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12479 .name = "Capture Source",
12480 .count = 1,
12481 .info = alc_mux_enum_info,
12482 .get = alc_mux_enum_get,
12483 .put = alc_mux_enum_put,
12484 },
12485
12486 { } /* end */
f12ab1e0 12487};
a53d1aec 12488
22309c3e
TI
12489static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12490 /* output mixer control */
12491 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12492 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12493 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12494 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12495 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12496
12497 /* Input mixer control */
12498 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12499 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12500 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12501 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12502 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12503 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12505 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12506 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 12508
22309c3e
TI
12509 /* Capture mixer control */
12510 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12511 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12512 {
12513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12514 .name = "Capture Source",
12515 .count = 1,
12516 .info = alc_mux_enum_info,
12517 .get = alc_mux_enum_get,
12518 .put = alc_mux_enum_put,
12519 },
12520 {
12521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12522 .name = "Channel Mode",
12523 .info = alc_ch_mode_info,
12524 .get = alc_ch_mode_get,
12525 .put = alc_ch_mode_put,
12526 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12527 },
12528 { } /* end */
f12ab1e0 12529};
7cdbff94
MD
12530
12531static struct snd_kcontrol_new alc861_asus_mixer[] = {
12532 /* output mixer control */
12533 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12534 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12535 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12536 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12537 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12538
12539 /* Input mixer control */
12540 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12541 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12542 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12543 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12544 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12545 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12547 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12548 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
12549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12550
7cdbff94
MD
12551 /* Capture mixer control */
12552 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12553 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12554 {
12555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12556 .name = "Capture Source",
12557 .count = 1,
12558 .info = alc_mux_enum_info,
12559 .get = alc_mux_enum_get,
12560 .put = alc_mux_enum_put,
12561 },
12562 {
12563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12564 .name = "Channel Mode",
12565 .info = alc_ch_mode_info,
12566 .get = alc_ch_mode_get,
12567 .put = alc_ch_mode_put,
12568 .private_value = ARRAY_SIZE(alc861_asus_modes),
12569 },
12570 { }
56bb0cab
TI
12571};
12572
12573/* additional mixer */
d1d985f0 12574static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
12575 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12576 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12577 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12578 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12579 { }
12580};
7cdbff94 12581
df694daa
KY
12582/*
12583 * generic initialization of ADC, input mixers and output mixers
12584 */
12585static struct hda_verb alc861_base_init_verbs[] = {
12586 /*
12587 * Unmute ADC0 and set the default input to mic-in
12588 */
12589 /* port-A for surround (rear panel) */
12590 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12591 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12592 /* port-B for mic-in (rear panel) with vref */
12593 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12594 /* port-C for line-in (rear panel) */
12595 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12596 /* port-D for Front */
12597 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12598 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12599 /* port-E for HP out (front panel) */
12600 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12601 /* route front PCM to HP */
9dece1d7 12602 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
12603 /* port-F for mic-in (front panel) with vref */
12604 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12605 /* port-G for CLFE (rear panel) */
12606 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12607 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12608 /* port-H for side (rear panel) */
12609 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12610 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12611 /* CD-in */
12612 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12613 /* route front mic to ADC1*/
12614 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 12616
df694daa
KY
12617 /* Unmute DAC0~3 & spdif out*/
12618 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12619 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12620 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12621 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12623
df694daa
KY
12624 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12625 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12626 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12627 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12628 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12629
df694daa
KY
12630 /* Unmute Stereo Mixer 15 */
12631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
12635
12636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12637 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12638 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12639 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12641 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12644 /* hp used DAC 3 (Front) */
12645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
12646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12647
12648 { }
12649};
12650
12651static struct hda_verb alc861_threestack_init_verbs[] = {
12652 /*
12653 * Unmute ADC0 and set the default input to mic-in
12654 */
12655 /* port-A for surround (rear panel) */
12656 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12657 /* port-B for mic-in (rear panel) with vref */
12658 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12659 /* port-C for line-in (rear panel) */
12660 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12661 /* port-D for Front */
12662 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12663 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12664 /* port-E for HP out (front panel) */
12665 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12666 /* route front PCM to HP */
9dece1d7 12667 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
12668 /* port-F for mic-in (front panel) with vref */
12669 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12670 /* port-G for CLFE (rear panel) */
12671 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12672 /* port-H for side (rear panel) */
12673 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12674 /* CD-in */
12675 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12676 /* route front mic to ADC1*/
12677 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12678 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12679 /* Unmute DAC0~3 & spdif out*/
12680 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12681 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12682 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12683 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12685
df694daa
KY
12686 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12687 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12688 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12689 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12690 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12691
df694daa
KY
12692 /* Unmute Stereo Mixer 15 */
12693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
12697
12698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12701 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12702 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12705 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12706 /* hp used DAC 3 (Front) */
12707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
12708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12709 { }
12710};
22309c3e
TI
12711
12712static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12713 /*
12714 * Unmute ADC0 and set the default input to mic-in
12715 */
12716 /* port-A for surround (rear panel) */
12717 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12718 /* port-B for mic-in (rear panel) with vref */
12719 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12720 /* port-C for line-in (rear panel) */
12721 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12722 /* port-D for Front */
12723 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12724 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12725 /* port-E for HP out (front panel) */
f12ab1e0
TI
12726 /* this has to be set to VREF80 */
12727 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 12728 /* route front PCM to HP */
9dece1d7 12729 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
12730 /* port-F for mic-in (front panel) with vref */
12731 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12732 /* port-G for CLFE (rear panel) */
12733 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12734 /* port-H for side (rear panel) */
12735 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12736 /* CD-in */
12737 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12738 /* route front mic to ADC1*/
12739 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12740 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12741 /* Unmute DAC0~3 & spdif out*/
12742 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12743 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12744 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12745 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12747
22309c3e
TI
12748 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12749 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12750 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12751 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12752 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12753
22309c3e
TI
12754 /* Unmute Stereo Mixer 15 */
12755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
12759
12760 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12761 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12762 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12763 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12764 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12767 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12768 /* hp used DAC 3 (Front) */
12769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
12770 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12771 { }
12772};
12773
7cdbff94
MD
12774static struct hda_verb alc861_asus_init_verbs[] = {
12775 /*
12776 * Unmute ADC0 and set the default input to mic-in
12777 */
f12ab1e0
TI
12778 /* port-A for surround (rear panel)
12779 * according to codec#0 this is the HP jack
12780 */
7cdbff94
MD
12781 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12782 /* route front PCM to HP */
12783 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12784 /* port-B for mic-in (rear panel) with vref */
12785 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12786 /* port-C for line-in (rear panel) */
12787 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12788 /* port-D for Front */
12789 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12790 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12791 /* port-E for HP out (front panel) */
f12ab1e0
TI
12792 /* this has to be set to VREF80 */
12793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 12794 /* route front PCM to HP */
9dece1d7 12795 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
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 /* port-H for side (rear panel) */
12801 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12802 /* CD-in */
12803 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12804 /* route front mic to ADC1*/
12805 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12806 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12807 /* Unmute DAC0~3 & spdif out*/
12808 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12809 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12810 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12811 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12813 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12814 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12815 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12816 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12817 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12818
7cdbff94
MD
12819 /* Unmute Stereo Mixer 15 */
12820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
12824
12825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12829 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12833 /* hp used DAC 3 (Front) */
12834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
12835 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12836 { }
12837};
12838
56bb0cab
TI
12839/* additional init verbs for ASUS laptops */
12840static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12841 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12842 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12843 { }
12844};
7cdbff94 12845
df694daa
KY
12846/*
12847 * generic initialization of ADC, input mixers and output mixers
12848 */
12849static struct hda_verb alc861_auto_init_verbs[] = {
12850 /*
12851 * Unmute ADC0 and set the default input to mic-in
12852 */
f12ab1e0 12853 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 12854 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 12855
df694daa
KY
12856 /* Unmute DAC0~3 & spdif out*/
12857 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12858 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12859 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12860 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12862
df694daa
KY
12863 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12864 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12865 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12866 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12867 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12868
df694daa
KY
12869 /* Unmute Stereo Mixer 15 */
12870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12874
12875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12876 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12877 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12878 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12880 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12882 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12883
12884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
12886 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12887 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
12888 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12889 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
12890 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12891 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 12892
f12ab1e0 12893 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
12894
12895 { }
12896};
12897
a53d1aec
TD
12898static struct hda_verb alc861_toshiba_init_verbs[] = {
12899 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 12900
a53d1aec
TD
12901 { }
12902};
12903
12904/* toggle speaker-output according to the hp-jack state */
12905static void alc861_toshiba_automute(struct hda_codec *codec)
12906{
12907 unsigned int present;
12908
12909 present = snd_hda_codec_read(codec, 0x0f, 0,
12910 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12911 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12912 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12913 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12914 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
12915}
12916
12917static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12918 unsigned int res)
12919{
a53d1aec
TD
12920 if ((res >> 26) == ALC880_HP_EVENT)
12921 alc861_toshiba_automute(codec);
12922}
12923
df694daa
KY
12924/* pcm configuration: identiacal with ALC880 */
12925#define alc861_pcm_analog_playback alc880_pcm_analog_playback
12926#define alc861_pcm_analog_capture alc880_pcm_analog_capture
12927#define alc861_pcm_digital_playback alc880_pcm_digital_playback
12928#define alc861_pcm_digital_capture alc880_pcm_digital_capture
12929
12930
12931#define ALC861_DIGOUT_NID 0x07
12932
12933static struct hda_channel_mode alc861_8ch_modes[1] = {
12934 { 8, NULL }
12935};
12936
12937static hda_nid_t alc861_dac_nids[4] = {
12938 /* front, surround, clfe, side */
12939 0x03, 0x06, 0x05, 0x04
12940};
12941
9c7f852e
TI
12942static hda_nid_t alc660_dac_nids[3] = {
12943 /* front, clfe, surround */
12944 0x03, 0x05, 0x06
12945};
12946
df694daa
KY
12947static hda_nid_t alc861_adc_nids[1] = {
12948 /* ADC0-2 */
12949 0x08,
12950};
12951
12952static struct hda_input_mux alc861_capture_source = {
12953 .num_items = 5,
12954 .items = {
12955 { "Mic", 0x0 },
12956 { "Front Mic", 0x3 },
12957 { "Line", 0x1 },
12958 { "CD", 0x4 },
12959 { "Mixer", 0x5 },
12960 },
12961};
12962
12963/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
12964static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12965 const struct auto_pin_cfg *cfg)
df694daa
KY
12966{
12967 int i;
12968 hda_nid_t nid;
12969
12970 spec->multiout.dac_nids = spec->private_dac_nids;
12971 for (i = 0; i < cfg->line_outs; i++) {
12972 nid = cfg->line_out_pins[i];
12973 if (nid) {
12974 if (i >= ARRAY_SIZE(alc861_dac_nids))
12975 continue;
12976 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12977 }
12978 }
12979 spec->multiout.num_dacs = cfg->line_outs;
12980 return 0;
12981}
12982
12983/* add playback controls from the parsed DAC table */
12984static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12985 const struct auto_pin_cfg *cfg)
12986{
12987 char name[32];
f12ab1e0
TI
12988 static const char *chname[4] = {
12989 "Front", "Surround", NULL /*CLFE*/, "Side"
12990 };
df694daa
KY
12991 hda_nid_t nid;
12992 int i, idx, err;
12993
12994 for (i = 0; i < cfg->line_outs; i++) {
12995 nid = spec->multiout.dac_nids[i];
f12ab1e0 12996 if (!nid)
df694daa
KY
12997 continue;
12998 if (nid == 0x05) {
12999 /* Center/LFE */
f12ab1e0
TI
13000 err = add_control(spec, ALC_CTL_BIND_MUTE,
13001 "Center Playback Switch",
13002 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13003 HDA_OUTPUT));
13004 if (err < 0)
df694daa 13005 return err;
f12ab1e0
TI
13006 err = add_control(spec, ALC_CTL_BIND_MUTE,
13007 "LFE Playback Switch",
13008 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13009 HDA_OUTPUT));
13010 if (err < 0)
df694daa
KY
13011 return err;
13012 } else {
f12ab1e0
TI
13013 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13014 idx++)
df694daa
KY
13015 if (nid == alc861_dac_nids[idx])
13016 break;
13017 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
13018 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13019 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13020 HDA_OUTPUT));
13021 if (err < 0)
df694daa
KY
13022 return err;
13023 }
13024 }
13025 return 0;
13026}
13027
13028static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13029{
13030 int err;
13031 hda_nid_t nid;
13032
f12ab1e0 13033 if (!pin)
df694daa
KY
13034 return 0;
13035
13036 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13037 nid = 0x03;
f12ab1e0
TI
13038 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13039 "Headphone Playback Switch",
13040 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13041 if (err < 0)
df694daa
KY
13042 return err;
13043 spec->multiout.hp_nid = nid;
13044 }
13045 return 0;
13046}
13047
13048/* create playback/capture controls for input pins */
f12ab1e0
TI
13049static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13050 const struct auto_pin_cfg *cfg)
df694daa 13051{
df694daa
KY
13052 struct hda_input_mux *imux = &spec->private_imux;
13053 int i, err, idx, idx1;
13054
13055 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 13056 switch (cfg->input_pins[i]) {
df694daa
KY
13057 case 0x0c:
13058 idx1 = 1;
f12ab1e0 13059 idx = 2; /* Line In */
df694daa
KY
13060 break;
13061 case 0x0f:
13062 idx1 = 2;
f12ab1e0 13063 idx = 2; /* Line In */
df694daa
KY
13064 break;
13065 case 0x0d:
13066 idx1 = 0;
f12ab1e0 13067 idx = 1; /* Mic In */
df694daa 13068 break;
f12ab1e0 13069 case 0x10:
df694daa 13070 idx1 = 3;
f12ab1e0 13071 idx = 1; /* Mic In */
df694daa
KY
13072 break;
13073 case 0x11:
13074 idx1 = 4;
f12ab1e0 13075 idx = 0; /* CD */
df694daa
KY
13076 break;
13077 default:
13078 continue;
13079 }
13080
4a471b7d
TI
13081 err = new_analog_input(spec, cfg->input_pins[i],
13082 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
13083 if (err < 0)
13084 return err;
13085
4a471b7d 13086 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 13087 imux->items[imux->num_items].index = idx1;
f12ab1e0 13088 imux->num_items++;
df694daa
KY
13089 }
13090 return 0;
13091}
13092
13093static struct snd_kcontrol_new alc861_capture_mixer[] = {
13094 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13095 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13096
13097 {
13098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13099 /* The multiple "Capture Source" controls confuse alsamixer
13100 * So call somewhat different..
df694daa
KY
13101 */
13102 /* .name = "Capture Source", */
13103 .name = "Input Source",
13104 .count = 1,
13105 .info = alc_mux_enum_info,
13106 .get = alc_mux_enum_get,
13107 .put = alc_mux_enum_put,
13108 },
13109 { } /* end */
13110};
13111
f12ab1e0
TI
13112static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13113 hda_nid_t nid,
df694daa
KY
13114 int pin_type, int dac_idx)
13115{
564c5bea
JL
13116 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13117 pin_type);
13118 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13119 AMP_OUT_UNMUTE);
df694daa
KY
13120}
13121
13122static void alc861_auto_init_multi_out(struct hda_codec *codec)
13123{
13124 struct alc_spec *spec = codec->spec;
13125 int i;
13126
bc9f98a9 13127 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
13128 for (i = 0; i < spec->autocfg.line_outs; i++) {
13129 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13130 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 13131 if (nid)
baba8ee9 13132 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 13133 spec->multiout.dac_nids[i]);
df694daa
KY
13134 }
13135}
13136
13137static void alc861_auto_init_hp_out(struct hda_codec *codec)
13138{
13139 struct alc_spec *spec = codec->spec;
13140 hda_nid_t pin;
13141
eb06ed8f 13142 pin = spec->autocfg.hp_pins[0];
df694daa 13143 if (pin) /* connect to front */
f12ab1e0
TI
13144 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13145 spec->multiout.dac_nids[0]);
f6c7e546
TI
13146 pin = spec->autocfg.speaker_pins[0];
13147 if (pin)
13148 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
13149}
13150
13151static void alc861_auto_init_analog_input(struct hda_codec *codec)
13152{
13153 struct alc_spec *spec = codec->spec;
13154 int i;
13155
13156 for (i = 0; i < AUTO_PIN_LAST; i++) {
13157 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
13158 if (nid >= 0x0c && nid <= 0x11) {
13159 snd_hda_codec_write(codec, nid, 0,
13160 AC_VERB_SET_PIN_WIDGET_CONTROL,
13161 i <= AUTO_PIN_FRONT_MIC ?
13162 PIN_VREF80 : PIN_IN);
df694daa
KY
13163 }
13164 }
13165}
13166
13167/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
13168/* return 1 if successful, 0 if the proper config is not found,
13169 * or a negative error code
13170 */
df694daa
KY
13171static int alc861_parse_auto_config(struct hda_codec *codec)
13172{
13173 struct alc_spec *spec = codec->spec;
13174 int err;
13175 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13176
f12ab1e0
TI
13177 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13178 alc861_ignore);
13179 if (err < 0)
df694daa 13180 return err;
f12ab1e0 13181 if (!spec->autocfg.line_outs)
df694daa
KY
13182 return 0; /* can't find valid BIOS pin config */
13183
f12ab1e0
TI
13184 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13185 if (err < 0)
13186 return err;
13187 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13188 if (err < 0)
13189 return err;
13190 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13191 if (err < 0)
13192 return err;
13193 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13194 if (err < 0)
df694daa
KY
13195 return err;
13196
13197 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13198
13199 if (spec->autocfg.dig_out_pin)
13200 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13201
13202 if (spec->kctl_alloc)
13203 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13204
13205 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13206
a1e8d2da 13207 spec->num_mux_defs = 1;
df694daa
KY
13208 spec->input_mux = &spec->private_imux;
13209
13210 spec->adc_nids = alc861_adc_nids;
13211 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13212 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13213 spec->num_mixers++;
13214
13215 return 1;
13216}
13217
ae6b813a
TI
13218/* additional initialization for auto-configuration model */
13219static void alc861_auto_init(struct hda_codec *codec)
df694daa 13220{
f6c7e546 13221 struct alc_spec *spec = codec->spec;
df694daa
KY
13222 alc861_auto_init_multi_out(codec);
13223 alc861_auto_init_hp_out(codec);
13224 alc861_auto_init_analog_input(codec);
f6c7e546
TI
13225 if (spec->unsol_event)
13226 alc_sku_automute(codec);
df694daa
KY
13227}
13228
cb53c626
TI
13229#ifdef CONFIG_SND_HDA_POWER_SAVE
13230static struct hda_amp_list alc861_loopbacks[] = {
13231 { 0x15, HDA_INPUT, 0 },
13232 { 0x15, HDA_INPUT, 1 },
13233 { 0x15, HDA_INPUT, 2 },
13234 { 0x15, HDA_INPUT, 3 },
13235 { } /* end */
13236};
13237#endif
13238
df694daa
KY
13239
13240/*
13241 * configuration and preset
13242 */
f5fcc13c
TI
13243static const char *alc861_models[ALC861_MODEL_LAST] = {
13244 [ALC861_3ST] = "3stack",
13245 [ALC660_3ST] = "3stack-660",
13246 [ALC861_3ST_DIG] = "3stack-dig",
13247 [ALC861_6ST_DIG] = "6stack-dig",
13248 [ALC861_UNIWILL_M31] = "uniwill-m31",
13249 [ALC861_TOSHIBA] = "toshiba",
13250 [ALC861_ASUS] = "asus",
13251 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13252 [ALC861_AUTO] = "auto",
13253};
13254
13255static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 13256 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
13257 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13258 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13259 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 13260 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 13261 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 13262 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
13263 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13264 * Any other models that need this preset?
13265 */
13266 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
13267 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13268 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 13269 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
13270 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13271 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13272 /* FIXME: the below seems conflict */
13273 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 13274 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 13275 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
13276 {}
13277};
13278
13279static struct alc_config_preset alc861_presets[] = {
13280 [ALC861_3ST] = {
13281 .mixers = { alc861_3ST_mixer },
13282 .init_verbs = { alc861_threestack_init_verbs },
13283 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13284 .dac_nids = alc861_dac_nids,
13285 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13286 .channel_mode = alc861_threestack_modes,
4e195a7b 13287 .need_dac_fix = 1,
df694daa
KY
13288 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13289 .adc_nids = alc861_adc_nids,
13290 .input_mux = &alc861_capture_source,
13291 },
13292 [ALC861_3ST_DIG] = {
13293 .mixers = { alc861_base_mixer },
13294 .init_verbs = { alc861_threestack_init_verbs },
13295 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13296 .dac_nids = alc861_dac_nids,
13297 .dig_out_nid = ALC861_DIGOUT_NID,
13298 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13299 .channel_mode = alc861_threestack_modes,
4e195a7b 13300 .need_dac_fix = 1,
df694daa
KY
13301 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13302 .adc_nids = alc861_adc_nids,
13303 .input_mux = &alc861_capture_source,
13304 },
13305 [ALC861_6ST_DIG] = {
13306 .mixers = { alc861_base_mixer },
13307 .init_verbs = { alc861_base_init_verbs },
13308 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13309 .dac_nids = alc861_dac_nids,
13310 .dig_out_nid = ALC861_DIGOUT_NID,
13311 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13312 .channel_mode = alc861_8ch_modes,
13313 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13314 .adc_nids = alc861_adc_nids,
13315 .input_mux = &alc861_capture_source,
13316 },
9c7f852e
TI
13317 [ALC660_3ST] = {
13318 .mixers = { alc861_3ST_mixer },
13319 .init_verbs = { alc861_threestack_init_verbs },
13320 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13321 .dac_nids = alc660_dac_nids,
13322 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13323 .channel_mode = alc861_threestack_modes,
4e195a7b 13324 .need_dac_fix = 1,
9c7f852e
TI
13325 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13326 .adc_nids = alc861_adc_nids,
13327 .input_mux = &alc861_capture_source,
13328 },
22309c3e
TI
13329 [ALC861_UNIWILL_M31] = {
13330 .mixers = { alc861_uniwill_m31_mixer },
13331 .init_verbs = { alc861_uniwill_m31_init_verbs },
13332 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13333 .dac_nids = alc861_dac_nids,
13334 .dig_out_nid = ALC861_DIGOUT_NID,
13335 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13336 .channel_mode = alc861_uniwill_m31_modes,
13337 .need_dac_fix = 1,
13338 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13339 .adc_nids = alc861_adc_nids,
13340 .input_mux = &alc861_capture_source,
13341 },
a53d1aec
TD
13342 [ALC861_TOSHIBA] = {
13343 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
13344 .init_verbs = { alc861_base_init_verbs,
13345 alc861_toshiba_init_verbs },
a53d1aec
TD
13346 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13347 .dac_nids = alc861_dac_nids,
13348 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13349 .channel_mode = alc883_3ST_2ch_modes,
13350 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13351 .adc_nids = alc861_adc_nids,
13352 .input_mux = &alc861_capture_source,
13353 .unsol_event = alc861_toshiba_unsol_event,
13354 .init_hook = alc861_toshiba_automute,
13355 },
7cdbff94
MD
13356 [ALC861_ASUS] = {
13357 .mixers = { alc861_asus_mixer },
13358 .init_verbs = { alc861_asus_init_verbs },
13359 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13360 .dac_nids = alc861_dac_nids,
13361 .dig_out_nid = ALC861_DIGOUT_NID,
13362 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13363 .channel_mode = alc861_asus_modes,
13364 .need_dac_fix = 1,
13365 .hp_nid = 0x06,
13366 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13367 .adc_nids = alc861_adc_nids,
13368 .input_mux = &alc861_capture_source,
13369 },
56bb0cab
TI
13370 [ALC861_ASUS_LAPTOP] = {
13371 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13372 .init_verbs = { alc861_asus_init_verbs,
13373 alc861_asus_laptop_init_verbs },
13374 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13375 .dac_nids = alc861_dac_nids,
13376 .dig_out_nid = ALC861_DIGOUT_NID,
13377 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13378 .channel_mode = alc883_3ST_2ch_modes,
13379 .need_dac_fix = 1,
13380 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13381 .adc_nids = alc861_adc_nids,
13382 .input_mux = &alc861_capture_source,
13383 },
13384};
df694daa
KY
13385
13386
13387static int patch_alc861(struct hda_codec *codec)
13388{
13389 struct alc_spec *spec;
13390 int board_config;
13391 int err;
13392
dc041e0b 13393 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
13394 if (spec == NULL)
13395 return -ENOMEM;
13396
f12ab1e0 13397 codec->spec = spec;
df694daa 13398
f5fcc13c
TI
13399 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13400 alc861_models,
13401 alc861_cfg_tbl);
9c7f852e 13402
f5fcc13c 13403 if (board_config < 0) {
9c7f852e
TI
13404 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13405 "trying auto-probe from BIOS...\n");
df694daa
KY
13406 board_config = ALC861_AUTO;
13407 }
13408
13409 if (board_config == ALC861_AUTO) {
13410 /* automatic parse from the BIOS config */
13411 err = alc861_parse_auto_config(codec);
13412 if (err < 0) {
13413 alc_free(codec);
13414 return err;
f12ab1e0 13415 } else if (!err) {
9c7f852e
TI
13416 printk(KERN_INFO
13417 "hda_codec: Cannot set up configuration "
13418 "from BIOS. Using base mode...\n");
df694daa
KY
13419 board_config = ALC861_3ST_DIG;
13420 }
13421 }
13422
13423 if (board_config != ALC861_AUTO)
13424 setup_preset(spec, &alc861_presets[board_config]);
13425
13426 spec->stream_name_analog = "ALC861 Analog";
13427 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13428 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13429
13430 spec->stream_name_digital = "ALC861 Digital";
13431 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13432 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13433
2134ea4f
TI
13434 spec->vmaster_nid = 0x03;
13435
df694daa
KY
13436 codec->patch_ops = alc_patch_ops;
13437 if (board_config == ALC861_AUTO)
ae6b813a 13438 spec->init_hook = alc861_auto_init;
cb53c626
TI
13439#ifdef CONFIG_SND_HDA_POWER_SAVE
13440 if (!spec->loopback.amplist)
13441 spec->loopback.amplist = alc861_loopbacks;
13442#endif
ea1fb29a 13443
1da177e4
LT
13444 return 0;
13445}
13446
f32610ed
JS
13447/*
13448 * ALC861-VD support
13449 *
13450 * Based on ALC882
13451 *
13452 * In addition, an independent DAC
13453 */
13454#define ALC861VD_DIGOUT_NID 0x06
13455
13456static hda_nid_t alc861vd_dac_nids[4] = {
13457 /* front, surr, clfe, side surr */
13458 0x02, 0x03, 0x04, 0x05
13459};
13460
13461/* dac_nids for ALC660vd are in a different order - according to
13462 * Realtek's driver.
13463 * This should probably tesult in a different mixer for 6stack models
13464 * of ALC660vd codecs, but for now there is only 3stack mixer
13465 * - and it is the same as in 861vd.
13466 * adc_nids in ALC660vd are (is) the same as in 861vd
13467 */
13468static hda_nid_t alc660vd_dac_nids[3] = {
13469 /* front, rear, clfe, rear_surr */
13470 0x02, 0x04, 0x03
13471};
13472
13473static hda_nid_t alc861vd_adc_nids[1] = {
13474 /* ADC0 */
13475 0x09,
13476};
13477
e1406348
TI
13478static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13479
f32610ed
JS
13480/* input MUX */
13481/* FIXME: should be a matrix-type input source selection */
13482static struct hda_input_mux alc861vd_capture_source = {
13483 .num_items = 4,
13484 .items = {
13485 { "Mic", 0x0 },
13486 { "Front Mic", 0x1 },
13487 { "Line", 0x2 },
13488 { "CD", 0x4 },
13489 },
13490};
13491
272a527c 13492static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 13493 .num_items = 2,
272a527c 13494 .items = {
b419f346
TD
13495 { "Ext Mic", 0x0 },
13496 { "Int Mic", 0x1 },
272a527c
KY
13497 },
13498};
13499
d1a991a6
KY
13500static struct hda_input_mux alc861vd_hp_capture_source = {
13501 .num_items = 2,
13502 .items = {
13503 { "Front Mic", 0x0 },
13504 { "ATAPI Mic", 0x1 },
13505 },
13506};
13507
f32610ed
JS
13508#define alc861vd_mux_enum_info alc_mux_enum_info
13509#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
13510/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13511#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
13512
13513/*
13514 * 2ch mode
13515 */
13516static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13517 { 2, NULL }
13518};
13519
13520/*
13521 * 6ch mode
13522 */
13523static struct hda_verb alc861vd_6stack_ch6_init[] = {
13524 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13525 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13526 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13527 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13528 { } /* end */
13529};
13530
13531/*
13532 * 8ch mode
13533 */
13534static struct hda_verb alc861vd_6stack_ch8_init[] = {
13535 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13536 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13537 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13538 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13539 { } /* end */
13540};
13541
13542static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13543 { 6, alc861vd_6stack_ch6_init },
13544 { 8, alc861vd_6stack_ch8_init },
13545};
13546
13547static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13548 {
13549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13550 .name = "Channel Mode",
13551 .info = alc_ch_mode_info,
13552 .get = alc_ch_mode_get,
13553 .put = alc_ch_mode_put,
13554 },
13555 { } /* end */
13556};
13557
13558static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13559 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13560 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13561
13562 {
13563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13564 /* The multiple "Capture Source" controls confuse alsamixer
13565 * So call somewhat different..
f32610ed
JS
13566 */
13567 /* .name = "Capture Source", */
13568 .name = "Input Source",
13569 .count = 1,
13570 .info = alc861vd_mux_enum_info,
13571 .get = alc861vd_mux_enum_get,
13572 .put = alc861vd_mux_enum_put,
13573 },
13574 { } /* end */
13575};
13576
13577/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13578 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13579 */
13580static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13581 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13582 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13583
13584 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13585 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13586
13587 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13588 HDA_OUTPUT),
13589 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13590 HDA_OUTPUT),
13591 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13592 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13593
13594 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13595 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13596
13597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13598
13599 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13602
13603 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13604 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13605 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13606
13607 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13608 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13609
13610 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13611 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13612
13613 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13614 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13615
13616 { } /* end */
13617};
13618
13619static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13620 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13621 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13622
13623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13624
13625 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13628
13629 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13632
13633 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13634 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13635
13636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13638
13639 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13640 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13641
13642 { } /* end */
13643};
13644
bdd148a3
KY
13645static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13646 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13647 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13648 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13649
13650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13651
13652 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13654 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13655
13656 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13659
13660 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13661 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13662
13663 { } /* end */
13664};
13665
b419f346
TD
13666/* Pin assignment: Speaker=0x14, HP = 0x15,
13667 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
13668 */
13669static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
13670 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13671 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
13672 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13673 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
13674 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13675 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13676 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13677 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13678 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13679 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13680 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13681 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
13682 { } /* end */
13683};
13684
d1a991a6
KY
13685/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13686 * Front Mic=0x18, ATAPI Mic = 0x19,
13687 */
13688static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13689 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13690 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13691 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13692 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13694 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 13697
d1a991a6
KY
13698 { } /* end */
13699};
13700
f32610ed
JS
13701/*
13702 * generic initialization of ADC, input mixers and output mixers
13703 */
13704static struct hda_verb alc861vd_volume_init_verbs[] = {
13705 /*
13706 * Unmute ADC0 and set the default input to mic-in
13707 */
13708 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13709 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13710
13711 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13712 * the analog-loopback mixer widget
13713 */
13714 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
13720
13721 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
13722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 13725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
13726
13727 /*
13728 * Set up output mixers (0x02 - 0x05)
13729 */
13730 /* set vol=0 to output mixers */
13731 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13732 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13733 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13734 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13735
13736 /* set up input amps for analog loopback */
13737 /* Amp Indices: DAC = 0, mixer = 1 */
13738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13743 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13746
13747 { }
13748};
13749
13750/*
13751 * 3-stack pin configuration:
13752 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13753 */
13754static struct hda_verb alc861vd_3stack_init_verbs[] = {
13755 /*
13756 * Set pin mode and muting
13757 */
13758 /* set front pin widgets 0x14 for output */
13759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13761 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13762
13763 /* Mic (rear) pin: input vref at 80% */
13764 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13766 /* Front Mic pin: input vref at 80% */
13767 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13768 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13769 /* Line In pin: input */
13770 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13771 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13772 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13773 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13774 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13776 /* CD pin widget for input */
13777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13778
13779 { }
13780};
13781
13782/*
13783 * 6-stack pin configuration:
13784 */
13785static struct hda_verb alc861vd_6stack_init_verbs[] = {
13786 /*
13787 * Set pin mode and muting
13788 */
13789 /* set front pin widgets 0x14 for output */
13790 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13791 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13792 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13793
13794 /* Rear Pin: output 1 (0x0d) */
13795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13798 /* CLFE Pin: output 2 (0x0e) */
13799 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13801 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13802 /* Side Pin: output 3 (0x0f) */
13803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13805 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13806
13807 /* Mic (rear) pin: input vref at 80% */
13808 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13809 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13810 /* Front Mic pin: input vref at 80% */
13811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13812 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13813 /* Line In pin: input */
13814 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13815 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13816 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13819 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13820 /* CD pin widget for input */
13821 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13822
13823 { }
13824};
13825
bdd148a3
KY
13826static struct hda_verb alc861vd_eapd_verbs[] = {
13827 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13828 { }
13829};
13830
f9423e7a
KY
13831static struct hda_verb alc660vd_eapd_verbs[] = {
13832 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13833 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13834 { }
13835};
13836
bdd148a3
KY
13837static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13841 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 13842 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
13843 {}
13844};
13845
13846/* toggle speaker-output according to the hp-jack state */
13847static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13848{
13849 unsigned int present;
13850 unsigned char bits;
13851
13852 present = snd_hda_codec_read(codec, 0x1b, 0,
13853 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13854 bits = present ? HDA_AMP_MUTE : 0;
13855 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13856 HDA_AMP_MUTE, bits);
bdd148a3
KY
13857}
13858
13859static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13860{
13861 unsigned int present;
13862 unsigned char bits;
13863
13864 present = snd_hda_codec_read(codec, 0x18, 0,
13865 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13866 bits = present ? HDA_AMP_MUTE : 0;
13867 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13868 HDA_AMP_MUTE, bits);
bdd148a3
KY
13869}
13870
13871static void alc861vd_lenovo_automute(struct hda_codec *codec)
13872{
13873 alc861vd_lenovo_hp_automute(codec);
13874 alc861vd_lenovo_mic_automute(codec);
13875}
13876
13877static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13878 unsigned int res)
13879{
13880 switch (res >> 26) {
13881 case ALC880_HP_EVENT:
13882 alc861vd_lenovo_hp_automute(codec);
13883 break;
13884 case ALC880_MIC_EVENT:
13885 alc861vd_lenovo_mic_automute(codec);
13886 break;
13887 }
13888}
13889
272a527c
KY
13890static struct hda_verb alc861vd_dallas_verbs[] = {
13891 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13892 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13893 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13894 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13895
13896 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13897 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13898 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13899 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13900 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13901 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13902 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13903 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 13904
272a527c
KY
13905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13906 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13909 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13910 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13911 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13912 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13913
13914 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13917 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13918 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13920 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13921 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13922
13923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13924 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13925 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13927
13928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 13929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
13930 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13931
13932 { } /* end */
13933};
13934
13935/* toggle speaker-output according to the hp-jack state */
13936static void alc861vd_dallas_automute(struct hda_codec *codec)
13937{
13938 unsigned int present;
13939
13940 present = snd_hda_codec_read(codec, 0x15, 0,
13941 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13942 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13943 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
13944}
13945
13946static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13947{
13948 if ((res >> 26) == ALC880_HP_EVENT)
13949 alc861vd_dallas_automute(codec);
13950}
13951
cb53c626
TI
13952#ifdef CONFIG_SND_HDA_POWER_SAVE
13953#define alc861vd_loopbacks alc880_loopbacks
13954#endif
13955
f32610ed
JS
13956/* pcm configuration: identiacal with ALC880 */
13957#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
13958#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
13959#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
13960#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
13961
13962/*
13963 * configuration and preset
13964 */
13965static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13966 [ALC660VD_3ST] = "3stack-660",
983f8ae4 13967 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
13968 [ALC861VD_3ST] = "3stack",
13969 [ALC861VD_3ST_DIG] = "3stack-digout",
13970 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 13971 [ALC861VD_LENOVO] = "lenovo",
272a527c 13972 [ALC861VD_DALLAS] = "dallas",
983f8ae4 13973 [ALC861VD_HP] = "hp",
f32610ed
JS
13974 [ALC861VD_AUTO] = "auto",
13975};
13976
13977static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
13978 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13979 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 13980 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 13981 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
2522d735 13982 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
6963f84c 13983 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 13984 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 13985 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 13986 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 13987 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 13988 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 13989 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 13990 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
13991 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13992 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
be321a89 13993 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
625dc0bf 13994 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
13995 {}
13996};
13997
13998static struct alc_config_preset alc861vd_presets[] = {
13999 [ALC660VD_3ST] = {
14000 .mixers = { alc861vd_3st_mixer },
14001 .init_verbs = { alc861vd_volume_init_verbs,
14002 alc861vd_3stack_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14004 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14005 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14006 .channel_mode = alc861vd_3stack_2ch_modes,
14007 .input_mux = &alc861vd_capture_source,
14008 },
6963f84c
MC
14009 [ALC660VD_3ST_DIG] = {
14010 .mixers = { alc861vd_3st_mixer },
14011 .init_verbs = { alc861vd_volume_init_verbs,
14012 alc861vd_3stack_init_verbs },
14013 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14014 .dac_nids = alc660vd_dac_nids,
14015 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14016 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14017 .channel_mode = alc861vd_3stack_2ch_modes,
14018 .input_mux = &alc861vd_capture_source,
14019 },
f32610ed
JS
14020 [ALC861VD_3ST] = {
14021 .mixers = { alc861vd_3st_mixer },
14022 .init_verbs = { alc861vd_volume_init_verbs,
14023 alc861vd_3stack_init_verbs },
14024 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14025 .dac_nids = alc861vd_dac_nids,
14026 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14027 .channel_mode = alc861vd_3stack_2ch_modes,
14028 .input_mux = &alc861vd_capture_source,
14029 },
14030 [ALC861VD_3ST_DIG] = {
14031 .mixers = { alc861vd_3st_mixer },
14032 .init_verbs = { alc861vd_volume_init_verbs,
14033 alc861vd_3stack_init_verbs },
14034 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14035 .dac_nids = alc861vd_dac_nids,
14036 .dig_out_nid = ALC861VD_DIGOUT_NID,
14037 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14038 .channel_mode = alc861vd_3stack_2ch_modes,
14039 .input_mux = &alc861vd_capture_source,
14040 },
14041 [ALC861VD_6ST_DIG] = {
14042 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14043 .init_verbs = { alc861vd_volume_init_verbs,
14044 alc861vd_6stack_init_verbs },
14045 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14046 .dac_nids = alc861vd_dac_nids,
14047 .dig_out_nid = ALC861VD_DIGOUT_NID,
14048 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14049 .channel_mode = alc861vd_6stack_modes,
14050 .input_mux = &alc861vd_capture_source,
14051 },
bdd148a3
KY
14052 [ALC861VD_LENOVO] = {
14053 .mixers = { alc861vd_lenovo_mixer },
14054 .init_verbs = { alc861vd_volume_init_verbs,
14055 alc861vd_3stack_init_verbs,
14056 alc861vd_eapd_verbs,
14057 alc861vd_lenovo_unsol_verbs },
14058 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14059 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14060 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14061 .channel_mode = alc861vd_3stack_2ch_modes,
14062 .input_mux = &alc861vd_capture_source,
14063 .unsol_event = alc861vd_lenovo_unsol_event,
14064 .init_hook = alc861vd_lenovo_automute,
14065 },
272a527c
KY
14066 [ALC861VD_DALLAS] = {
14067 .mixers = { alc861vd_dallas_mixer },
14068 .init_verbs = { alc861vd_dallas_verbs },
14069 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14070 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14071 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14072 .channel_mode = alc861vd_3stack_2ch_modes,
14073 .input_mux = &alc861vd_dallas_capture_source,
14074 .unsol_event = alc861vd_dallas_unsol_event,
14075 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
14076 },
14077 [ALC861VD_HP] = {
14078 .mixers = { alc861vd_hp_mixer },
14079 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14080 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14081 .dac_nids = alc861vd_dac_nids,
d1a991a6 14082 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
14083 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14084 .channel_mode = alc861vd_3stack_2ch_modes,
14085 .input_mux = &alc861vd_hp_capture_source,
14086 .unsol_event = alc861vd_dallas_unsol_event,
14087 .init_hook = alc861vd_dallas_automute,
ea1fb29a 14088 },
f32610ed
JS
14089};
14090
14091/*
14092 * BIOS auto configuration
14093 */
14094static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14095 hda_nid_t nid, int pin_type, int dac_idx)
14096{
f6c7e546 14097 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
14098}
14099
14100static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14101{
14102 struct alc_spec *spec = codec->spec;
14103 int i;
14104
bc9f98a9 14105 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
14106 for (i = 0; i <= HDA_SIDE; i++) {
14107 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14108 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
14109 if (nid)
14110 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 14111 pin_type, i);
f32610ed
JS
14112 }
14113}
14114
14115
14116static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14117{
14118 struct alc_spec *spec = codec->spec;
14119 hda_nid_t pin;
14120
14121 pin = spec->autocfg.hp_pins[0];
14122 if (pin) /* connect to front and use dac 0 */
14123 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14124 pin = spec->autocfg.speaker_pins[0];
14125 if (pin)
14126 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
14127}
14128
14129#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14130#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14131
14132static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14133{
14134 struct alc_spec *spec = codec->spec;
14135 int i;
14136
14137 for (i = 0; i < AUTO_PIN_LAST; i++) {
14138 hda_nid_t nid = spec->autocfg.input_pins[i];
14139 if (alc861vd_is_input_pin(nid)) {
14140 snd_hda_codec_write(codec, nid, 0,
14141 AC_VERB_SET_PIN_WIDGET_CONTROL,
14142 i <= AUTO_PIN_FRONT_MIC ?
14143 PIN_VREF80 : PIN_IN);
14144 if (nid != ALC861VD_PIN_CD_NID)
14145 snd_hda_codec_write(codec, nid, 0,
14146 AC_VERB_SET_AMP_GAIN_MUTE,
14147 AMP_OUT_MUTE);
14148 }
14149 }
14150}
14151
f511b01c
TI
14152#define alc861vd_auto_init_input_src alc882_auto_init_input_src
14153
f32610ed
JS
14154#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14155#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14156
14157/* add playback controls from the parsed DAC table */
14158/* Based on ALC880 version. But ALC861VD has separate,
14159 * different NIDs for mute/unmute switch and volume control */
14160static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14161 const struct auto_pin_cfg *cfg)
14162{
14163 char name[32];
14164 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14165 hda_nid_t nid_v, nid_s;
14166 int i, err;
14167
14168 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 14169 if (!spec->multiout.dac_nids[i])
f32610ed
JS
14170 continue;
14171 nid_v = alc861vd_idx_to_mixer_vol(
14172 alc880_dac_to_idx(
14173 spec->multiout.dac_nids[i]));
14174 nid_s = alc861vd_idx_to_mixer_switch(
14175 alc880_dac_to_idx(
14176 spec->multiout.dac_nids[i]));
14177
14178 if (i == 2) {
14179 /* Center/LFE */
f12ab1e0
TI
14180 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14181 "Center Playback Volume",
14182 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14183 HDA_OUTPUT));
14184 if (err < 0)
f32610ed 14185 return err;
f12ab1e0
TI
14186 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14187 "LFE Playback Volume",
14188 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14189 HDA_OUTPUT));
14190 if (err < 0)
f32610ed 14191 return err;
f12ab1e0
TI
14192 err = add_control(spec, ALC_CTL_BIND_MUTE,
14193 "Center Playback Switch",
14194 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14195 HDA_INPUT));
14196 if (err < 0)
f32610ed 14197 return err;
f12ab1e0
TI
14198 err = add_control(spec, ALC_CTL_BIND_MUTE,
14199 "LFE Playback Switch",
14200 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14201 HDA_INPUT));
14202 if (err < 0)
f32610ed
JS
14203 return err;
14204 } else {
14205 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
14206 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14207 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14208 HDA_OUTPUT));
14209 if (err < 0)
f32610ed
JS
14210 return err;
14211 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 14212 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 14213 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
14214 HDA_INPUT));
14215 if (err < 0)
f32610ed
JS
14216 return err;
14217 }
14218 }
14219 return 0;
14220}
14221
14222/* add playback controls for speaker and HP outputs */
14223/* Based on ALC880 version. But ALC861VD has separate,
14224 * different NIDs for mute/unmute switch and volume control */
14225static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14226 hda_nid_t pin, const char *pfx)
14227{
14228 hda_nid_t nid_v, nid_s;
14229 int err;
14230 char name[32];
14231
f12ab1e0 14232 if (!pin)
f32610ed
JS
14233 return 0;
14234
14235 if (alc880_is_fixed_pin(pin)) {
14236 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14237 /* specify the DAC as the extra output */
f12ab1e0 14238 if (!spec->multiout.hp_nid)
f32610ed
JS
14239 spec->multiout.hp_nid = nid_v;
14240 else
14241 spec->multiout.extra_out_nid[0] = nid_v;
14242 /* control HP volume/switch on the output mixer amp */
14243 nid_v = alc861vd_idx_to_mixer_vol(
14244 alc880_fixed_pin_idx(pin));
14245 nid_s = alc861vd_idx_to_mixer_switch(
14246 alc880_fixed_pin_idx(pin));
14247
14248 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
14249 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14250 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14251 if (err < 0)
f32610ed
JS
14252 return err;
14253 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14254 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14255 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14256 if (err < 0)
f32610ed
JS
14257 return err;
14258 } else if (alc880_is_multi_pin(pin)) {
14259 /* set manual connection */
14260 /* we have only a switch on HP-out PIN */
14261 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14262 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14263 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14264 if (err < 0)
f32610ed
JS
14265 return err;
14266 }
14267 return 0;
14268}
14269
14270/* parse the BIOS configuration and set up the alc_spec
14271 * return 1 if successful, 0 if the proper config is not found,
14272 * or a negative error code
14273 * Based on ALC880 version - had to change it to override
14274 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14275static int alc861vd_parse_auto_config(struct hda_codec *codec)
14276{
14277 struct alc_spec *spec = codec->spec;
14278 int err;
14279 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14280
f12ab1e0
TI
14281 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14282 alc861vd_ignore);
14283 if (err < 0)
f32610ed 14284 return err;
f12ab1e0 14285 if (!spec->autocfg.line_outs)
f32610ed
JS
14286 return 0; /* can't find valid BIOS pin config */
14287
f12ab1e0
TI
14288 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14289 if (err < 0)
14290 return err;
14291 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14292 if (err < 0)
14293 return err;
14294 err = alc861vd_auto_create_extra_out(spec,
14295 spec->autocfg.speaker_pins[0],
14296 "Speaker");
14297 if (err < 0)
14298 return err;
14299 err = alc861vd_auto_create_extra_out(spec,
14300 spec->autocfg.hp_pins[0],
14301 "Headphone");
14302 if (err < 0)
14303 return err;
14304 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14305 if (err < 0)
f32610ed
JS
14306 return err;
14307
14308 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14309
14310 if (spec->autocfg.dig_out_pin)
14311 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14312
14313 if (spec->kctl_alloc)
14314 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14315
14316 spec->init_verbs[spec->num_init_verbs++]
14317 = alc861vd_volume_init_verbs;
14318
14319 spec->num_mux_defs = 1;
14320 spec->input_mux = &spec->private_imux;
14321
776e184e
TI
14322 err = alc_auto_add_mic_boost(codec);
14323 if (err < 0)
14324 return err;
14325
f32610ed
JS
14326 return 1;
14327}
14328
14329/* additional initialization for auto-configuration model */
14330static void alc861vd_auto_init(struct hda_codec *codec)
14331{
f6c7e546 14332 struct alc_spec *spec = codec->spec;
f32610ed
JS
14333 alc861vd_auto_init_multi_out(codec);
14334 alc861vd_auto_init_hp_out(codec);
14335 alc861vd_auto_init_analog_input(codec);
f511b01c 14336 alc861vd_auto_init_input_src(codec);
f6c7e546
TI
14337 if (spec->unsol_event)
14338 alc_sku_automute(codec);
f32610ed
JS
14339}
14340
14341static int patch_alc861vd(struct hda_codec *codec)
14342{
14343 struct alc_spec *spec;
14344 int err, board_config;
14345
14346 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14347 if (spec == NULL)
14348 return -ENOMEM;
14349
14350 codec->spec = spec;
14351
14352 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14353 alc861vd_models,
14354 alc861vd_cfg_tbl);
14355
14356 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14357 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14358 "ALC861VD, trying auto-probe from BIOS...\n");
14359 board_config = ALC861VD_AUTO;
14360 }
14361
14362 if (board_config == ALC861VD_AUTO) {
14363 /* automatic parse from the BIOS config */
14364 err = alc861vd_parse_auto_config(codec);
14365 if (err < 0) {
14366 alc_free(codec);
14367 return err;
f12ab1e0 14368 } else if (!err) {
f32610ed
JS
14369 printk(KERN_INFO
14370 "hda_codec: Cannot set up configuration "
14371 "from BIOS. Using base mode...\n");
14372 board_config = ALC861VD_3ST;
14373 }
14374 }
14375
14376 if (board_config != ALC861VD_AUTO)
14377 setup_preset(spec, &alc861vd_presets[board_config]);
14378
2f893286
KY
14379 if (codec->vendor_id == 0x10ec0660) {
14380 spec->stream_name_analog = "ALC660-VD Analog";
14381 spec->stream_name_digital = "ALC660-VD Digital";
f9423e7a
KY
14382 /* always turn on EAPD */
14383 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
2f893286
KY
14384 } else {
14385 spec->stream_name_analog = "ALC861VD Analog";
14386 spec->stream_name_digital = "ALC861VD Digital";
14387 }
14388
f32610ed
JS
14389 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14390 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14391
f32610ed
JS
14392 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14393 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14394
14395 spec->adc_nids = alc861vd_adc_nids;
14396 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 14397 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed
JS
14398
14399 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14400 spec->num_mixers++;
14401
2134ea4f
TI
14402 spec->vmaster_nid = 0x02;
14403
f32610ed
JS
14404 codec->patch_ops = alc_patch_ops;
14405
14406 if (board_config == ALC861VD_AUTO)
14407 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
14408#ifdef CONFIG_SND_HDA_POWER_SAVE
14409 if (!spec->loopback.amplist)
14410 spec->loopback.amplist = alc861vd_loopbacks;
14411#endif
f32610ed
JS
14412
14413 return 0;
14414}
14415
bc9f98a9
KY
14416/*
14417 * ALC662 support
14418 *
14419 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14420 * configuration. Each pin widget can choose any input DACs and a mixer.
14421 * Each ADC is connected from a mixer of all inputs. This makes possible
14422 * 6-channel independent captures.
14423 *
14424 * In addition, an independent DAC for the multi-playback (not used in this
14425 * driver yet).
14426 */
14427#define ALC662_DIGOUT_NID 0x06
14428#define ALC662_DIGIN_NID 0x0a
14429
14430static hda_nid_t alc662_dac_nids[4] = {
14431 /* front, rear, clfe, rear_surr */
14432 0x02, 0x03, 0x04
14433};
14434
14435static hda_nid_t alc662_adc_nids[1] = {
14436 /* ADC1-2 */
14437 0x09,
14438};
e1406348 14439
77a261b7 14440static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
e1406348 14441
bc9f98a9
KY
14442/* input MUX */
14443/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
14444static struct hda_input_mux alc662_capture_source = {
14445 .num_items = 4,
14446 .items = {
14447 { "Mic", 0x0 },
14448 { "Front Mic", 0x1 },
14449 { "Line", 0x2 },
14450 { "CD", 0x4 },
14451 },
14452};
14453
14454static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14455 .num_items = 2,
14456 .items = {
14457 { "Mic", 0x1 },
14458 { "Line", 0x2 },
14459 },
14460};
291702f0
KY
14461
14462static struct hda_input_mux alc662_eeepc_capture_source = {
14463 .num_items = 2,
14464 .items = {
14465 { "i-Mic", 0x1 },
14466 { "e-Mic", 0x0 },
14467 },
14468};
14469
6dda9f4a
KY
14470static struct hda_input_mux alc663_capture_source = {
14471 .num_items = 3,
14472 .items = {
14473 { "Mic", 0x0 },
14474 { "Front Mic", 0x1 },
14475 { "Line", 0x2 },
14476 },
14477};
14478
14479static struct hda_input_mux alc663_m51va_capture_source = {
14480 .num_items = 2,
14481 .items = {
14482 { "Ext-Mic", 0x0 },
14483 { "D-Mic", 0x9 },
14484 },
14485};
14486
bc9f98a9
KY
14487#define alc662_mux_enum_info alc_mux_enum_info
14488#define alc662_mux_enum_get alc_mux_enum_get
e1406348 14489#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 14490
bc9f98a9
KY
14491/*
14492 * 2ch mode
14493 */
14494static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14495 { 2, NULL }
14496};
14497
14498/*
14499 * 2ch mode
14500 */
14501static struct hda_verb alc662_3ST_ch2_init[] = {
14502 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14503 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14504 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14505 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14506 { } /* end */
14507};
14508
14509/*
14510 * 6ch mode
14511 */
14512static struct hda_verb alc662_3ST_ch6_init[] = {
14513 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14514 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14515 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14517 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14518 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14519 { } /* end */
14520};
14521
14522static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14523 { 2, alc662_3ST_ch2_init },
14524 { 6, alc662_3ST_ch6_init },
14525};
14526
14527/*
14528 * 2ch mode
14529 */
14530static struct hda_verb alc662_sixstack_ch6_init[] = {
14531 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14532 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14533 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14534 { } /* end */
14535};
14536
14537/*
14538 * 6ch mode
14539 */
14540static struct hda_verb alc662_sixstack_ch8_init[] = {
14541 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14542 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14543 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14544 { } /* end */
14545};
14546
14547static struct hda_channel_mode alc662_5stack_modes[2] = {
14548 { 2, alc662_sixstack_ch6_init },
14549 { 6, alc662_sixstack_ch8_init },
14550};
14551
14552/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14553 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14554 */
14555
14556static struct snd_kcontrol_new alc662_base_mixer[] = {
14557 /* output mixer control */
14558 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 14559 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 14560 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 14561 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
14562 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14563 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
14564 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14565 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
14566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14567
14568 /*Input mixer control */
14569 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14570 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14571 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14572 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14573 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14574 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14575 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14576 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
14577 { } /* end */
14578};
14579
14580static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14581 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 14582 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
14583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14591 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14592 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14593 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
14594 { } /* end */
14595};
14596
14597static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14598 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 14599 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 14600 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 14601 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
14602 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
14604 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14605 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
14606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14612 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14613 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14615 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14616 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
14617 { } /* end */
14618};
14619
14620static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14621 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14622 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
14623 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14624 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
14625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14626 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14627 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
14630 { } /* end */
14631};
14632
291702f0 14633static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 14634 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 14635
b4818494
HRK
14636 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14637 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
14638
14639 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14640 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14641 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14642
14643 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14644 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14645 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14646 { } /* end */
14647};
14648
8c427226 14649static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
14650 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14651 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
14652 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14653 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14654 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14655 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14656 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14657 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 14658 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
14659 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14660 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14661 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14664 { } /* end */
14665};
14666
f1d4e28b
KY
14667static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14668 .ops = &snd_hda_bind_vol,
14669 .values = {
14670 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14671 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14672 0
14673 },
14674};
14675
14676static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14677 .ops = &snd_hda_bind_sw,
14678 .values = {
14679 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14680 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14681 0
14682 },
14683};
14684
6dda9f4a 14685static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
14686 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14687 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14689 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14690 { } /* end */
14691};
14692
14693static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14694 .ops = &snd_hda_bind_sw,
14695 .values = {
14696 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14697 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14698 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14699 0
14700 },
14701};
14702
14703static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14704 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14705 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14708 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14709 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14710
14711 { } /* end */
14712};
14713
14714static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14715 .ops = &snd_hda_bind_sw,
14716 .values = {
14717 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14718 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14719 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14720 0
14721 },
14722};
14723
14724static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14725 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14726 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14729 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14730 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14731 { } /* end */
14732};
14733
14734static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
14735 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14736 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
14737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14740 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14741 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14742 { } /* end */
14743};
14744
14745static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14746 .ops = &snd_hda_bind_vol,
14747 .values = {
14748 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14749 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14750 0
14751 },
14752};
14753
14754static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14755 .ops = &snd_hda_bind_sw,
14756 .values = {
14757 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14758 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14759 0
14760 },
14761};
14762
14763static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14764 HDA_BIND_VOL("Master Playback Volume",
14765 &alc663_asus_two_bind_master_vol),
14766 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
14768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
14771 { } /* end */
14772};
14773
14774static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14775 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14776 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14777 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
14781 { } /* end */
14782};
14783
14784static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14785 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14786 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14787 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14788 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14789 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14790
14791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14793 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14794 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14795 { } /* end */
14796};
14797
14798static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14799 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14800 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14802
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("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14806 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14807 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14808 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14809 { } /* end */
14810};
14811
bc9f98a9
KY
14812static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14813 {
14814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14815 .name = "Channel Mode",
14816 .info = alc_ch_mode_info,
14817 .get = alc_ch_mode_get,
14818 .put = alc_ch_mode_put,
14819 },
14820 { } /* end */
14821};
14822
14823static struct hda_verb alc662_init_verbs[] = {
14824 /* ADC: mute amp left and right */
14825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14826 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14827 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14828
cb53c626
TI
14829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 14834
b60dd394
KY
14835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
14841
14842 /* Front Pin: output 0 (0x0c) */
14843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14845
14846 /* Rear Pin: output 1 (0x0d) */
14847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14849
14850 /* CLFE Pin: output 2 (0x0e) */
14851 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14853
14854 /* Mic (rear) pin: input vref at 80% */
14855 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14857 /* Front Mic pin: input vref at 80% */
14858 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14860 /* Line In pin: input */
14861 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14863 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14864 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14865 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14866 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14867 /* CD pin widget for input */
14868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14869
14870 /* FIXME: use matrix-type input source selection */
14871 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14872 /* Input mixer */
14873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
14877
14878 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14879 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6dda9f4a
KY
14882
14883 /* always trun on EAPD */
14884 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14885 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14886
bc9f98a9
KY
14887 { }
14888};
14889
14890static struct hda_verb alc662_sue_init_verbs[] = {
14891 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14892 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
14893 {}
14894};
14895
14896static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14897 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14898 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14899 {}
bc9f98a9
KY
14900};
14901
8c427226
KY
14902/* Set Unsolicited Event*/
14903static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14905 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14906 {}
14907};
14908
bc9f98a9
KY
14909/*
14910 * generic initialization of ADC, input mixers and output mixers
14911 */
14912static struct hda_verb alc662_auto_init_verbs[] = {
14913 /*
14914 * Unmute ADC and set the default input to mic-in
14915 */
14916 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14917 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14918
14919 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14920 * mixer widget
14921 * Note: PASD motherboards uses the Line In 2 as the input for front
14922 * panel mic (mic 2)
14923 */
14924 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
14930
14931 /*
14932 * Set up output mixers (0x0c - 0x0f)
14933 */
14934 /* set vol=0 to output mixers */
14935 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14936 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14937 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14938
14939 /* set up input amps for analog loopback */
14940 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
14941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14944 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14946 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
14947
14948
14949 /* FIXME: use matrix-type input source selection */
14950 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14951 /* Input mixer */
14952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 14953 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
14954 { }
14955};
14956
24fb9173
TI
14957/* additional verbs for ALC663 */
14958static struct hda_verb alc663_auto_init_verbs[] = {
14959 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14960 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14961 { }
14962};
14963
6dda9f4a 14964static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
14965 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14966 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
14967 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14968 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
14969 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14972 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14973 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14974 {}
14975};
14976
14977static struct hda_verb alc663_21jd_amic_init_verbs[] = {
14978 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14979 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14980 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14984 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14985 {}
14986};
14987
14988static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
14989 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14990 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14991 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14992 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14995 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14996 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14997 {}
14998};
6dda9f4a 14999
f1d4e28b
KY
15000static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15006 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15007 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15008 {}
15009};
6dda9f4a 15010
f1d4e28b
KY
15011static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15012 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15013 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15014 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15015 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15016 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15017 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15018 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15021 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15022 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15023 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15024 {}
15025};
15026
15027static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15028 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15029 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15030 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15031 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15037 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15038 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15039 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
15040 {}
15041};
15042
15043static struct hda_verb alc663_g71v_init_verbs[] = {
15044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15045 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15046 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15047
15048 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15049 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15051
15052 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15053 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15054 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15055 {}
15056};
15057
15058static struct hda_verb alc663_g50v_init_verbs[] = {
15059 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15060 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15061 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15062
15063 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15064 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15065 {}
15066};
15067
f1d4e28b
KY
15068static struct hda_verb alc662_ecs_init_verbs[] = {
15069 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15071 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15073 {}
15074};
15075
bc9f98a9
KY
15076/* capture mixer elements */
15077static struct snd_kcontrol_new alc662_capture_mixer[] = {
15078 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15079 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15080 {
15081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15082 /* The multiple "Capture Source" controls confuse alsamixer
15083 * So call somewhat different..
bc9f98a9
KY
15084 */
15085 /* .name = "Capture Source", */
15086 .name = "Input Source",
15087 .count = 1,
6e7939bb
HRK
15088 .info = alc662_mux_enum_info,
15089 .get = alc662_mux_enum_get,
15090 .put = alc662_mux_enum_put,
bc9f98a9
KY
15091 },
15092 { } /* end */
15093};
15094
f1d4e28b
KY
15095static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15096 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15097 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15098 { } /* end */
15099};
15100
bc9f98a9
KY
15101static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15102{
15103 unsigned int present;
f12ab1e0 15104 unsigned char bits;
bc9f98a9
KY
15105
15106 present = snd_hda_codec_read(codec, 0x14, 0,
15107 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15108 bits = present ? HDA_AMP_MUTE : 0;
15109 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15110 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15111}
15112
15113static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15114{
15115 unsigned int present;
f12ab1e0 15116 unsigned char bits;
bc9f98a9
KY
15117
15118 present = snd_hda_codec_read(codec, 0x1b, 0,
15119 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15120 bits = present ? HDA_AMP_MUTE : 0;
15121 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15122 HDA_AMP_MUTE, bits);
15123 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15124 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15125}
15126
15127static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15128 unsigned int res)
15129{
15130 if ((res >> 26) == ALC880_HP_EVENT)
15131 alc662_lenovo_101e_all_automute(codec);
15132 if ((res >> 26) == ALC880_FRONT_EVENT)
15133 alc662_lenovo_101e_ispeaker_automute(codec);
15134}
15135
291702f0
KY
15136static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15137{
15138 unsigned int present;
15139
15140 present = snd_hda_codec_read(codec, 0x18, 0,
15141 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15142 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15143 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15144 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15145 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15146 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15147 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15148 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15149 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15150}
15151
15152/* unsolicited event for HP jack sensing */
15153static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15154 unsigned int res)
15155{
15156 if ((res >> 26) == ALC880_HP_EVENT)
15157 alc262_hippo1_automute( codec );
15158
15159 if ((res >> 26) == ALC880_MIC_EVENT)
15160 alc662_eeepc_mic_automute(codec);
15161}
15162
15163static void alc662_eeepc_inithook(struct hda_codec *codec)
15164{
15165 alc262_hippo1_automute( codec );
15166 alc662_eeepc_mic_automute(codec);
15167}
15168
8c427226
KY
15169static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15170{
15171 unsigned int mute;
15172 unsigned int present;
15173
15174 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15175 present = snd_hda_codec_read(codec, 0x14, 0,
15176 AC_VERB_GET_PIN_SENSE, 0);
15177 present = (present & 0x80000000) != 0;
15178 if (present) {
15179 /* mute internal speaker */
15180 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15181 HDA_AMP_MUTE, HDA_AMP_MUTE);
8c427226
KY
15182 } else {
15183 /* unmute internal speaker if necessary */
15184 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15185 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15186 HDA_AMP_MUTE, mute);
8c427226
KY
15187 }
15188}
15189
15190/* unsolicited event for HP jack sensing */
15191static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15192 unsigned int res)
15193{
15194 if ((res >> 26) == ALC880_HP_EVENT)
15195 alc662_eeepc_ep20_automute(codec);
15196}
15197
15198static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15199{
15200 alc662_eeepc_ep20_automute(codec);
15201}
15202
6dda9f4a
KY
15203static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15204{
15205 unsigned int present;
15206 unsigned char bits;
15207
15208 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
15209 AC_VERB_GET_PIN_SENSE, 0)
15210 & AC_PINSENSE_PRESENCE;
6dda9f4a 15211 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
15212 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15213 AMP_IN_MUTE(0), bits);
15214 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15215 AMP_IN_MUTE(0), bits);
15216}
15217
15218static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15219{
15220 unsigned int present;
15221 unsigned char bits;
15222
15223 present = snd_hda_codec_read(codec, 0x21, 0,
15224 AC_VERB_GET_PIN_SENSE, 0)
15225 & AC_PINSENSE_PRESENCE;
15226 bits = present ? HDA_AMP_MUTE : 0;
15227 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15228 AMP_IN_MUTE(0), bits);
15229 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15230 AMP_IN_MUTE(0), bits);
15231 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15232 AMP_IN_MUTE(0), bits);
15233 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15234 AMP_IN_MUTE(0), bits);
15235}
15236
15237static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15238{
15239 unsigned int present;
15240 unsigned char bits;
15241
15242 present = snd_hda_codec_read(codec, 0x15, 0,
15243 AC_VERB_GET_PIN_SENSE, 0)
15244 & AC_PINSENSE_PRESENCE;
15245 bits = present ? HDA_AMP_MUTE : 0;
15246 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15247 AMP_IN_MUTE(0), bits);
15248 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15249 AMP_IN_MUTE(0), bits);
15250 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15251 AMP_IN_MUTE(0), bits);
15252 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15253 AMP_IN_MUTE(0), bits);
15254}
15255
15256static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15257{
15258 unsigned int present;
15259 unsigned char bits;
15260
15261 present = snd_hda_codec_read(codec, 0x1b, 0,
15262 AC_VERB_GET_PIN_SENSE, 0)
15263 & AC_PINSENSE_PRESENCE;
15264 bits = present ? 0 : PIN_OUT;
15265 snd_hda_codec_write(codec, 0x14, 0,
15266 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15267}
15268
15269static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15270{
15271 unsigned int present1, present2;
15272
15273 present1 = snd_hda_codec_read(codec, 0x21, 0,
15274 AC_VERB_GET_PIN_SENSE, 0)
15275 & AC_PINSENSE_PRESENCE;
15276 present2 = snd_hda_codec_read(codec, 0x15, 0,
15277 AC_VERB_GET_PIN_SENSE, 0)
15278 & AC_PINSENSE_PRESENCE;
15279
15280 if (present1 || present2) {
15281 snd_hda_codec_write_cache(codec, 0x14, 0,
15282 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15283 } else {
15284 snd_hda_codec_write_cache(codec, 0x14, 0,
15285 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15286 }
15287}
15288
15289static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15290{
15291 unsigned int present1, present2;
15292
15293 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15294 AC_VERB_GET_PIN_SENSE, 0)
15295 & AC_PINSENSE_PRESENCE;
15296 present2 = snd_hda_codec_read(codec, 0x15, 0,
15297 AC_VERB_GET_PIN_SENSE, 0)
15298 & AC_PINSENSE_PRESENCE;
15299
15300 if (present1 || present2) {
15301 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15302 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15303 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15304 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15305 } else {
15306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15307 AMP_IN_MUTE(0), 0);
15308 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15309 AMP_IN_MUTE(0), 0);
15310 }
6dda9f4a
KY
15311}
15312
15313static void alc663_m51va_mic_automute(struct hda_codec *codec)
15314{
15315 unsigned int present;
15316
15317 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
15318 AC_VERB_GET_PIN_SENSE, 0)
15319 & AC_PINSENSE_PRESENCE;
6dda9f4a 15320 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15321 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15322 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15323 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15324 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15325 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 15326 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15327 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
15328}
15329
15330static void alc663_m51va_unsol_event(struct hda_codec *codec,
15331 unsigned int res)
15332{
15333 switch (res >> 26) {
15334 case ALC880_HP_EVENT:
15335 alc663_m51va_speaker_automute(codec);
15336 break;
15337 case ALC880_MIC_EVENT:
15338 alc663_m51va_mic_automute(codec);
15339 break;
15340 }
15341}
15342
15343static void alc663_m51va_inithook(struct hda_codec *codec)
15344{
15345 alc663_m51va_speaker_automute(codec);
15346 alc663_m51va_mic_automute(codec);
15347}
15348
f1d4e28b
KY
15349/* ***************** Mode1 ******************************/
15350static void alc663_mode1_unsol_event(struct hda_codec *codec,
15351 unsigned int res)
15352{
15353 switch (res >> 26) {
15354 case ALC880_HP_EVENT:
15355 alc663_m51va_speaker_automute(codec);
15356 break;
15357 case ALC880_MIC_EVENT:
15358 alc662_eeepc_mic_automute(codec);
15359 break;
15360 }
15361}
15362
15363static void alc663_mode1_inithook(struct hda_codec *codec)
15364{
15365 alc663_m51va_speaker_automute(codec);
15366 alc662_eeepc_mic_automute(codec);
15367}
15368/* ***************** Mode2 ******************************/
15369static void alc662_mode2_unsol_event(struct hda_codec *codec,
15370 unsigned int res)
15371{
15372 switch (res >> 26) {
15373 case ALC880_HP_EVENT:
15374 alc662_f5z_speaker_automute(codec);
15375 break;
15376 case ALC880_MIC_EVENT:
15377 alc662_eeepc_mic_automute(codec);
15378 break;
15379 }
15380}
15381
15382static void alc662_mode2_inithook(struct hda_codec *codec)
15383{
15384 alc662_f5z_speaker_automute(codec);
15385 alc662_eeepc_mic_automute(codec);
15386}
15387/* ***************** Mode3 ******************************/
15388static void alc663_mode3_unsol_event(struct hda_codec *codec,
15389 unsigned int res)
15390{
15391 switch (res >> 26) {
15392 case ALC880_HP_EVENT:
15393 alc663_two_hp_m1_speaker_automute(codec);
15394 break;
15395 case ALC880_MIC_EVENT:
15396 alc662_eeepc_mic_automute(codec);
15397 break;
15398 }
15399}
15400
15401static void alc663_mode3_inithook(struct hda_codec *codec)
15402{
15403 alc663_two_hp_m1_speaker_automute(codec);
15404 alc662_eeepc_mic_automute(codec);
15405}
15406/* ***************** Mode4 ******************************/
15407static void alc663_mode4_unsol_event(struct hda_codec *codec,
15408 unsigned int res)
15409{
15410 switch (res >> 26) {
15411 case ALC880_HP_EVENT:
15412 alc663_21jd_two_speaker_automute(codec);
15413 break;
15414 case ALC880_MIC_EVENT:
15415 alc662_eeepc_mic_automute(codec);
15416 break;
15417 }
15418}
15419
15420static void alc663_mode4_inithook(struct hda_codec *codec)
15421{
15422 alc663_21jd_two_speaker_automute(codec);
15423 alc662_eeepc_mic_automute(codec);
15424}
15425/* ***************** Mode5 ******************************/
15426static void alc663_mode5_unsol_event(struct hda_codec *codec,
15427 unsigned int res)
15428{
15429 switch (res >> 26) {
15430 case ALC880_HP_EVENT:
15431 alc663_15jd_two_speaker_automute(codec);
15432 break;
15433 case ALC880_MIC_EVENT:
15434 alc662_eeepc_mic_automute(codec);
15435 break;
15436 }
15437}
15438
15439static void alc663_mode5_inithook(struct hda_codec *codec)
15440{
15441 alc663_15jd_two_speaker_automute(codec);
15442 alc662_eeepc_mic_automute(codec);
15443}
15444/* ***************** Mode6 ******************************/
15445static void alc663_mode6_unsol_event(struct hda_codec *codec,
15446 unsigned int res)
15447{
15448 switch (res >> 26) {
15449 case ALC880_HP_EVENT:
15450 alc663_two_hp_m2_speaker_automute(codec);
15451 break;
15452 case ALC880_MIC_EVENT:
15453 alc662_eeepc_mic_automute(codec);
15454 break;
15455 }
15456}
15457
15458static void alc663_mode6_inithook(struct hda_codec *codec)
15459{
15460 alc663_two_hp_m2_speaker_automute(codec);
15461 alc662_eeepc_mic_automute(codec);
15462}
15463
6dda9f4a
KY
15464static void alc663_g71v_hp_automute(struct hda_codec *codec)
15465{
15466 unsigned int present;
15467 unsigned char bits;
15468
15469 present = snd_hda_codec_read(codec, 0x21, 0,
15470 AC_VERB_GET_PIN_SENSE, 0)
15471 & AC_PINSENSE_PRESENCE;
15472 bits = present ? HDA_AMP_MUTE : 0;
15473 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15474 HDA_AMP_MUTE, bits);
15475 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15476 HDA_AMP_MUTE, bits);
15477}
15478
15479static void alc663_g71v_front_automute(struct hda_codec *codec)
15480{
15481 unsigned int present;
15482 unsigned char bits;
15483
15484 present = snd_hda_codec_read(codec, 0x15, 0,
15485 AC_VERB_GET_PIN_SENSE, 0)
15486 & AC_PINSENSE_PRESENCE;
15487 bits = present ? HDA_AMP_MUTE : 0;
15488 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15489 HDA_AMP_MUTE, bits);
15490}
15491
15492static void alc663_g71v_unsol_event(struct hda_codec *codec,
15493 unsigned int res)
15494{
15495 switch (res >> 26) {
15496 case ALC880_HP_EVENT:
15497 alc663_g71v_hp_automute(codec);
15498 break;
15499 case ALC880_FRONT_EVENT:
15500 alc663_g71v_front_automute(codec);
15501 break;
15502 case ALC880_MIC_EVENT:
15503 alc662_eeepc_mic_automute(codec);
15504 break;
15505 }
15506}
15507
15508static void alc663_g71v_inithook(struct hda_codec *codec)
15509{
15510 alc663_g71v_front_automute(codec);
15511 alc663_g71v_hp_automute(codec);
15512 alc662_eeepc_mic_automute(codec);
15513}
15514
15515static void alc663_g50v_unsol_event(struct hda_codec *codec,
15516 unsigned int res)
15517{
15518 switch (res >> 26) {
15519 case ALC880_HP_EVENT:
15520 alc663_m51va_speaker_automute(codec);
15521 break;
15522 case ALC880_MIC_EVENT:
15523 alc662_eeepc_mic_automute(codec);
15524 break;
15525 }
15526}
15527
15528static void alc663_g50v_inithook(struct hda_codec *codec)
15529{
15530 alc663_m51va_speaker_automute(codec);
15531 alc662_eeepc_mic_automute(codec);
15532}
15533
f1d4e28b
KY
15534/* bind hp and internal speaker mute (with plug check) */
15535static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15536 struct snd_ctl_elem_value *ucontrol)
15537{
15538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15539 long *valp = ucontrol->value.integer.value;
15540 int change;
15541
15542 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15543 HDA_AMP_MUTE,
15544 valp[0] ? 0 : HDA_AMP_MUTE);
15545 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15546 HDA_AMP_MUTE,
15547 valp[1] ? 0 : HDA_AMP_MUTE);
15548 if (change)
15549 alc262_hippo1_automute(codec);
15550 return change;
15551}
15552
15553static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15554 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15555 {
15556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15557 .name = "Master Playback Switch",
15558 .info = snd_hda_mixer_amp_switch_info,
15559 .get = snd_hda_mixer_amp_switch_get,
15560 .put = alc662_ecs_master_sw_put,
15561 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15562 },
15563
15564 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15565 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15566 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15567
15568 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15569 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15570 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15571 { } /* end */
15572};
15573
cb53c626
TI
15574#ifdef CONFIG_SND_HDA_POWER_SAVE
15575#define alc662_loopbacks alc880_loopbacks
15576#endif
15577
bc9f98a9
KY
15578
15579/* pcm configuration: identiacal with ALC880 */
15580#define alc662_pcm_analog_playback alc880_pcm_analog_playback
15581#define alc662_pcm_analog_capture alc880_pcm_analog_capture
15582#define alc662_pcm_digital_playback alc880_pcm_digital_playback
15583#define alc662_pcm_digital_capture alc880_pcm_digital_capture
15584
15585/*
15586 * configuration and preset
15587 */
15588static const char *alc662_models[ALC662_MODEL_LAST] = {
15589 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15590 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15591 [ALC662_3ST_6ch] = "3stack-6ch",
15592 [ALC662_5ST_DIG] = "6stack-dig",
15593 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 15594 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 15595 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 15596 [ALC662_ECS] = "ecs",
6dda9f4a
KY
15597 [ALC663_ASUS_M51VA] = "m51va",
15598 [ALC663_ASUS_G71V] = "g71v",
15599 [ALC663_ASUS_H13] = "h13",
15600 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
15601 [ALC663_ASUS_MODE1] = "asus-mode1",
15602 [ALC662_ASUS_MODE2] = "asus-mode2",
15603 [ALC663_ASUS_MODE3] = "asus-mode3",
15604 [ALC663_ASUS_MODE4] = "asus-mode4",
15605 [ALC663_ASUS_MODE5] = "asus-mode5",
15606 [ALC663_ASUS_MODE6] = "asus-mode6",
bc9f98a9
KY
15607 [ALC662_AUTO] = "auto",
15608};
15609
15610static struct snd_pci_quirk alc662_cfg_tbl[] = {
6dda9f4a
KY
15611 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15612 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
3da23cac 15613 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
291702f0 15614 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 15615 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
f1d4e28b
KY
15616 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15617 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15618 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15619 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15620 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15621 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15622 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15623 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15624 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15625 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15626 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15627 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15628 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15629 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15630 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15631 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15632 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15633 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15634 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15635 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15636 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15637 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15638 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15639 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15640 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15641 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15642 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15643 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15644 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15645 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15646 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
ac3e3741 15647 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
f1d4e28b
KY
15648 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15649 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
6dda9f4a
KY
15650 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15651 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15652 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
bc9f98a9
KY
15653 {}
15654};
15655
15656static struct alc_config_preset alc662_presets[] = {
15657 [ALC662_3ST_2ch_DIG] = {
291702f0 15658 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
15659 .init_verbs = { alc662_init_verbs },
15660 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15661 .dac_nids = alc662_dac_nids,
15662 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
15663 .dig_in_nid = ALC662_DIGIN_NID,
15664 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15665 .channel_mode = alc662_3ST_2ch_modes,
15666 .input_mux = &alc662_capture_source,
15667 },
15668 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
15669 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15670 alc662_capture_mixer },
bc9f98a9
KY
15671 .init_verbs = { alc662_init_verbs },
15672 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15673 .dac_nids = alc662_dac_nids,
15674 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
15675 .dig_in_nid = ALC662_DIGIN_NID,
15676 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15677 .channel_mode = alc662_3ST_6ch_modes,
15678 .need_dac_fix = 1,
15679 .input_mux = &alc662_capture_source,
f12ab1e0 15680 },
bc9f98a9 15681 [ALC662_3ST_6ch] = {
291702f0
KY
15682 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15683 alc662_capture_mixer },
bc9f98a9
KY
15684 .init_verbs = { alc662_init_verbs },
15685 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15686 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
15687 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15688 .channel_mode = alc662_3ST_6ch_modes,
15689 .need_dac_fix = 1,
15690 .input_mux = &alc662_capture_source,
f12ab1e0 15691 },
bc9f98a9 15692 [ALC662_5ST_DIG] = {
291702f0
KY
15693 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15694 alc662_capture_mixer },
bc9f98a9
KY
15695 .init_verbs = { alc662_init_verbs },
15696 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15697 .dac_nids = alc662_dac_nids,
15698 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
15699 .dig_in_nid = ALC662_DIGIN_NID,
15700 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15701 .channel_mode = alc662_5stack_modes,
15702 .input_mux = &alc662_capture_source,
15703 },
15704 [ALC662_LENOVO_101E] = {
291702f0 15705 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
15706 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15707 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15708 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
15709 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15710 .channel_mode = alc662_3ST_2ch_modes,
15711 .input_mux = &alc662_lenovo_101e_capture_source,
15712 .unsol_event = alc662_lenovo_101e_unsol_event,
15713 .init_hook = alc662_lenovo_101e_all_automute,
15714 },
291702f0
KY
15715 [ALC662_ASUS_EEEPC_P701] = {
15716 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15717 .init_verbs = { alc662_init_verbs,
15718 alc662_eeepc_sue_init_verbs },
15719 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15720 .dac_nids = alc662_dac_nids,
291702f0
KY
15721 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15722 .channel_mode = alc662_3ST_2ch_modes,
15723 .input_mux = &alc662_eeepc_capture_source,
15724 .unsol_event = alc662_eeepc_unsol_event,
15725 .init_hook = alc662_eeepc_inithook,
15726 },
8c427226
KY
15727 [ALC662_ASUS_EEEPC_EP20] = {
15728 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15729 alc662_chmode_mixer },
15730 .init_verbs = { alc662_init_verbs,
15731 alc662_eeepc_ep20_sue_init_verbs },
15732 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15733 .dac_nids = alc662_dac_nids,
8c427226
KY
15734 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15735 .channel_mode = alc662_3ST_6ch_modes,
15736 .input_mux = &alc662_lenovo_101e_capture_source,
15737 .unsol_event = alc662_eeepc_ep20_unsol_event,
15738 .init_hook = alc662_eeepc_ep20_inithook,
15739 },
f1d4e28b
KY
15740 [ALC662_ECS] = {
15741 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15742 .init_verbs = { alc662_init_verbs,
15743 alc662_ecs_init_verbs },
15744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15745 .dac_nids = alc662_dac_nids,
15746 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15747 .channel_mode = alc662_3ST_2ch_modes,
15748 .input_mux = &alc662_eeepc_capture_source,
15749 .unsol_event = alc662_eeepc_unsol_event,
15750 .init_hook = alc662_eeepc_inithook,
15751 },
6dda9f4a
KY
15752 [ALC663_ASUS_M51VA] = {
15753 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15754 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15755 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15756 .dac_nids = alc662_dac_nids,
15757 .dig_out_nid = ALC662_DIGOUT_NID,
15758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15759 .channel_mode = alc662_3ST_2ch_modes,
15760 .input_mux = &alc663_m51va_capture_source,
15761 .unsol_event = alc663_m51va_unsol_event,
15762 .init_hook = alc663_m51va_inithook,
15763 },
15764 [ALC663_ASUS_G71V] = {
15765 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15766 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15767 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15768 .dac_nids = alc662_dac_nids,
15769 .dig_out_nid = ALC662_DIGOUT_NID,
15770 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15771 .channel_mode = alc662_3ST_2ch_modes,
15772 .input_mux = &alc662_eeepc_capture_source,
15773 .unsol_event = alc663_g71v_unsol_event,
15774 .init_hook = alc663_g71v_inithook,
15775 },
15776 [ALC663_ASUS_H13] = {
15777 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15778 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15779 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15780 .dac_nids = alc662_dac_nids,
15781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15782 .channel_mode = alc662_3ST_2ch_modes,
15783 .input_mux = &alc663_m51va_capture_source,
15784 .unsol_event = alc663_m51va_unsol_event,
15785 .init_hook = alc663_m51va_inithook,
15786 },
15787 [ALC663_ASUS_G50V] = {
15788 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15789 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15790 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15791 .dac_nids = alc662_dac_nids,
15792 .dig_out_nid = ALC662_DIGOUT_NID,
15793 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15794 .channel_mode = alc662_3ST_6ch_modes,
15795 .input_mux = &alc663_capture_source,
15796 .unsol_event = alc663_g50v_unsol_event,
15797 .init_hook = alc663_g50v_inithook,
15798 },
f1d4e28b
KY
15799 [ALC663_ASUS_MODE1] = {
15800 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15801 .init_verbs = { alc662_init_verbs,
15802 alc663_21jd_amic_init_verbs },
15803 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15804 .hp_nid = 0x03,
15805 .dac_nids = alc662_dac_nids,
15806 .dig_out_nid = ALC662_DIGOUT_NID,
15807 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15808 .channel_mode = alc662_3ST_2ch_modes,
15809 .input_mux = &alc662_eeepc_capture_source,
15810 .unsol_event = alc663_mode1_unsol_event,
15811 .init_hook = alc663_mode1_inithook,
15812 },
15813 [ALC662_ASUS_MODE2] = {
15814 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15815 .init_verbs = { alc662_init_verbs,
15816 alc662_1bjd_amic_init_verbs },
15817 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15818 .dac_nids = alc662_dac_nids,
15819 .dig_out_nid = ALC662_DIGOUT_NID,
15820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15821 .channel_mode = alc662_3ST_2ch_modes,
15822 .input_mux = &alc662_eeepc_capture_source,
15823 .unsol_event = alc662_mode2_unsol_event,
15824 .init_hook = alc662_mode2_inithook,
15825 },
15826 [ALC663_ASUS_MODE3] = {
15827 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15828 .init_verbs = { alc662_init_verbs,
15829 alc663_two_hp_amic_m1_init_verbs },
15830 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15831 .hp_nid = 0x03,
15832 .dac_nids = alc662_dac_nids,
15833 .dig_out_nid = ALC662_DIGOUT_NID,
15834 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15835 .channel_mode = alc662_3ST_2ch_modes,
15836 .input_mux = &alc662_eeepc_capture_source,
15837 .unsol_event = alc663_mode3_unsol_event,
15838 .init_hook = alc663_mode3_inithook,
15839 },
15840 [ALC663_ASUS_MODE4] = {
15841 .mixers = { alc663_asus_21jd_clfe_mixer,
15842 alc662_auto_capture_mixer},
15843 .init_verbs = { alc662_init_verbs,
15844 alc663_21jd_amic_init_verbs},
15845 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15846 .hp_nid = 0x03,
15847 .dac_nids = alc662_dac_nids,
15848 .dig_out_nid = ALC662_DIGOUT_NID,
15849 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15850 .channel_mode = alc662_3ST_2ch_modes,
15851 .input_mux = &alc662_eeepc_capture_source,
15852 .unsol_event = alc663_mode4_unsol_event,
15853 .init_hook = alc663_mode4_inithook,
15854 },
15855 [ALC663_ASUS_MODE5] = {
15856 .mixers = { alc663_asus_15jd_clfe_mixer,
15857 alc662_auto_capture_mixer },
15858 .init_verbs = { alc662_init_verbs,
15859 alc663_15jd_amic_init_verbs },
15860 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15861 .hp_nid = 0x03,
15862 .dac_nids = alc662_dac_nids,
15863 .dig_out_nid = ALC662_DIGOUT_NID,
15864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15865 .channel_mode = alc662_3ST_2ch_modes,
15866 .input_mux = &alc662_eeepc_capture_source,
15867 .unsol_event = alc663_mode5_unsol_event,
15868 .init_hook = alc663_mode5_inithook,
15869 },
15870 [ALC663_ASUS_MODE6] = {
15871 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15872 .init_verbs = { alc662_init_verbs,
15873 alc663_two_hp_amic_m2_init_verbs },
15874 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15875 .hp_nid = 0x03,
15876 .dac_nids = alc662_dac_nids,
15877 .dig_out_nid = ALC662_DIGOUT_NID,
15878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15879 .channel_mode = alc662_3ST_2ch_modes,
15880 .input_mux = &alc662_eeepc_capture_source,
15881 .unsol_event = alc663_mode6_unsol_event,
15882 .init_hook = alc663_mode6_inithook,
15883 },
bc9f98a9
KY
15884};
15885
15886
15887/*
15888 * BIOS auto configuration
15889 */
15890
15891/* add playback controls from the parsed DAC table */
15892static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15893 const struct auto_pin_cfg *cfg)
15894{
15895 char name[32];
15896 static const char *chname[4] = {
15897 "Front", "Surround", NULL /*CLFE*/, "Side"
15898 };
15899 hda_nid_t nid;
15900 int i, err;
15901
15902 for (i = 0; i < cfg->line_outs; i++) {
15903 if (!spec->multiout.dac_nids[i])
15904 continue;
b60dd394 15905 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
15906 if (i == 2) {
15907 /* Center/LFE */
15908 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15909 "Center Playback Volume",
f12ab1e0
TI
15910 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15911 HDA_OUTPUT));
bc9f98a9
KY
15912 if (err < 0)
15913 return err;
15914 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15915 "LFE Playback Volume",
f12ab1e0
TI
15916 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15917 HDA_OUTPUT));
bc9f98a9
KY
15918 if (err < 0)
15919 return err;
15920 err = add_control(spec, ALC_CTL_BIND_MUTE,
15921 "Center Playback Switch",
f12ab1e0
TI
15922 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
15923 HDA_INPUT));
bc9f98a9
KY
15924 if (err < 0)
15925 return err;
15926 err = add_control(spec, ALC_CTL_BIND_MUTE,
15927 "LFE Playback Switch",
f12ab1e0
TI
15928 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
15929 HDA_INPUT));
bc9f98a9
KY
15930 if (err < 0)
15931 return err;
15932 } else {
15933 sprintf(name, "%s Playback Volume", chname[i]);
15934 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
15935 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15936 HDA_OUTPUT));
bc9f98a9
KY
15937 if (err < 0)
15938 return err;
15939 sprintf(name, "%s Playback Switch", chname[i]);
15940 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
15941 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
15942 HDA_INPUT));
bc9f98a9
KY
15943 if (err < 0)
15944 return err;
15945 }
15946 }
15947 return 0;
15948}
15949
15950/* add playback controls for speaker and HP outputs */
15951static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15952 const char *pfx)
15953{
15954 hda_nid_t nid;
15955 int err;
15956 char name[32];
15957
15958 if (!pin)
15959 return 0;
15960
24fb9173
TI
15961 if (pin == 0x17) {
15962 /* ALC663 has a mono output pin on 0x17 */
15963 sprintf(name, "%s Playback Switch", pfx);
15964 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15965 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15966 return err;
15967 }
15968
bc9f98a9
KY
15969 if (alc880_is_fixed_pin(pin)) {
15970 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15971 /* printk("DAC nid=%x\n",nid); */
15972 /* specify the DAC as the extra output */
15973 if (!spec->multiout.hp_nid)
15974 spec->multiout.hp_nid = nid;
15975 else
15976 spec->multiout.extra_out_nid[0] = nid;
15977 /* control HP volume/switch on the output mixer amp */
15978 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15979 sprintf(name, "%s Playback Volume", pfx);
15980 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15981 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15982 if (err < 0)
15983 return err;
15984 sprintf(name, "%s Playback Switch", pfx);
15985 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15986 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15987 if (err < 0)
15988 return err;
15989 } else if (alc880_is_multi_pin(pin)) {
15990 /* set manual connection */
15991 /* we have only a switch on HP-out PIN */
15992 sprintf(name, "%s Playback Switch", pfx);
15993 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15994 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15995 if (err < 0)
15996 return err;
15997 }
15998 return 0;
15999}
16000
16001/* create playback/capture controls for input pins */
16002static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16003 const struct auto_pin_cfg *cfg)
16004{
16005 struct hda_input_mux *imux = &spec->private_imux;
16006 int i, err, idx;
16007
16008 for (i = 0; i < AUTO_PIN_LAST; i++) {
16009 if (alc880_is_input_pin(cfg->input_pins[i])) {
16010 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16011 err = new_analog_input(spec, cfg->input_pins[i],
16012 auto_pin_cfg_labels[i],
16013 idx, 0x0b);
16014 if (err < 0)
16015 return err;
16016 imux->items[imux->num_items].label =
16017 auto_pin_cfg_labels[i];
16018 imux->items[imux->num_items].index =
16019 alc880_input_pin_idx(cfg->input_pins[i]);
16020 imux->num_items++;
16021 }
16022 }
16023 return 0;
16024}
16025
16026static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16027 hda_nid_t nid, int pin_type,
16028 int dac_idx)
16029{
f6c7e546 16030 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
16031 /* need the manual connection? */
16032 if (alc880_is_multi_pin(nid)) {
16033 struct alc_spec *spec = codec->spec;
16034 int idx = alc880_multi_pin_idx(nid);
16035 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16036 AC_VERB_SET_CONNECT_SEL,
16037 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16038 }
16039}
16040
16041static void alc662_auto_init_multi_out(struct hda_codec *codec)
16042{
16043 struct alc_spec *spec = codec->spec;
16044 int i;
16045
8c427226 16046 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
16047 for (i = 0; i <= HDA_SIDE; i++) {
16048 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16049 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 16050 if (nid)
baba8ee9 16051 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
16052 i);
16053 }
16054}
16055
16056static void alc662_auto_init_hp_out(struct hda_codec *codec)
16057{
16058 struct alc_spec *spec = codec->spec;
16059 hda_nid_t pin;
16060
16061 pin = spec->autocfg.hp_pins[0];
16062 if (pin) /* connect to front */
16063 /* use dac 0 */
16064 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16065 pin = spec->autocfg.speaker_pins[0];
16066 if (pin)
16067 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
16068}
16069
16070#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16071#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16072
16073static void alc662_auto_init_analog_input(struct hda_codec *codec)
16074{
16075 struct alc_spec *spec = codec->spec;
16076 int i;
16077
16078 for (i = 0; i < AUTO_PIN_LAST; i++) {
16079 hda_nid_t nid = spec->autocfg.input_pins[i];
16080 if (alc662_is_input_pin(nid)) {
16081 snd_hda_codec_write(codec, nid, 0,
16082 AC_VERB_SET_PIN_WIDGET_CONTROL,
16083 (i <= AUTO_PIN_FRONT_MIC ?
16084 PIN_VREF80 : PIN_IN));
16085 if (nid != ALC662_PIN_CD_NID)
16086 snd_hda_codec_write(codec, nid, 0,
16087 AC_VERB_SET_AMP_GAIN_MUTE,
16088 AMP_OUT_MUTE);
16089 }
16090 }
16091}
16092
f511b01c
TI
16093#define alc662_auto_init_input_src alc882_auto_init_input_src
16094
bc9f98a9
KY
16095static int alc662_parse_auto_config(struct hda_codec *codec)
16096{
16097 struct alc_spec *spec = codec->spec;
16098 int err;
16099 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16100
16101 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16102 alc662_ignore);
16103 if (err < 0)
16104 return err;
16105 if (!spec->autocfg.line_outs)
16106 return 0; /* can't find valid BIOS pin config */
16107
f12ab1e0
TI
16108 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16109 if (err < 0)
16110 return err;
16111 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16112 if (err < 0)
16113 return err;
16114 err = alc662_auto_create_extra_out(spec,
16115 spec->autocfg.speaker_pins[0],
16116 "Speaker");
16117 if (err < 0)
16118 return err;
16119 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16120 "Headphone");
16121 if (err < 0)
16122 return err;
16123 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16124 if (err < 0)
bc9f98a9
KY
16125 return err;
16126
16127 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16128
16129 if (spec->autocfg.dig_out_pin)
16130 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16131
16132 if (spec->kctl_alloc)
16133 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
16134
16135 spec->num_mux_defs = 1;
16136 spec->input_mux = &spec->private_imux;
ea1fb29a 16137
8c87286f 16138 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
24fb9173
TI
16139 if (codec->vendor_id == 0x10ec0663)
16140 spec->init_verbs[spec->num_init_verbs++] =
16141 alc663_auto_init_verbs;
ee979a14
TI
16142
16143 err = alc_auto_add_mic_boost(codec);
16144 if (err < 0)
16145 return err;
16146
bc9f98a9
KY
16147 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16148 spec->num_mixers++;
8c87286f 16149 return 1;
bc9f98a9
KY
16150}
16151
16152/* additional initialization for auto-configuration model */
16153static void alc662_auto_init(struct hda_codec *codec)
16154{
f6c7e546 16155 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
16156 alc662_auto_init_multi_out(codec);
16157 alc662_auto_init_hp_out(codec);
16158 alc662_auto_init_analog_input(codec);
f511b01c 16159 alc662_auto_init_input_src(codec);
f6c7e546
TI
16160 if (spec->unsol_event)
16161 alc_sku_automute(codec);
bc9f98a9
KY
16162}
16163
16164static int patch_alc662(struct hda_codec *codec)
16165{
16166 struct alc_spec *spec;
16167 int err, board_config;
16168
16169 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16170 if (!spec)
16171 return -ENOMEM;
16172
16173 codec->spec = spec;
16174
2c3bf9ab
TI
16175 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16176
bc9f98a9
KY
16177 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16178 alc662_models,
16179 alc662_cfg_tbl);
16180 if (board_config < 0) {
16181 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16182 "trying auto-probe from BIOS...\n");
16183 board_config = ALC662_AUTO;
16184 }
16185
16186 if (board_config == ALC662_AUTO) {
16187 /* automatic parse from the BIOS config */
16188 err = alc662_parse_auto_config(codec);
16189 if (err < 0) {
16190 alc_free(codec);
16191 return err;
8c87286f 16192 } else if (!err) {
bc9f98a9
KY
16193 printk(KERN_INFO
16194 "hda_codec: Cannot set up configuration "
16195 "from BIOS. Using base mode...\n");
16196 board_config = ALC662_3ST_2ch_DIG;
16197 }
16198 }
16199
16200 if (board_config != ALC662_AUTO)
16201 setup_preset(spec, &alc662_presets[board_config]);
16202
6dda9f4a
KY
16203 if (codec->vendor_id == 0x10ec0663) {
16204 spec->stream_name_analog = "ALC663 Analog";
16205 spec->stream_name_digital = "ALC663 Digital";
16206 } else {
16207 spec->stream_name_analog = "ALC662 Analog";
16208 spec->stream_name_digital = "ALC662 Digital";
16209 }
16210
bc9f98a9
KY
16211 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16212 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16213
bc9f98a9
KY
16214 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16215 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16216
e1406348
TI
16217 spec->adc_nids = alc662_adc_nids;
16218 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16219 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 16220
2134ea4f
TI
16221 spec->vmaster_nid = 0x02;
16222
bc9f98a9
KY
16223 codec->patch_ops = alc_patch_ops;
16224 if (board_config == ALC662_AUTO)
16225 spec->init_hook = alc662_auto_init;
cb53c626
TI
16226#ifdef CONFIG_SND_HDA_POWER_SAVE
16227 if (!spec->loopback.amplist)
16228 spec->loopback.amplist = alc662_loopbacks;
16229#endif
bc9f98a9
KY
16230
16231 return 0;
16232}
16233
1da177e4
LT
16234/*
16235 * patch entries
16236 */
16237struct hda_codec_preset snd_hda_preset_realtek[] = {
16238 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 16239 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 16240 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 16241 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 16242 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 16243 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 16244 .patch = patch_alc861 },
f32610ed
JS
16245 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16246 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16247 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
16248 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16249 .patch = patch_alc883 },
16250 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16251 .patch = patch_alc662 },
6dda9f4a 16252 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 16253 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 16254 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 16255 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
cb308f97 16256 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 16257 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 16258 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 16259 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 16260 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
16261 {} /* terminator */
16262};