]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] hda - Add ALC663 support
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
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,
df694daa
KY
75 ALC260_HP_3013,
76 ALC260_FUJITSU_S702X,
0bfc90e9 77 ALC260_ACER,
bc9f98a9
KY
78 ALC260_WILL,
79 ALC260_REPLACER_672V,
7cf51e48
JW
80#ifdef CONFIG_SND_DEBUG
81 ALC260_TEST,
82#endif
df694daa 83 ALC260_AUTO,
16ded525 84 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
85};
86
df694daa
KY
87/* ALC262 models */
88enum {
89 ALC262_BASIC,
ccc656ce
KY
90 ALC262_HIPPO,
91 ALC262_HIPPO_1,
834be88d 92 ALC262_FUJITSU,
9c7f852e 93 ALC262_HP_BPC,
cd7509a4
KY
94 ALC262_HP_BPC_D7000_WL,
95 ALC262_HP_BPC_D7000_WF,
66d2a9d6 96 ALC262_HP_TC_T5735,
8c427226 97 ALC262_HP_RP5700,
304dcaac 98 ALC262_BENQ_ED8,
272a527c 99 ALC262_SONY_ASSAMD,
83c34218 100 ALC262_BENQ_T31,
f651b50b 101 ALC262_ULTRA,
0e31daf7 102 ALC262_LENOVO_3000,
df694daa
KY
103 ALC262_AUTO,
104 ALC262_MODEL_LAST /* last tag */
105};
106
a361d84b
KY
107/* ALC268 models */
108enum {
eb5a6621 109 ALC267_QUANTA_IL1,
a361d84b 110 ALC268_3ST,
d1a991a6 111 ALC268_TOSHIBA,
d273809e 112 ALC268_ACER,
3866f0b0 113 ALC268_DELL,
f12462c5 114 ALC268_ZEPTO,
86c53bd2
JW
115#ifdef CONFIG_SND_DEBUG
116 ALC268_TEST,
117#endif
a361d84b
KY
118 ALC268_AUTO,
119 ALC268_MODEL_LAST /* last tag */
120};
121
f6a92248
KY
122/* ALC269 models */
123enum {
124 ALC269_BASIC,
125 ALC269_AUTO,
126 ALC269_MODEL_LAST /* last tag */
127};
128
df694daa
KY
129/* ALC861 models */
130enum {
131 ALC861_3ST,
9c7f852e 132 ALC660_3ST,
df694daa
KY
133 ALC861_3ST_DIG,
134 ALC861_6ST_DIG,
22309c3e 135 ALC861_UNIWILL_M31,
a53d1aec 136 ALC861_TOSHIBA,
7cdbff94 137 ALC861_ASUS,
56bb0cab 138 ALC861_ASUS_LAPTOP,
df694daa
KY
139 ALC861_AUTO,
140 ALC861_MODEL_LAST,
141};
142
f32610ed
JS
143/* ALC861-VD models */
144enum {
145 ALC660VD_3ST,
6963f84c 146 ALC660VD_3ST_DIG,
f32610ed
JS
147 ALC861VD_3ST,
148 ALC861VD_3ST_DIG,
149 ALC861VD_6ST_DIG,
bdd148a3 150 ALC861VD_LENOVO,
272a527c 151 ALC861VD_DALLAS,
d1a991a6 152 ALC861VD_HP,
f32610ed
JS
153 ALC861VD_AUTO,
154 ALC861VD_MODEL_LAST,
155};
156
bc9f98a9
KY
157/* ALC662 models */
158enum {
159 ALC662_3ST_2ch_DIG,
160 ALC662_3ST_6ch_DIG,
161 ALC662_3ST_6ch,
162 ALC662_5ST_DIG,
163 ALC662_LENOVO_101E,
291702f0 164 ALC662_ASUS_EEEPC_P701,
8c427226 165 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
166 ALC663_ASUS_M51VA,
167 ALC663_ASUS_G71V,
168 ALC663_ASUS_H13,
169 ALC663_ASUS_G50V,
bc9f98a9
KY
170 ALC662_AUTO,
171 ALC662_MODEL_LAST,
172};
173
df694daa
KY
174/* ALC882 models */
175enum {
176 ALC882_3ST_DIG,
177 ALC882_6ST_DIG,
4b146cb0 178 ALC882_ARIMA,
bdd148a3 179 ALC882_W2JC,
272a527c
KY
180 ALC882_TARGA,
181 ALC882_ASUS_A7J,
914759b7 182 ALC882_ASUS_A7M,
9102cd1c 183 ALC885_MACPRO,
87350ad0 184 ALC885_MBP3,
c54728d8 185 ALC885_IMAC24,
272a527c 186 ALC882_AUTO,
df694daa
KY
187 ALC882_MODEL_LAST,
188};
189
9c7f852e
TI
190/* ALC883 models */
191enum {
192 ALC883_3ST_2ch_DIG,
193 ALC883_3ST_6ch_DIG,
194 ALC883_3ST_6ch,
195 ALC883_6ST_DIG,
ccc656ce
KY
196 ALC883_TARGA_DIG,
197 ALC883_TARGA_2ch_DIG,
bab282b9 198 ALC883_ACER,
2880a867 199 ALC883_ACER_ASPIRE,
c07584c8 200 ALC883_MEDION,
272a527c 201 ALC883_MEDION_MD2,
b373bdeb 202 ALC883_LAPTOP_EAPD,
bc9f98a9 203 ALC883_LENOVO_101E_2ch,
272a527c 204 ALC883_LENOVO_NB0763,
189609ae
KY
205 ALC888_LENOVO_MS7195_DIG,
206 ALC883_HAIER_W66,
4723c022 207 ALC888_3ST_HP,
5795b9e6 208 ALC888_6ST_DELL,
a8848bd6 209 ALC883_MITAC,
0c4cc443 210 ALC883_CLEVO_M720,
fb97dc67 211 ALC883_FUJITSU_PI2515,
9c7f852e
TI
212 ALC883_AUTO,
213 ALC883_MODEL_LAST,
214};
215
df694daa
KY
216/* for GPIO Poll */
217#define GPIO_MASK 0x03
218
1da177e4
LT
219struct alc_spec {
220 /* codec parameterization */
df694daa 221 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
222 unsigned int num_mixers;
223
df694daa 224 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
225 * don't forget NULL
226 * termination!
e9edcee0
TI
227 */
228 unsigned int num_init_verbs;
1da177e4 229
16ded525 230 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
231 struct hda_pcm_stream *stream_analog_playback;
232 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
233 struct hda_pcm_stream *stream_analog_alt_playback;
234 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 235
f12ab1e0 236 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
237 struct hda_pcm_stream *stream_digital_playback;
238 struct hda_pcm_stream *stream_digital_capture;
239
240 /* playback */
16ded525
TI
241 struct hda_multi_out multiout; /* playback set-up
242 * max_channels, dacs must be set
243 * dig_out_nid and hp_nid are optional
244 */
6330079f 245 hda_nid_t alt_dac_nid;
1da177e4
LT
246
247 /* capture */
248 unsigned int num_adc_nids;
249 hda_nid_t *adc_nids;
e1406348 250 hda_nid_t *capsrc_nids;
16ded525 251 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
252
253 /* capture source */
a1e8d2da 254 unsigned int num_mux_defs;
1da177e4
LT
255 const struct hda_input_mux *input_mux;
256 unsigned int cur_mux[3];
257
258 /* channel model */
d2a6d7dc 259 const struct hda_channel_mode *channel_mode;
1da177e4 260 int num_channel_mode;
4e195a7b 261 int need_dac_fix;
1da177e4
LT
262
263 /* PCM information */
4c5186ed 264 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 265
e9edcee0
TI
266 /* dynamic controls, init_verbs and input_mux */
267 struct auto_pin_cfg autocfg;
268 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 269 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 270 struct hda_input_mux private_imux;
41923e44 271 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 272
ae6b813a
TI
273 /* hooks */
274 void (*init_hook)(struct hda_codec *codec);
275 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
276
834be88d
TI
277 /* for pin sensing */
278 unsigned int sense_updated: 1;
279 unsigned int jack_present: 1;
bec15c3a 280 unsigned int master_sw: 1;
cb53c626 281
2134ea4f
TI
282 /* for virtual master */
283 hda_nid_t vmaster_nid;
cb53c626
TI
284#ifdef CONFIG_SND_HDA_POWER_SAVE
285 struct hda_loopback_check loopback;
286#endif
df694daa
KY
287};
288
289/*
290 * configuration template - to be copied to the spec instance
291 */
292struct alc_config_preset {
9c7f852e
TI
293 struct snd_kcontrol_new *mixers[5]; /* should be identical size
294 * with spec
295 */
df694daa
KY
296 const struct hda_verb *init_verbs[5];
297 unsigned int num_dacs;
298 hda_nid_t *dac_nids;
299 hda_nid_t dig_out_nid; /* optional */
300 hda_nid_t hp_nid; /* optional */
301 unsigned int num_adc_nids;
302 hda_nid_t *adc_nids;
e1406348 303 hda_nid_t *capsrc_nids;
df694daa
KY
304 hda_nid_t dig_in_nid;
305 unsigned int num_channel_mode;
306 const struct hda_channel_mode *channel_mode;
4e195a7b 307 int need_dac_fix;
a1e8d2da 308 unsigned int num_mux_defs;
df694daa 309 const struct hda_input_mux *input_mux;
ae6b813a
TI
310 void (*unsol_event)(struct hda_codec *, unsigned int);
311 void (*init_hook)(struct hda_codec *);
cb53c626
TI
312#ifdef CONFIG_SND_HDA_POWER_SAVE
313 struct hda_amp_list *loopbacks;
314#endif
1da177e4
LT
315};
316
1da177e4
LT
317
318/*
319 * input MUX handling
320 */
9c7f852e
TI
321static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
323{
324 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
325 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
326 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
327 if (mux_idx >= spec->num_mux_defs)
328 mux_idx = 0;
329 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
330}
331
9c7f852e
TI
332static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
334{
335 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
336 struct alc_spec *spec = codec->spec;
337 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
338
339 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
340 return 0;
341}
342
9c7f852e
TI
343static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
345{
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct alc_spec *spec = codec->spec;
348 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da 349 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
e1406348
TI
350 hda_nid_t nid = spec->capsrc_nids ?
351 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
a1e8d2da 352 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
e1406348 353 nid, &spec->cur_mux[adc_idx]);
1da177e4
LT
354}
355
e9edcee0 356
1da177e4
LT
357/*
358 * channel mode setting
359 */
9c7f852e
TI
360static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
361 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
362{
363 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
364 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
365 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
366 spec->num_channel_mode);
1da177e4
LT
367}
368
9c7f852e
TI
369static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
370 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
371{
372 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
373 struct alc_spec *spec = codec->spec;
d2a6d7dc 374 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
375 spec->num_channel_mode,
376 spec->multiout.max_channels);
1da177e4
LT
377}
378
9c7f852e
TI
379static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
380 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
381{
382 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
383 struct alc_spec *spec = codec->spec;
4e195a7b
TI
384 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
385 spec->num_channel_mode,
386 &spec->multiout.max_channels);
bd2033f2 387 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
388 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
389 return err;
1da177e4
LT
390}
391
a9430dd8 392/*
4c5186ed
JW
393 * Control the mode of pin widget settings via the mixer. "pc" is used
394 * instead of "%" to avoid consequences of accidently treating the % as
395 * being part of a format specifier. Maximum allowed length of a value is
396 * 63 characters plus NULL terminator.
7cf51e48
JW
397 *
398 * Note: some retasking pin complexes seem to ignore requests for input
399 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
400 * are requested. Therefore order this list so that this behaviour will not
401 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
402 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
403 * March 2006.
4c5186ed
JW
404 */
405static char *alc_pin_mode_names[] = {
7cf51e48
JW
406 "Mic 50pc bias", "Mic 80pc bias",
407 "Line in", "Line out", "Headphone out",
4c5186ed
JW
408};
409static unsigned char alc_pin_mode_values[] = {
7cf51e48 410 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
411};
412/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
413 * in the pin being assumed to be exclusively an input or an output pin. In
414 * addition, "input" pins may or may not process the mic bias option
415 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
416 * accept requests for bias as of chip versions up to March 2006) and/or
417 * wiring in the computer.
a9430dd8 418 */
a1e8d2da
JW
419#define ALC_PIN_DIR_IN 0x00
420#define ALC_PIN_DIR_OUT 0x01
421#define ALC_PIN_DIR_INOUT 0x02
422#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
423#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 424
a1e8d2da 425/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
426 * For each direction the minimum and maximum values are given.
427 */
a1e8d2da 428static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
429 { 0, 2 }, /* ALC_PIN_DIR_IN */
430 { 3, 4 }, /* ALC_PIN_DIR_OUT */
431 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
432 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
433 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
434};
435#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
436#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
437#define alc_pin_mode_n_items(_dir) \
438 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
439
9c7f852e
TI
440static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
441 struct snd_ctl_elem_info *uinfo)
a9430dd8 442{
4c5186ed
JW
443 unsigned int item_num = uinfo->value.enumerated.item;
444 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
445
446 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 447 uinfo->count = 1;
4c5186ed
JW
448 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
449
450 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
451 item_num = alc_pin_mode_min(dir);
452 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
453 return 0;
454}
455
9c7f852e
TI
456static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
a9430dd8 458{
4c5186ed 459 unsigned int i;
a9430dd8
JW
460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
461 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 462 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 463 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
464 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
465 AC_VERB_GET_PIN_WIDGET_CONTROL,
466 0x00);
a9430dd8 467
4c5186ed
JW
468 /* Find enumerated value for current pinctl setting */
469 i = alc_pin_mode_min(dir);
9c7f852e 470 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 471 i++;
9c7f852e 472 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
473 return 0;
474}
475
9c7f852e
TI
476static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
477 struct snd_ctl_elem_value *ucontrol)
a9430dd8 478{
4c5186ed 479 signed int change;
a9430dd8
JW
480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
481 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
482 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
483 long val = *ucontrol->value.integer.value;
9c7f852e
TI
484 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
485 AC_VERB_GET_PIN_WIDGET_CONTROL,
486 0x00);
a9430dd8 487
f12ab1e0 488 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
489 val = alc_pin_mode_min(dir);
490
491 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
492 if (change) {
493 /* Set pin mode to that requested */
82beb8fd
TI
494 snd_hda_codec_write_cache(codec, nid, 0,
495 AC_VERB_SET_PIN_WIDGET_CONTROL,
496 alc_pin_mode_values[val]);
cdcd9268
JW
497
498 /* Also enable the retasking pin's input/output as required
499 * for the requested pin mode. Enum values of 2 or less are
500 * input modes.
501 *
502 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
503 * reduces noise slightly (particularly on input) so we'll
504 * do it. However, having both input and output buffers
505 * enabled simultaneously doesn't seem to be problematic if
506 * this turns out to be necessary in the future.
cdcd9268
JW
507 */
508 if (val <= 2) {
47fd830a
TI
509 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
510 HDA_AMP_MUTE, HDA_AMP_MUTE);
511 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
512 HDA_AMP_MUTE, 0);
cdcd9268 513 } else {
47fd830a
TI
514 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
515 HDA_AMP_MUTE, HDA_AMP_MUTE);
516 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
517 HDA_AMP_MUTE, 0);
cdcd9268
JW
518 }
519 }
a9430dd8
JW
520 return change;
521}
522
4c5186ed 523#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 524 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
525 .info = alc_pin_mode_info, \
526 .get = alc_pin_mode_get, \
527 .put = alc_pin_mode_put, \
528 .private_value = nid | (dir<<16) }
df694daa 529
5c8f858d
JW
530/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
531 * together using a mask with more than one bit set. This control is
532 * currently used only by the ALC260 test model. At this stage they are not
533 * needed for any "production" models.
534 */
535#ifdef CONFIG_SND_DEBUG
a5ce8890 536#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 537
9c7f852e
TI
538static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
540{
541 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
542 hda_nid_t nid = kcontrol->private_value & 0xffff;
543 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
544 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
545 unsigned int val = snd_hda_codec_read(codec, nid, 0,
546 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
547
548 *valp = (val & mask) != 0;
549 return 0;
550}
9c7f852e
TI
551static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
553{
554 signed int change;
555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
556 hda_nid_t nid = kcontrol->private_value & 0xffff;
557 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
558 long val = *ucontrol->value.integer.value;
9c7f852e
TI
559 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
560 AC_VERB_GET_GPIO_DATA,
561 0x00);
5c8f858d
JW
562
563 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
564 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
565 if (val == 0)
5c8f858d
JW
566 gpio_data &= ~mask;
567 else
568 gpio_data |= mask;
82beb8fd
TI
569 snd_hda_codec_write_cache(codec, nid, 0,
570 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
571
572 return change;
573}
574#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
575 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
576 .info = alc_gpio_data_info, \
577 .get = alc_gpio_data_get, \
578 .put = alc_gpio_data_put, \
579 .private_value = nid | (mask<<16) }
580#endif /* CONFIG_SND_DEBUG */
581
92621f13
JW
582/* A switch control to allow the enabling of the digital IO pins on the
583 * ALC260. This is incredibly simplistic; the intention of this control is
584 * to provide something in the test model allowing digital outputs to be
585 * identified if present. If models are found which can utilise these
586 * outputs a more complete mixer control can be devised for those models if
587 * necessary.
588 */
589#ifdef CONFIG_SND_DEBUG
a5ce8890 590#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 591
9c7f852e
TI
592static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
593 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
594{
595 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
596 hda_nid_t nid = kcontrol->private_value & 0xffff;
597 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
598 long *valp = ucontrol->value.integer.value;
9c7f852e 599 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 600 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
601
602 *valp = (val & mask) != 0;
603 return 0;
604}
9c7f852e
TI
605static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
606 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
607{
608 signed int change;
609 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
610 hda_nid_t nid = kcontrol->private_value & 0xffff;
611 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
612 long val = *ucontrol->value.integer.value;
9c7f852e 613 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 614 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 615 0x00);
92621f13
JW
616
617 /* Set/unset the masked control bit(s) as needed */
9c7f852e 618 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
619 if (val==0)
620 ctrl_data &= ~mask;
621 else
622 ctrl_data |= mask;
82beb8fd
TI
623 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
624 ctrl_data);
92621f13
JW
625
626 return change;
627}
628#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
629 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
630 .info = alc_spdif_ctrl_info, \
631 .get = alc_spdif_ctrl_get, \
632 .put = alc_spdif_ctrl_put, \
633 .private_value = nid | (mask<<16) }
634#endif /* CONFIG_SND_DEBUG */
635
f8225f6d
JW
636/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
637 * Again, this is only used in the ALC26x test models to help identify when
638 * the EAPD line must be asserted for features to work.
639 */
640#ifdef CONFIG_SND_DEBUG
641#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
642
643static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol)
645{
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
648 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
649 long *valp = ucontrol->value.integer.value;
650 unsigned int val = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
652
653 *valp = (val & mask) != 0;
654 return 0;
655}
656
657static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
658 struct snd_ctl_elem_value *ucontrol)
659{
660 int change;
661 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
662 hda_nid_t nid = kcontrol->private_value & 0xffff;
663 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
664 long val = *ucontrol->value.integer.value;
665 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
666 AC_VERB_GET_EAPD_BTLENABLE,
667 0x00);
668
669 /* Set/unset the masked control bit(s) as needed */
670 change = (!val ? 0 : mask) != (ctrl_data & mask);
671 if (!val)
672 ctrl_data &= ~mask;
673 else
674 ctrl_data |= mask;
675 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
676 ctrl_data);
677
678 return change;
679}
680
681#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
682 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
683 .info = alc_eapd_ctrl_info, \
684 .get = alc_eapd_ctrl_get, \
685 .put = alc_eapd_ctrl_put, \
686 .private_value = nid | (mask<<16) }
687#endif /* CONFIG_SND_DEBUG */
688
df694daa
KY
689/*
690 * set up from the preset table
691 */
9c7f852e
TI
692static void setup_preset(struct alc_spec *spec,
693 const struct alc_config_preset *preset)
df694daa
KY
694{
695 int i;
696
697 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
698 spec->mixers[spec->num_mixers++] = preset->mixers[i];
9c7f852e
TI
699 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
700 i++)
701 spec->init_verbs[spec->num_init_verbs++] =
702 preset->init_verbs[i];
df694daa
KY
703
704 spec->channel_mode = preset->channel_mode;
705 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 706 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
707
708 spec->multiout.max_channels = spec->channel_mode[0].channels;
709
710 spec->multiout.num_dacs = preset->num_dacs;
711 spec->multiout.dac_nids = preset->dac_nids;
712 spec->multiout.dig_out_nid = preset->dig_out_nid;
713 spec->multiout.hp_nid = preset->hp_nid;
714
a1e8d2da 715 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 716 if (!spec->num_mux_defs)
a1e8d2da 717 spec->num_mux_defs = 1;
df694daa
KY
718 spec->input_mux = preset->input_mux;
719
720 spec->num_adc_nids = preset->num_adc_nids;
721 spec->adc_nids = preset->adc_nids;
e1406348 722 spec->capsrc_nids = preset->capsrc_nids;
df694daa 723 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
724
725 spec->unsol_event = preset->unsol_event;
726 spec->init_hook = preset->init_hook;
cb53c626
TI
727#ifdef CONFIG_SND_HDA_POWER_SAVE
728 spec->loopback.amplist = preset->loopbacks;
729#endif
df694daa
KY
730}
731
bc9f98a9
KY
732/* Enable GPIO mask and set output */
733static struct hda_verb alc_gpio1_init_verbs[] = {
734 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
735 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
736 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
737 { }
738};
739
740static struct hda_verb alc_gpio2_init_verbs[] = {
741 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
742 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
743 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
744 { }
745};
746
bdd148a3
KY
747static struct hda_verb alc_gpio3_init_verbs[] = {
748 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
749 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
750 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
751 { }
752};
753
c9b58006
KY
754static void alc_sku_automute(struct hda_codec *codec)
755{
756 struct alc_spec *spec = codec->spec;
c9b58006
KY
757 unsigned int present;
758 unsigned int hp_nid = spec->autocfg.hp_pins[0];
759 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
760
761 /* need to execute and sync at first */
762 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
763 present = snd_hda_codec_read(codec, hp_nid, 0,
764 AC_VERB_GET_PIN_SENSE, 0);
765 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
766 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
767 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
768}
769
770/* unsolicited event for HP jack sensing */
771static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
772{
773 if (codec->vendor_id == 0x10ec0880)
774 res >>= 28;
775 else
776 res >>= 26;
777 if (res != ALC880_HP_EVENT)
778 return;
779
780 alc_sku_automute(codec);
781}
782
bc9f98a9
KY
783/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
784 * 31 ~ 16 : Manufacture ID
785 * 15 ~ 8 : SKU ID
786 * 7 ~ 0 : Assembly ID
787 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
788 */
789static void alc_subsystem_id(struct hda_codec *codec,
790 unsigned int porta, unsigned int porte,
791 unsigned int portd)
792{
c9b58006
KY
793 unsigned int ass, tmp, i;
794 unsigned nid;
795 struct alc_spec *spec = codec->spec;
bc9f98a9 796
c9b58006
KY
797 ass = codec->subsystem_id & 0xffff;
798 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
799 goto do_sku;
800
801 /*
802 * 31~30 : port conetcivity
803 * 29~21 : reserve
804 * 20 : PCBEEP input
805 * 19~16 : Check sum (15:1)
806 * 15~1 : Custom
807 * 0 : override
808 */
809 nid = 0x1d;
810 if (codec->vendor_id == 0x10ec0260)
811 nid = 0x17;
812 ass = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_CONFIG_DEFAULT, 0);
814 if (!(ass & 1) && !(ass & 0x100000))
815 return;
816 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
817 return;
818
c9b58006
KY
819 /* check sum */
820 tmp = 0;
821 for (i = 1; i < 16; i++) {
8c427226 822 if ((ass >> i) & 1)
c9b58006
KY
823 tmp++;
824 }
825 if (((ass >> 16) & 0xf) != tmp)
826 return;
827do_sku:
828 /*
829 * 0 : override
830 * 1 : Swap Jack
831 * 2 : 0 --> Desktop, 1 --> Laptop
832 * 3~5 : External Amplifier control
833 * 7~6 : Reserved
834 */
bc9f98a9
KY
835 tmp = (ass & 0x38) >> 3; /* external Amp control */
836 switch (tmp) {
837 case 1:
838 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
839 break;
840 case 3:
841 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
842 break;
bdd148a3
KY
843 case 7:
844 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
845 break;
c9b58006 846 case 5: /* set EAPD output high */
bdd148a3 847 switch (codec->vendor_id) {
c9b58006
KY
848 case 0x10ec0260:
849 snd_hda_codec_write(codec, 0x0f, 0,
850 AC_VERB_SET_EAPD_BTLENABLE, 2);
851 snd_hda_codec_write(codec, 0x10, 0,
852 AC_VERB_SET_EAPD_BTLENABLE, 2);
853 break;
854 case 0x10ec0262:
bdd148a3
KY
855 case 0x10ec0267:
856 case 0x10ec0268:
c9b58006
KY
857 case 0x10ec0269:
858 case 0x10ec0862:
859 case 0x10ec0662:
20a3a05d 860 case 0x10ec0889:
bdd148a3
KY
861 snd_hda_codec_write(codec, 0x14, 0,
862 AC_VERB_SET_EAPD_BTLENABLE, 2);
863 snd_hda_codec_write(codec, 0x15, 0,
864 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 865 break;
bdd148a3 866 }
c9b58006
KY
867 switch (codec->vendor_id) {
868 case 0x10ec0260:
869 snd_hda_codec_write(codec, 0x1a, 0,
870 AC_VERB_SET_COEF_INDEX, 7);
871 tmp = snd_hda_codec_read(codec, 0x1a, 0,
872 AC_VERB_GET_PROC_COEF, 0);
873 snd_hda_codec_write(codec, 0x1a, 0,
874 AC_VERB_SET_COEF_INDEX, 7);
875 snd_hda_codec_write(codec, 0x1a, 0,
876 AC_VERB_SET_PROC_COEF,
877 tmp | 0x2010);
878 break;
879 case 0x10ec0262:
880 case 0x10ec0880:
881 case 0x10ec0882:
882 case 0x10ec0883:
883 case 0x10ec0885:
884 case 0x10ec0888:
20a3a05d 885 case 0x10ec0889:
c9b58006
KY
886 snd_hda_codec_write(codec, 0x20, 0,
887 AC_VERB_SET_COEF_INDEX, 7);
888 tmp = snd_hda_codec_read(codec, 0x20, 0,
889 AC_VERB_GET_PROC_COEF, 0);
890 snd_hda_codec_write(codec, 0x20, 0,
891 AC_VERB_SET_COEF_INDEX, 7);
892 snd_hda_codec_write(codec, 0x20, 0,
893 AC_VERB_SET_PROC_COEF,
894 tmp | 0x2010);
895 break;
896 case 0x10ec0267:
897 case 0x10ec0268:
898 snd_hda_codec_write(codec, 0x20, 0,
899 AC_VERB_SET_COEF_INDEX, 7);
900 tmp = snd_hda_codec_read(codec, 0x20, 0,
901 AC_VERB_GET_PROC_COEF, 0);
902 snd_hda_codec_write(codec, 0x20, 0,
903 AC_VERB_SET_COEF_INDEX, 7);
904 snd_hda_codec_write(codec, 0x20, 0,
905 AC_VERB_SET_PROC_COEF,
906 tmp | 0x3000);
907 break;
bc9f98a9 908 }
c9b58006 909 default:
bc9f98a9
KY
910 break;
911 }
c9b58006 912
8c427226 913 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
914 * when the external headphone out jack is plugged"
915 */
8c427226 916 if (!(ass & 0x8000))
c9b58006
KY
917 return;
918 /*
919 * 10~8 : Jack location
920 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
921 * 14~13: Resvered
922 * 15 : 1 --> enable the function "Mute internal speaker
923 * when the external headphone out jack is plugged"
924 */
925 if (!spec->autocfg.speaker_pins[0]) {
8c427226 926 if (spec->autocfg.line_out_pins[0])
c9b58006 927 spec->autocfg.speaker_pins[0] =
8c427226 928 spec->autocfg.line_out_pins[0];
c9b58006
KY
929 else
930 return;
931 }
932
933 if (!spec->autocfg.hp_pins[0]) {
934 tmp = (ass >> 11) & 0x3; /* HP to chassis */
935 if (tmp == 0)
936 spec->autocfg.hp_pins[0] = porta;
937 else if (tmp == 1)
938 spec->autocfg.hp_pins[0] = porte;
939 else if (tmp == 2)
940 spec->autocfg.hp_pins[0] = portd;
941 else
942 return;
943 }
944
945 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
946 AC_VERB_SET_UNSOLICITED_ENABLE,
947 AC_USRSP_EN | ALC880_HP_EVENT);
948 spec->unsol_event = alc_sku_unsol_event;
bc9f98a9
KY
949}
950
f95474ec
TI
951/*
952 * Fix-up pin default configurations
953 */
954
955struct alc_pincfg {
956 hda_nid_t nid;
957 u32 val;
958};
959
960static void alc_fix_pincfg(struct hda_codec *codec,
961 const struct snd_pci_quirk *quirk,
962 const struct alc_pincfg **pinfix)
963{
964 const struct alc_pincfg *cfg;
965
966 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
967 if (!quirk)
968 return;
969
970 cfg = pinfix[quirk->value];
971 for (; cfg->nid; cfg++) {
972 int i;
973 u32 val = cfg->val;
974 for (i = 0; i < 4; i++) {
975 snd_hda_codec_write(codec, cfg->nid, 0,
976 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
977 val & 0xff);
978 val >>= 8;
979 }
980 }
981}
982
1da177e4 983/*
e9edcee0
TI
984 * ALC880 3-stack model
985 *
986 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
987 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
988 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
989 */
990
e9edcee0
TI
991static hda_nid_t alc880_dac_nids[4] = {
992 /* front, rear, clfe, rear_surr */
993 0x02, 0x05, 0x04, 0x03
994};
995
996static hda_nid_t alc880_adc_nids[3] = {
997 /* ADC0-2 */
998 0x07, 0x08, 0x09,
999};
1000
1001/* The datasheet says the node 0x07 is connected from inputs,
1002 * but it shows zero connection in the real implementation on some devices.
df694daa 1003 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1004 */
e9edcee0
TI
1005static hda_nid_t alc880_adc_nids_alt[2] = {
1006 /* ADC1-2 */
1007 0x08, 0x09,
1008};
1009
1010#define ALC880_DIGOUT_NID 0x06
1011#define ALC880_DIGIN_NID 0x0a
1012
1013static struct hda_input_mux alc880_capture_source = {
1014 .num_items = 4,
1015 .items = {
1016 { "Mic", 0x0 },
1017 { "Front Mic", 0x3 },
1018 { "Line", 0x2 },
1019 { "CD", 0x4 },
1020 },
1021};
1022
1023/* channel source setting (2/6 channel selection for 3-stack) */
1024/* 2ch mode */
1025static struct hda_verb alc880_threestack_ch2_init[] = {
1026 /* set line-in to input, mute it */
1027 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1028 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1029 /* set mic-in to input vref 80%, mute it */
1030 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1031 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1032 { } /* end */
1033};
1034
1035/* 6ch mode */
1036static struct hda_verb alc880_threestack_ch6_init[] = {
1037 /* set line-in to output, unmute it */
1038 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1039 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1040 /* set mic-in to output, unmute it */
1041 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1042 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1043 { } /* end */
1044};
1045
d2a6d7dc 1046static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1047 { 2, alc880_threestack_ch2_init },
1048 { 6, alc880_threestack_ch6_init },
1049};
1050
c8b6bf9b 1051static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1054 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1055 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1056 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1057 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1058 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1059 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1060 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1061 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1065 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1066 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1067 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1068 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1069 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1070 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1071 {
1072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1073 .name = "Channel Mode",
df694daa
KY
1074 .info = alc_ch_mode_info,
1075 .get = alc_ch_mode_get,
1076 .put = alc_ch_mode_put,
e9edcee0
TI
1077 },
1078 { } /* end */
1079};
1080
1081/* capture mixer elements */
c8b6bf9b 1082static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1083 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1084 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1085 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1086 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1087 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1088 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1089 {
1090 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1091 /* The multiple "Capture Source" controls confuse alsamixer
1092 * So call somewhat different..
1da177e4
LT
1093 */
1094 /* .name = "Capture Source", */
1095 .name = "Input Source",
e9edcee0 1096 .count = 3,
1da177e4
LT
1097 .info = alc_mux_enum_info,
1098 .get = alc_mux_enum_get,
1099 .put = alc_mux_enum_put,
1100 },
1da177e4
LT
1101 { } /* end */
1102};
1103
e9edcee0 1104/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1105static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1106 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1107 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1108 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1109 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1110 {
1111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1112 /* The multiple "Capture Source" controls confuse alsamixer
1113 * So call somewhat different..
1da177e4
LT
1114 */
1115 /* .name = "Capture Source", */
1116 .name = "Input Source",
1117 .count = 2,
1118 .info = alc_mux_enum_info,
1119 .get = alc_mux_enum_get,
1120 .put = alc_mux_enum_put,
1121 },
1da177e4
LT
1122 { } /* end */
1123};
1124
e9edcee0
TI
1125
1126
1127/*
1128 * ALC880 5-stack model
1129 *
9c7f852e
TI
1130 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1131 * Side = 0x02 (0xd)
e9edcee0
TI
1132 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1133 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1134 */
1135
1136/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1137static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1138 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1139 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1140 { } /* end */
1141};
1142
e9edcee0
TI
1143/* channel source setting (6/8 channel selection for 5-stack) */
1144/* 6ch mode */
1145static struct hda_verb alc880_fivestack_ch6_init[] = {
1146 /* set line-in to input, mute it */
1147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1149 { } /* end */
1150};
1151
e9edcee0
TI
1152/* 8ch mode */
1153static struct hda_verb alc880_fivestack_ch8_init[] = {
1154 /* set line-in to output, unmute it */
1155 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1156 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1157 { } /* end */
1158};
1159
d2a6d7dc 1160static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1161 { 6, alc880_fivestack_ch6_init },
1162 { 8, alc880_fivestack_ch8_init },
1163};
1164
1165
1166/*
1167 * ALC880 6-stack model
1168 *
9c7f852e
TI
1169 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1170 * Side = 0x05 (0x0f)
e9edcee0
TI
1171 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1172 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1173 */
1174
1175static hda_nid_t alc880_6st_dac_nids[4] = {
1176 /* front, rear, clfe, rear_surr */
1177 0x02, 0x03, 0x04, 0x05
f12ab1e0 1178};
e9edcee0
TI
1179
1180static struct hda_input_mux alc880_6stack_capture_source = {
1181 .num_items = 4,
1182 .items = {
1183 { "Mic", 0x0 },
1184 { "Front Mic", 0x1 },
1185 { "Line", 0x2 },
1186 { "CD", 0x4 },
1187 },
1188};
1189
1190/* fixed 8-channels */
d2a6d7dc 1191static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1192 { 8, NULL },
1193};
1194
c8b6bf9b 1195static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1198 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1199 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1200 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1201 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1202 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1203 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1204 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1205 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1206 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1207 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1212 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1213 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1214 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1215 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1216 {
1217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1218 .name = "Channel Mode",
df694daa
KY
1219 .info = alc_ch_mode_info,
1220 .get = alc_ch_mode_get,
1221 .put = alc_ch_mode_put,
16ded525
TI
1222 },
1223 { } /* end */
1224};
1225
e9edcee0
TI
1226
1227/*
1228 * ALC880 W810 model
1229 *
1230 * W810 has rear IO for:
1231 * Front (DAC 02)
1232 * Surround (DAC 03)
1233 * Center/LFE (DAC 04)
1234 * Digital out (06)
1235 *
1236 * The system also has a pair of internal speakers, and a headphone jack.
1237 * These are both connected to Line2 on the codec, hence to DAC 02.
1238 *
1239 * There is a variable resistor to control the speaker or headphone
1240 * volume. This is a hardware-only device without a software API.
1241 *
1242 * Plugging headphones in will disable the internal speakers. This is
1243 * implemented in hardware, not via the driver using jack sense. In
1244 * a similar fashion, plugging into the rear socket marked "front" will
1245 * disable both the speakers and headphones.
1246 *
1247 * For input, there's a microphone jack, and an "audio in" jack.
1248 * These may not do anything useful with this driver yet, because I
1249 * haven't setup any initialization verbs for these yet...
1250 */
1251
1252static hda_nid_t alc880_w810_dac_nids[3] = {
1253 /* front, rear/surround, clfe */
1254 0x02, 0x03, 0x04
16ded525
TI
1255};
1256
e9edcee0 1257/* fixed 6 channels */
d2a6d7dc 1258static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1259 { 6, NULL }
1260};
1261
1262/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1263static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1264 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1265 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1266 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1267 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1268 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1269 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1270 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1271 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1272 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1273 { } /* end */
1274};
1275
1276
1277/*
1278 * Z710V model
1279 *
1280 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1281 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1282 * Line = 0x1a
e9edcee0
TI
1283 */
1284
1285static hda_nid_t alc880_z71v_dac_nids[1] = {
1286 0x02
1287};
1288#define ALC880_Z71V_HP_DAC 0x03
1289
1290/* fixed 2 channels */
d2a6d7dc 1291static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1292 { 2, NULL }
1293};
1294
c8b6bf9b 1295static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1296 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1297 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1298 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1299 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1304 { } /* end */
1305};
1306
e9edcee0 1307
e9edcee0
TI
1308/*
1309 * ALC880 F1734 model
1310 *
1311 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1312 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1313 */
1314
1315static hda_nid_t alc880_f1734_dac_nids[1] = {
1316 0x03
1317};
1318#define ALC880_F1734_HP_DAC 0x02
1319
c8b6bf9b 1320static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1321 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1322 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1323 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1324 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1325 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1326 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1329 { } /* end */
1330};
1331
937b4160
TI
1332static struct hda_input_mux alc880_f1734_capture_source = {
1333 .num_items = 2,
1334 .items = {
1335 { "Mic", 0x1 },
1336 { "CD", 0x4 },
1337 },
1338};
1339
e9edcee0 1340
e9edcee0
TI
1341/*
1342 * ALC880 ASUS model
1343 *
1344 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1345 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1346 * Mic = 0x18, Line = 0x1a
1347 */
1348
1349#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1350#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1351
c8b6bf9b 1352static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1354 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1355 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1356 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1357 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1358 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1359 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1360 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1361 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1362 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1363 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1364 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1365 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1366 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1367 {
1368 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1369 .name = "Channel Mode",
df694daa
KY
1370 .info = alc_ch_mode_info,
1371 .get = alc_ch_mode_get,
1372 .put = alc_ch_mode_put,
16ded525
TI
1373 },
1374 { } /* end */
1375};
e9edcee0 1376
e9edcee0
TI
1377/*
1378 * ALC880 ASUS W1V model
1379 *
1380 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1381 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1382 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1383 */
1384
1385/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1386static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1387 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1388 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1389 { } /* end */
1390};
1391
3c10a9d9 1392/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1393static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1394 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1395 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1396 { } /* end */
1397};
e9edcee0 1398
df694daa
KY
1399/* TCL S700 */
1400static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1401 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1402 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1404 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1405 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1408 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1409 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1410 {
1411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412 /* The multiple "Capture Source" controls confuse alsamixer
1413 * So call somewhat different..
df694daa
KY
1414 */
1415 /* .name = "Capture Source", */
1416 .name = "Input Source",
1417 .count = 1,
1418 .info = alc_mux_enum_info,
1419 .get = alc_mux_enum_get,
1420 .put = alc_mux_enum_put,
1421 },
1422 { } /* end */
1423};
1424
ccc656ce
KY
1425/* Uniwill */
1426static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1427 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1428 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1429 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1430 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1443 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1444 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1445 {
1446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1447 .name = "Channel Mode",
1448 .info = alc_ch_mode_info,
1449 .get = alc_ch_mode_get,
1450 .put = alc_ch_mode_put,
1451 },
1452 { } /* end */
1453};
1454
2cf9f0fc
TD
1455static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1456 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1457 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1458 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1459 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1460 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1461 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1462 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1463 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1464 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1465 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1466 { } /* end */
1467};
1468
ccc656ce 1469static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1470 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1471 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1472 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1473 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1474 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1475 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1476 { } /* end */
1477};
1478
2134ea4f
TI
1479/*
1480 * virtual master controls
1481 */
1482
1483/*
1484 * slave controls for virtual master
1485 */
1486static const char *alc_slave_vols[] = {
1487 "Front Playback Volume",
1488 "Surround Playback Volume",
1489 "Center Playback Volume",
1490 "LFE Playback Volume",
1491 "Side Playback Volume",
1492 "Headphone Playback Volume",
1493 "Speaker Playback Volume",
1494 "Mono Playback Volume",
2134ea4f
TI
1495 "Line-Out Playback Volume",
1496 NULL,
1497};
1498
1499static const char *alc_slave_sws[] = {
1500 "Front Playback Switch",
1501 "Surround Playback Switch",
1502 "Center Playback Switch",
1503 "LFE Playback Switch",
1504 "Side Playback Switch",
1505 "Headphone Playback Switch",
1506 "Speaker Playback Switch",
1507 "Mono Playback Switch",
edb54a55 1508 "IEC958 Playback Switch",
2134ea4f
TI
1509 NULL,
1510};
1511
1da177e4 1512/*
e9edcee0 1513 * build control elements
1da177e4
LT
1514 */
1515static int alc_build_controls(struct hda_codec *codec)
1516{
1517 struct alc_spec *spec = codec->spec;
1518 int err;
1519 int i;
1520
1521 for (i = 0; i < spec->num_mixers; i++) {
1522 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1523 if (err < 0)
1524 return err;
1525 }
1526
1527 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1528 err = snd_hda_create_spdif_out_ctls(codec,
1529 spec->multiout.dig_out_nid);
1da177e4
LT
1530 if (err < 0)
1531 return err;
9a08160b
TI
1532 err = snd_hda_create_spdif_share_sw(codec,
1533 &spec->multiout);
1534 if (err < 0)
1535 return err;
1536 spec->multiout.share_spdif = 1;
1da177e4
LT
1537 }
1538 if (spec->dig_in_nid) {
1539 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1540 if (err < 0)
1541 return err;
1542 }
2134ea4f
TI
1543
1544 /* if we have no master control, let's create it */
1545 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 1546 unsigned int vmaster_tlv[4];
2134ea4f 1547 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 1548 HDA_OUTPUT, vmaster_tlv);
2134ea4f 1549 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 1550 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
1551 if (err < 0)
1552 return err;
1553 }
1554 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1555 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1556 NULL, alc_slave_sws);
1557 if (err < 0)
1558 return err;
1559 }
1560
1da177e4
LT
1561 return 0;
1562}
1563
e9edcee0 1564
1da177e4
LT
1565/*
1566 * initialize the codec volumes, etc
1567 */
1568
e9edcee0
TI
1569/*
1570 * generic initialization of ADC, input mixers and output mixers
1571 */
1572static struct hda_verb alc880_volume_init_verbs[] = {
1573 /*
1574 * Unmute ADC0-2 and set the default input to mic-in
1575 */
71fe7b82 1576 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1578 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1580 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1582
e9edcee0
TI
1583 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1584 * mixer widget
9c7f852e
TI
1585 * Note: PASD motherboards uses the Line In 2 as the input for front
1586 * panel mic (mic 2)
1da177e4 1587 */
e9edcee0 1588 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1590 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1591 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1592 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1593 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1594 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1595 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1596
e9edcee0
TI
1597 /*
1598 * Set up output mixers (0x0c - 0x0f)
1da177e4 1599 */
e9edcee0
TI
1600 /* set vol=0 to output mixers */
1601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1602 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1605 /* set up input amps for analog loopback */
1606 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1612 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1613 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1614 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1615
1616 { }
1617};
1618
e9edcee0
TI
1619/*
1620 * 3-stack pin configuration:
1621 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1622 */
1623static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1624 /*
1625 * preset connection lists of input pins
1626 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1627 */
1628 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1629 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1630 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1631
1632 /*
1633 * Set pin mode and muting
1634 */
1635 /* set front pin widgets 0x14 for output */
05acb863 1636 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1637 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1638 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1639 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1641 /* Mic2 (as headphone out) for HP output */
1642 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1644 /* Line In pin widget for input */
05acb863 1645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1647 /* Line2 (as front mic) pin widget for input and vref at 80% */
1648 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1649 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1650 /* CD pin widget for input */
05acb863 1651 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1652
e9edcee0
TI
1653 { }
1654};
1da177e4 1655
e9edcee0
TI
1656/*
1657 * 5-stack pin configuration:
1658 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1659 * line-in/side = 0x1a, f-mic = 0x1b
1660 */
1661static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1662 /*
1663 * preset connection lists of input pins
1664 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1665 */
e9edcee0
TI
1666 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1667 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1668
e9edcee0
TI
1669 /*
1670 * Set pin mode and muting
1da177e4 1671 */
e9edcee0
TI
1672 /* set pin widgets 0x14-0x17 for output */
1673 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1675 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1676 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1677 /* unmute pins for output (no gain on this amp) */
1678 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1682
1683 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1684 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1685 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1686 /* Mic2 (as headphone out) for HP output */
1687 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1688 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689 /* Line In pin widget for input */
1690 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1692 /* Line2 (as front mic) pin widget for input and vref at 80% */
1693 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1694 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1695 /* CD pin widget for input */
1696 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1697
1698 { }
1699};
1700
e9edcee0
TI
1701/*
1702 * W810 pin configuration:
1703 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1704 */
1705static struct hda_verb alc880_pin_w810_init_verbs[] = {
1706 /* hphone/speaker input selector: front DAC */
1707 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1708
05acb863 1709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1713 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1714 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1715
e9edcee0 1716 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1717 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1718
1da177e4
LT
1719 { }
1720};
1721
e9edcee0
TI
1722/*
1723 * Z71V pin configuration:
1724 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1725 */
1726static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1727 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1729 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1731
16ded525 1732 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1733 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1736
1737 { }
1738};
1739
e9edcee0
TI
1740/*
1741 * 6-stack pin configuration:
9c7f852e
TI
1742 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1743 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1744 */
1745static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1746 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1747
16ded525 1748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1752 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1754 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1756
16ded525 1757 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1759 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1760 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1761 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1763 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1764 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1766
e9edcee0
TI
1767 { }
1768};
1769
ccc656ce
KY
1770/*
1771 * Uniwill pin configuration:
1772 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1773 * line = 0x1a
1774 */
1775static struct hda_verb alc880_uniwill_init_verbs[] = {
1776 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1777
1778 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1781 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1782 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1783 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1784 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1789 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1792
1793 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1794 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1795 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1796 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1797 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1799 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1800 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1801 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1802
1803 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1804 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1805
1806 { }
1807};
1808
1809/*
1810* Uniwill P53
1811* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1812 */
1813static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1814 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1815
1816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1817 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1819 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1820 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1821 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1824 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1825 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1826 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1827 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1828
1829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1835
1836 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1837 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1838
1839 { }
1840};
1841
2cf9f0fc
TD
1842static struct hda_verb alc880_beep_init_verbs[] = {
1843 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1844 { }
1845};
1846
ccc656ce 1847/* toggle speaker-output according to the hp-jack state */
458a4fab 1848static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1849{
1850 unsigned int present;
f12ab1e0 1851 unsigned char bits;
ccc656ce
KY
1852
1853 present = snd_hda_codec_read(codec, 0x14, 0,
1854 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1855 bits = present ? HDA_AMP_MUTE : 0;
1856 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1857 HDA_AMP_MUTE, bits);
1858 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1859 HDA_AMP_MUTE, bits);
458a4fab
TI
1860}
1861
1862/* auto-toggle front mic */
1863static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1864{
1865 unsigned int present;
1866 unsigned char bits;
ccc656ce
KY
1867
1868 present = snd_hda_codec_read(codec, 0x18, 0,
1869 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1870 bits = present ? HDA_AMP_MUTE : 0;
1871 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1872}
1873
1874static void alc880_uniwill_automute(struct hda_codec *codec)
1875{
1876 alc880_uniwill_hp_automute(codec);
1877 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1878}
1879
1880static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1881 unsigned int res)
1882{
1883 /* Looks like the unsol event is incompatible with the standard
1884 * definition. 4bit tag is placed at 28 bit!
1885 */
458a4fab
TI
1886 switch (res >> 28) {
1887 case ALC880_HP_EVENT:
1888 alc880_uniwill_hp_automute(codec);
1889 break;
1890 case ALC880_MIC_EVENT:
1891 alc880_uniwill_mic_automute(codec);
1892 break;
1893 }
ccc656ce
KY
1894}
1895
1896static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1897{
1898 unsigned int present;
f12ab1e0 1899 unsigned char bits;
ccc656ce
KY
1900
1901 present = snd_hda_codec_read(codec, 0x14, 0,
1902 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a 1903 bits = present ? HDA_AMP_MUTE : 0;
64654c2f 1904 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1905}
1906
1907static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1908{
1909 unsigned int present;
1910
1911 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1912 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1913 present &= HDA_AMP_VOLMASK;
1914 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1915 HDA_AMP_VOLMASK, present);
1916 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1917 HDA_AMP_VOLMASK, present);
ccc656ce 1918}
47fd830a 1919
ccc656ce
KY
1920static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1921 unsigned int res)
1922{
1923 /* Looks like the unsol event is incompatible with the standard
1924 * definition. 4bit tag is placed at 28 bit!
1925 */
1926 if ((res >> 28) == ALC880_HP_EVENT)
1927 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1928 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1929 alc880_uniwill_p53_dcvol_automute(codec);
1930}
1931
e9edcee0
TI
1932/*
1933 * F1734 pin configuration:
1934 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1935 */
1936static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 1937 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
1938 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1939 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1940 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1941 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1942
e9edcee0 1943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1944 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1945 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1946 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1947
e9edcee0
TI
1948 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1949 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 1950 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 1951 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1952 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1953 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1955 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1956 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 1957
937b4160
TI
1958 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1959 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1960
dfc0ff62
TI
1961 { }
1962};
1963
e9edcee0
TI
1964/*
1965 * ASUS pin configuration:
1966 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1967 */
1968static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1969 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1970 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1971 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1972 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1973
1974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1978 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1980 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1981 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1982
1983 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1985 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1986 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1987 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1988 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1989 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1990 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1991 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1992
e9edcee0
TI
1993 { }
1994};
16ded525 1995
e9edcee0 1996/* Enable GPIO mask and set output */
bc9f98a9
KY
1997#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1998#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1999
2000/* Clevo m520g init */
2001static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2002 /* headphone output */
2003 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2004 /* line-out */
2005 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2006 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007 /* Line-in */
2008 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2009 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2010 /* CD */
2011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2012 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2013 /* Mic1 (rear panel) */
2014 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2015 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2016 /* Mic2 (front panel) */
2017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2019 /* headphone */
2020 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2021 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022 /* change to EAPD mode */
2023 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2024 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2025
2026 { }
16ded525
TI
2027};
2028
df694daa 2029static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2030 /* change to EAPD mode */
2031 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2032 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2033
df694daa
KY
2034 /* Headphone output */
2035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2036 /* Front output*/
2037 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2038 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2039
2040 /* Line In pin widget for input */
2041 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2042 /* CD pin widget for input */
2043 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2044 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2045 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2046
2047 /* change to EAPD mode */
2048 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2049 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2050
2051 { }
2052};
16ded525 2053
e9edcee0 2054/*
ae6b813a
TI
2055 * LG m1 express dual
2056 *
2057 * Pin assignment:
2058 * Rear Line-In/Out (blue): 0x14
2059 * Build-in Mic-In: 0x15
2060 * Speaker-out: 0x17
2061 * HP-Out (green): 0x1b
2062 * Mic-In/Out (red): 0x19
2063 * SPDIF-Out: 0x1e
2064 */
2065
2066/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2067static hda_nid_t alc880_lg_dac_nids[3] = {
2068 0x05, 0x02, 0x03
2069};
2070
2071/* seems analog CD is not working */
2072static struct hda_input_mux alc880_lg_capture_source = {
2073 .num_items = 3,
2074 .items = {
2075 { "Mic", 0x1 },
2076 { "Line", 0x5 },
2077 { "Internal Mic", 0x6 },
2078 },
2079};
2080
2081/* 2,4,6 channel modes */
2082static struct hda_verb alc880_lg_ch2_init[] = {
2083 /* set line-in and mic-in to input */
2084 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2085 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2086 { }
2087};
2088
2089static struct hda_verb alc880_lg_ch4_init[] = {
2090 /* set line-in to out and mic-in to input */
2091 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2092 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2093 { }
2094};
2095
2096static struct hda_verb alc880_lg_ch6_init[] = {
2097 /* set line-in and mic-in to output */
2098 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2099 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2100 { }
2101};
2102
2103static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2104 { 2, alc880_lg_ch2_init },
2105 { 4, alc880_lg_ch4_init },
2106 { 6, alc880_lg_ch6_init },
2107};
2108
2109static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2111 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2112 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2113 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2114 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2115 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2116 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2117 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2118 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2119 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2120 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2121 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2122 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2123 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2124 {
2125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2126 .name = "Channel Mode",
2127 .info = alc_ch_mode_info,
2128 .get = alc_ch_mode_get,
2129 .put = alc_ch_mode_put,
2130 },
2131 { } /* end */
2132};
2133
2134static struct hda_verb alc880_lg_init_verbs[] = {
2135 /* set capture source to mic-in */
2136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2137 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2138 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2139 /* mute all amp mixer inputs */
2140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2141 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2142 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2143 /* line-in to input */
2144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2145 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2146 /* built-in mic */
2147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2149 /* speaker-out */
2150 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2151 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2152 /* mic-in to input */
2153 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2154 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2155 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 /* HP-out */
2157 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160 /* jack sense */
2161 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2162 { }
2163};
2164
2165/* toggle speaker-output according to the hp-jack state */
2166static void alc880_lg_automute(struct hda_codec *codec)
2167{
2168 unsigned int present;
f12ab1e0 2169 unsigned char bits;
ae6b813a
TI
2170
2171 present = snd_hda_codec_read(codec, 0x1b, 0,
2172 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2173 bits = present ? HDA_AMP_MUTE : 0;
2174 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2175 HDA_AMP_MUTE, bits);
ae6b813a
TI
2176}
2177
2178static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2179{
2180 /* Looks like the unsol event is incompatible with the standard
2181 * definition. 4bit tag is placed at 28 bit!
2182 */
2183 if ((res >> 28) == 0x01)
2184 alc880_lg_automute(codec);
2185}
2186
d681518a
TI
2187/*
2188 * LG LW20
2189 *
2190 * Pin assignment:
2191 * Speaker-out: 0x14
2192 * Mic-In: 0x18
e4f41da9
CM
2193 * Built-in Mic-In: 0x19
2194 * Line-In: 0x1b
2195 * HP-Out: 0x1a
d681518a
TI
2196 * SPDIF-Out: 0x1e
2197 */
2198
d681518a 2199static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2200 .num_items = 3,
d681518a
TI
2201 .items = {
2202 { "Mic", 0x0 },
2203 { "Internal Mic", 0x1 },
e4f41da9 2204 { "Line In", 0x2 },
d681518a
TI
2205 },
2206};
2207
0a8c5da3
CM
2208#define alc880_lg_lw_modes alc880_threestack_modes
2209
d681518a 2210static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2211 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2212 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2214 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2215 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2216 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2217 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2218 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2219 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2220 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2221 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2223 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2224 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2225 {
2226 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2227 .name = "Channel Mode",
2228 .info = alc_ch_mode_info,
2229 .get = alc_ch_mode_get,
2230 .put = alc_ch_mode_put,
2231 },
d681518a
TI
2232 { } /* end */
2233};
2234
2235static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2236 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2237 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2238 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2239
d681518a
TI
2240 /* set capture source to mic-in */
2241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2245 /* speaker-out */
2246 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2247 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2248 /* HP-out */
d681518a
TI
2249 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2250 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2251 /* mic-in to input */
2252 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2253 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254 /* built-in mic */
2255 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2256 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2257 /* jack sense */
2258 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2259 { }
2260};
2261
2262/* toggle speaker-output according to the hp-jack state */
2263static void alc880_lg_lw_automute(struct hda_codec *codec)
2264{
2265 unsigned int present;
f12ab1e0 2266 unsigned char bits;
d681518a
TI
2267
2268 present = snd_hda_codec_read(codec, 0x1b, 0,
2269 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2270 bits = present ? HDA_AMP_MUTE : 0;
2271 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2272 HDA_AMP_MUTE, bits);
d681518a
TI
2273}
2274
2275static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2276{
2277 /* Looks like the unsol event is incompatible with the standard
2278 * definition. 4bit tag is placed at 28 bit!
2279 */
2280 if ((res >> 28) == 0x01)
2281 alc880_lg_lw_automute(codec);
2282}
2283
df99cd33
TI
2284static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2285 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2286 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2289 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2290 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2291 { } /* end */
2292};
2293
2294static struct hda_input_mux alc880_medion_rim_capture_source = {
2295 .num_items = 2,
2296 .items = {
2297 { "Mic", 0x0 },
2298 { "Internal Mic", 0x1 },
2299 },
2300};
2301
2302static struct hda_verb alc880_medion_rim_init_verbs[] = {
2303 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2304
2305 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2306 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2307
2308 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2309 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2310 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2311 /* Mic2 (as headphone out) for HP output */
2312 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2313 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2314 /* Internal Speaker */
2315 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2316 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2317
2318 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2319 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2320
2321 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2322 { }
2323};
2324
2325/* toggle speaker-output according to the hp-jack state */
2326static void alc880_medion_rim_automute(struct hda_codec *codec)
2327{
2328 unsigned int present;
2329 unsigned char bits;
2330
2331 present = snd_hda_codec_read(codec, 0x14, 0,
2332 AC_VERB_GET_PIN_SENSE, 0)
2333 & AC_PINSENSE_PRESENCE;
2334 bits = present ? HDA_AMP_MUTE : 0;
2335 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2336 HDA_AMP_MUTE, bits);
2337 if (present)
2338 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2339 else
2340 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2341}
2342
2343static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2344 unsigned int res)
2345{
2346 /* Looks like the unsol event is incompatible with the standard
2347 * definition. 4bit tag is placed at 28 bit!
2348 */
2349 if ((res >> 28) == ALC880_HP_EVENT)
2350 alc880_medion_rim_automute(codec);
2351}
2352
cb53c626
TI
2353#ifdef CONFIG_SND_HDA_POWER_SAVE
2354static struct hda_amp_list alc880_loopbacks[] = {
2355 { 0x0b, HDA_INPUT, 0 },
2356 { 0x0b, HDA_INPUT, 1 },
2357 { 0x0b, HDA_INPUT, 2 },
2358 { 0x0b, HDA_INPUT, 3 },
2359 { 0x0b, HDA_INPUT, 4 },
2360 { } /* end */
2361};
2362
2363static struct hda_amp_list alc880_lg_loopbacks[] = {
2364 { 0x0b, HDA_INPUT, 1 },
2365 { 0x0b, HDA_INPUT, 6 },
2366 { 0x0b, HDA_INPUT, 7 },
2367 { } /* end */
2368};
2369#endif
2370
ae6b813a
TI
2371/*
2372 * Common callbacks
e9edcee0
TI
2373 */
2374
1da177e4
LT
2375static int alc_init(struct hda_codec *codec)
2376{
2377 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2378 unsigned int i;
2379
2380 for (i = 0; i < spec->num_init_verbs; i++)
2381 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2382
2383 if (spec->init_hook)
2384 spec->init_hook(codec);
2385
1da177e4
LT
2386 return 0;
2387}
2388
ae6b813a
TI
2389static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2390{
2391 struct alc_spec *spec = codec->spec;
2392
2393 if (spec->unsol_event)
2394 spec->unsol_event(codec, res);
2395}
2396
cb53c626
TI
2397#ifdef CONFIG_SND_HDA_POWER_SAVE
2398static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2399{
2400 struct alc_spec *spec = codec->spec;
2401 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2402}
2403#endif
2404
1da177e4
LT
2405/*
2406 * Analog playback callbacks
2407 */
2408static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2409 struct hda_codec *codec,
c8b6bf9b 2410 struct snd_pcm_substream *substream)
1da177e4
LT
2411{
2412 struct alc_spec *spec = codec->spec;
9a08160b
TI
2413 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2414 hinfo);
1da177e4
LT
2415}
2416
2417static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2418 struct hda_codec *codec,
2419 unsigned int stream_tag,
2420 unsigned int format,
c8b6bf9b 2421 struct snd_pcm_substream *substream)
1da177e4
LT
2422{
2423 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2424 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2425 stream_tag, format, substream);
1da177e4
LT
2426}
2427
2428static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2429 struct hda_codec *codec,
c8b6bf9b 2430 struct snd_pcm_substream *substream)
1da177e4
LT
2431{
2432 struct alc_spec *spec = codec->spec;
2433 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2434}
2435
2436/*
2437 * Digital out
2438 */
2439static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2440 struct hda_codec *codec,
c8b6bf9b 2441 struct snd_pcm_substream *substream)
1da177e4
LT
2442{
2443 struct alc_spec *spec = codec->spec;
2444 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2445}
2446
6b97eb45
TI
2447static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2448 struct hda_codec *codec,
2449 unsigned int stream_tag,
2450 unsigned int format,
2451 struct snd_pcm_substream *substream)
2452{
2453 struct alc_spec *spec = codec->spec;
2454 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2455 stream_tag, format, substream);
2456}
2457
1da177e4
LT
2458static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2459 struct hda_codec *codec,
c8b6bf9b 2460 struct snd_pcm_substream *substream)
1da177e4
LT
2461{
2462 struct alc_spec *spec = codec->spec;
2463 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2464}
2465
2466/*
2467 * Analog capture
2468 */
6330079f 2469static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2470 struct hda_codec *codec,
2471 unsigned int stream_tag,
2472 unsigned int format,
c8b6bf9b 2473 struct snd_pcm_substream *substream)
1da177e4
LT
2474{
2475 struct alc_spec *spec = codec->spec;
2476
6330079f 2477 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2478 stream_tag, 0, format);
2479 return 0;
2480}
2481
6330079f 2482static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2483 struct hda_codec *codec,
c8b6bf9b 2484 struct snd_pcm_substream *substream)
1da177e4
LT
2485{
2486 struct alc_spec *spec = codec->spec;
2487
888afa15
TI
2488 snd_hda_codec_cleanup_stream(codec,
2489 spec->adc_nids[substream->number + 1]);
1da177e4
LT
2490 return 0;
2491}
2492
2493
2494/*
2495 */
2496static struct hda_pcm_stream alc880_pcm_analog_playback = {
2497 .substreams = 1,
2498 .channels_min = 2,
2499 .channels_max = 8,
e9edcee0 2500 /* NID is set in alc_build_pcms */
1da177e4
LT
2501 .ops = {
2502 .open = alc880_playback_pcm_open,
2503 .prepare = alc880_playback_pcm_prepare,
2504 .cleanup = alc880_playback_pcm_cleanup
2505 },
2506};
2507
2508static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2509 .substreams = 1,
2510 .channels_min = 2,
2511 .channels_max = 2,
2512 /* NID is set in alc_build_pcms */
2513};
2514
2515static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2516 .substreams = 1,
2517 .channels_min = 2,
2518 .channels_max = 2,
2519 /* NID is set in alc_build_pcms */
2520};
2521
2522static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2523 .substreams = 2, /* can be overridden */
1da177e4
LT
2524 .channels_min = 2,
2525 .channels_max = 2,
e9edcee0 2526 /* NID is set in alc_build_pcms */
1da177e4 2527 .ops = {
6330079f
TI
2528 .prepare = alc880_alt_capture_pcm_prepare,
2529 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2530 },
2531};
2532
2533static struct hda_pcm_stream alc880_pcm_digital_playback = {
2534 .substreams = 1,
2535 .channels_min = 2,
2536 .channels_max = 2,
2537 /* NID is set in alc_build_pcms */
2538 .ops = {
2539 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2540 .close = alc880_dig_playback_pcm_close,
2541 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2542 },
2543};
2544
2545static struct hda_pcm_stream alc880_pcm_digital_capture = {
2546 .substreams = 1,
2547 .channels_min = 2,
2548 .channels_max = 2,
2549 /* NID is set in alc_build_pcms */
2550};
2551
4c5186ed 2552/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2553static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2554 .substreams = 0,
2555 .channels_min = 0,
2556 .channels_max = 0,
2557};
2558
1da177e4
LT
2559static int alc_build_pcms(struct hda_codec *codec)
2560{
2561 struct alc_spec *spec = codec->spec;
2562 struct hda_pcm *info = spec->pcm_rec;
2563 int i;
2564
2565 codec->num_pcms = 1;
2566 codec->pcm_info = info;
2567
2568 info->name = spec->stream_name_analog;
4a471b7d
TI
2569 if (spec->stream_analog_playback) {
2570 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2571 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2572 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2573 }
2574 if (spec->stream_analog_capture) {
2575 snd_assert(spec->adc_nids, return -EINVAL);
2576 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2577 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2578 }
2579
2580 if (spec->channel_mode) {
2581 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2582 for (i = 0; i < spec->num_channel_mode; i++) {
2583 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2584 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2585 }
1da177e4
LT
2586 }
2587 }
2588
e08a007d 2589 /* SPDIF for stream index #1 */
1da177e4 2590 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2591 codec->num_pcms = 2;
c06134d7 2592 info = spec->pcm_rec + 1;
1da177e4 2593 info->name = spec->stream_name_digital;
7ba72ba1 2594 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2595 if (spec->multiout.dig_out_nid &&
2596 spec->stream_digital_playback) {
1da177e4
LT
2597 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2598 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2599 }
4a471b7d
TI
2600 if (spec->dig_in_nid &&
2601 spec->stream_digital_capture) {
1da177e4
LT
2602 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2603 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2604 }
2605 }
2606
e08a007d
TI
2607 /* If the use of more than one ADC is requested for the current
2608 * model, configure a second analog capture-only PCM.
2609 */
2610 /* Additional Analaog capture for index #2 */
6330079f
TI
2611 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2612 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2613 codec->num_pcms = 3;
c06134d7 2614 info = spec->pcm_rec + 2;
e08a007d 2615 info->name = spec->stream_name_analog;
6330079f
TI
2616 if (spec->alt_dac_nid) {
2617 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2618 *spec->stream_analog_alt_playback;
2619 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2620 spec->alt_dac_nid;
2621 } else {
2622 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2623 alc_pcm_null_stream;
2624 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2625 }
2626 if (spec->num_adc_nids > 1) {
2627 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2628 *spec->stream_analog_alt_capture;
2629 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2630 spec->adc_nids[1];
2631 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2632 spec->num_adc_nids - 1;
2633 } else {
2634 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2635 alc_pcm_null_stream;
2636 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2637 }
2638 }
2639
1da177e4
LT
2640 return 0;
2641}
2642
2643static void alc_free(struct hda_codec *codec)
2644{
e9edcee0
TI
2645 struct alc_spec *spec = codec->spec;
2646 unsigned int i;
2647
f12ab1e0 2648 if (!spec)
e9edcee0
TI
2649 return;
2650
2651 if (spec->kctl_alloc) {
2652 for (i = 0; i < spec->num_kctl_used; i++)
2653 kfree(spec->kctl_alloc[i].name);
2654 kfree(spec->kctl_alloc);
2655 }
2656 kfree(spec);
7943a8ab 2657 codec->spec = NULL; /* to be sure */
1da177e4
LT
2658}
2659
2660/*
2661 */
2662static struct hda_codec_ops alc_patch_ops = {
2663 .build_controls = alc_build_controls,
2664 .build_pcms = alc_build_pcms,
2665 .init = alc_init,
2666 .free = alc_free,
ae6b813a 2667 .unsol_event = alc_unsol_event,
cb53c626
TI
2668#ifdef CONFIG_SND_HDA_POWER_SAVE
2669 .check_power_status = alc_check_power_status,
2670#endif
1da177e4
LT
2671};
2672
2fa522be
TI
2673
2674/*
2675 * Test configuration for debugging
2676 *
2677 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2678 * enum controls.
2679 */
2680#ifdef CONFIG_SND_DEBUG
2681static hda_nid_t alc880_test_dac_nids[4] = {
2682 0x02, 0x03, 0x04, 0x05
2683};
2684
2685static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2686 .num_items = 7,
2fa522be
TI
2687 .items = {
2688 { "In-1", 0x0 },
2689 { "In-2", 0x1 },
2690 { "In-3", 0x2 },
2691 { "In-4", 0x3 },
2692 { "CD", 0x4 },
ae6b813a
TI
2693 { "Front", 0x5 },
2694 { "Surround", 0x6 },
2fa522be
TI
2695 },
2696};
2697
d2a6d7dc 2698static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2699 { 2, NULL },
fd2c326d 2700 { 4, NULL },
2fa522be 2701 { 6, NULL },
fd2c326d 2702 { 8, NULL },
2fa522be
TI
2703};
2704
9c7f852e
TI
2705static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2706 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2707{
2708 static char *texts[] = {
2709 "N/A", "Line Out", "HP Out",
2710 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2711 };
2712 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2713 uinfo->count = 1;
2714 uinfo->value.enumerated.items = 8;
2715 if (uinfo->value.enumerated.item >= 8)
2716 uinfo->value.enumerated.item = 7;
2717 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2718 return 0;
2719}
2720
9c7f852e
TI
2721static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2722 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2723{
2724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2725 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2726 unsigned int pin_ctl, item = 0;
2727
2728 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2729 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2730 if (pin_ctl & AC_PINCTL_OUT_EN) {
2731 if (pin_ctl & AC_PINCTL_HP_EN)
2732 item = 2;
2733 else
2734 item = 1;
2735 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2736 switch (pin_ctl & AC_PINCTL_VREFEN) {
2737 case AC_PINCTL_VREF_HIZ: item = 3; break;
2738 case AC_PINCTL_VREF_50: item = 4; break;
2739 case AC_PINCTL_VREF_GRD: item = 5; break;
2740 case AC_PINCTL_VREF_80: item = 6; break;
2741 case AC_PINCTL_VREF_100: item = 7; break;
2742 }
2743 }
2744 ucontrol->value.enumerated.item[0] = item;
2745 return 0;
2746}
2747
9c7f852e
TI
2748static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2749 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2750{
2751 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2752 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2753 static unsigned int ctls[] = {
2754 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2755 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2756 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2757 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2758 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2759 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2760 };
2761 unsigned int old_ctl, new_ctl;
2762
2763 old_ctl = snd_hda_codec_read(codec, nid, 0,
2764 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2765 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2766 if (old_ctl != new_ctl) {
82beb8fd
TI
2767 int val;
2768 snd_hda_codec_write_cache(codec, nid, 0,
2769 AC_VERB_SET_PIN_WIDGET_CONTROL,
2770 new_ctl);
47fd830a
TI
2771 val = ucontrol->value.enumerated.item[0] >= 3 ?
2772 HDA_AMP_MUTE : 0;
2773 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2774 HDA_AMP_MUTE, val);
2fa522be
TI
2775 return 1;
2776 }
2777 return 0;
2778}
2779
9c7f852e
TI
2780static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2781 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2782{
2783 static char *texts[] = {
2784 "Front", "Surround", "CLFE", "Side"
2785 };
2786 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2787 uinfo->count = 1;
2788 uinfo->value.enumerated.items = 4;
2789 if (uinfo->value.enumerated.item >= 4)
2790 uinfo->value.enumerated.item = 3;
2791 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2792 return 0;
2793}
2794
9c7f852e
TI
2795static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2796 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2797{
2798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2799 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2800 unsigned int sel;
2801
2802 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2803 ucontrol->value.enumerated.item[0] = sel & 3;
2804 return 0;
2805}
2806
9c7f852e
TI
2807static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2808 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2809{
2810 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2811 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2812 unsigned int sel;
2813
2814 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2815 if (ucontrol->value.enumerated.item[0] != sel) {
2816 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2817 snd_hda_codec_write_cache(codec, nid, 0,
2818 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2819 return 1;
2820 }
2821 return 0;
2822}
2823
2824#define PIN_CTL_TEST(xname,nid) { \
2825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2826 .name = xname, \
2827 .info = alc_test_pin_ctl_info, \
2828 .get = alc_test_pin_ctl_get, \
2829 .put = alc_test_pin_ctl_put, \
2830 .private_value = nid \
2831 }
2832
2833#define PIN_SRC_TEST(xname,nid) { \
2834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2835 .name = xname, \
2836 .info = alc_test_pin_src_info, \
2837 .get = alc_test_pin_src_get, \
2838 .put = alc_test_pin_src_put, \
2839 .private_value = nid \
2840 }
2841
c8b6bf9b 2842static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2843 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2844 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2845 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2846 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2847 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2848 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2849 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2850 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2851 PIN_CTL_TEST("Front Pin Mode", 0x14),
2852 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2853 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2854 PIN_CTL_TEST("Side Pin Mode", 0x17),
2855 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2856 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2857 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2858 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2859 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2860 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2861 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2862 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2863 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2864 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2865 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2866 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2867 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2868 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2869 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2870 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2871 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2872 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2873 {
2874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2875 .name = "Channel Mode",
df694daa
KY
2876 .info = alc_ch_mode_info,
2877 .get = alc_ch_mode_get,
2878 .put = alc_ch_mode_put,
2fa522be
TI
2879 },
2880 { } /* end */
2881};
2882
2883static struct hda_verb alc880_test_init_verbs[] = {
2884 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2889 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2891 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2892 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2893 /* Vol output for 0x0c-0x0f */
05acb863
TI
2894 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2897 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2898 /* Set output pins 0x14-0x17 */
05acb863
TI
2899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2900 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2901 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2902 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2903 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2904 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2905 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2906 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2907 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2908 /* Set input pins 0x18-0x1c */
16ded525
TI
2909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2910 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2912 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2913 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2914 /* Mute input pins 0x18-0x1b */
05acb863
TI
2915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2916 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2917 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2918 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2919 /* ADC set up */
05acb863 2920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2921 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2922 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2923 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2924 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2925 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2926 /* Analog input/passthru */
2927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2932 { }
2933};
2934#endif
2935
1da177e4
LT
2936/*
2937 */
2938
f5fcc13c
TI
2939static const char *alc880_models[ALC880_MODEL_LAST] = {
2940 [ALC880_3ST] = "3stack",
2941 [ALC880_TCL_S700] = "tcl",
2942 [ALC880_3ST_DIG] = "3stack-digout",
2943 [ALC880_CLEVO] = "clevo",
2944 [ALC880_5ST] = "5stack",
2945 [ALC880_5ST_DIG] = "5stack-digout",
2946 [ALC880_W810] = "w810",
2947 [ALC880_Z71V] = "z71v",
2948 [ALC880_6ST] = "6stack",
2949 [ALC880_6ST_DIG] = "6stack-digout",
2950 [ALC880_ASUS] = "asus",
2951 [ALC880_ASUS_W1V] = "asus-w1v",
2952 [ALC880_ASUS_DIG] = "asus-dig",
2953 [ALC880_ASUS_DIG2] = "asus-dig2",
2954 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2955 [ALC880_UNIWILL_P53] = "uniwill-p53",
2956 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2957 [ALC880_F1734] = "F1734",
2958 [ALC880_LG] = "lg",
2959 [ALC880_LG_LW] = "lg-lw",
df99cd33 2960 [ALC880_MEDION_RIM] = "medion",
2fa522be 2961#ifdef CONFIG_SND_DEBUG
f5fcc13c 2962 [ALC880_TEST] = "test",
2fa522be 2963#endif
f5fcc13c
TI
2964 [ALC880_AUTO] = "auto",
2965};
2966
2967static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2968 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2969 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2970 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2971 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2972 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2973 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2974 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2975 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2976 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2977 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2978 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2979 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2980 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2981 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2982 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2983 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2984 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2985 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2986 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2987 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2988 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 2989 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
2990 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2991 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2992 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2993 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2994 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2995 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2996 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2997 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2998 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2999 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3000 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3001 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3002 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3003 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3004 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3005 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3006 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3007 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3008 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3009 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3010 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3011 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3012 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3013 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3014 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3015 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 3016 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3017 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3018 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3019 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3020 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3021 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3022 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3023 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3024 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3025 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3026 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3027 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3028 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3029 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3030 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3031 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3032 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3033 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3034 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3035 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3036 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3037 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3038 {}
3039};
3040
16ded525 3041/*
df694daa 3042 * ALC880 codec presets
16ded525 3043 */
16ded525
TI
3044static struct alc_config_preset alc880_presets[] = {
3045 [ALC880_3ST] = {
e9edcee0 3046 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3047 .init_verbs = { alc880_volume_init_verbs,
3048 alc880_pin_3stack_init_verbs },
16ded525 3049 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3050 .dac_nids = alc880_dac_nids,
16ded525
TI
3051 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3052 .channel_mode = alc880_threestack_modes,
4e195a7b 3053 .need_dac_fix = 1,
16ded525
TI
3054 .input_mux = &alc880_capture_source,
3055 },
3056 [ALC880_3ST_DIG] = {
e9edcee0 3057 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3058 .init_verbs = { alc880_volume_init_verbs,
3059 alc880_pin_3stack_init_verbs },
16ded525 3060 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3061 .dac_nids = alc880_dac_nids,
3062 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3063 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3064 .channel_mode = alc880_threestack_modes,
4e195a7b 3065 .need_dac_fix = 1,
16ded525
TI
3066 .input_mux = &alc880_capture_source,
3067 },
df694daa
KY
3068 [ALC880_TCL_S700] = {
3069 .mixers = { alc880_tcl_s700_mixer },
3070 .init_verbs = { alc880_volume_init_verbs,
3071 alc880_pin_tcl_S700_init_verbs,
3072 alc880_gpio2_init_verbs },
3073 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3074 .dac_nids = alc880_dac_nids,
3075 .hp_nid = 0x03,
3076 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3077 .channel_mode = alc880_2_jack_modes,
3078 .input_mux = &alc880_capture_source,
3079 },
16ded525 3080 [ALC880_5ST] = {
f12ab1e0
TI
3081 .mixers = { alc880_three_stack_mixer,
3082 alc880_five_stack_mixer},
3083 .init_verbs = { alc880_volume_init_verbs,
3084 alc880_pin_5stack_init_verbs },
16ded525
TI
3085 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3086 .dac_nids = alc880_dac_nids,
16ded525
TI
3087 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3088 .channel_mode = alc880_fivestack_modes,
3089 .input_mux = &alc880_capture_source,
3090 },
3091 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3092 .mixers = { alc880_three_stack_mixer,
3093 alc880_five_stack_mixer },
3094 .init_verbs = { alc880_volume_init_verbs,
3095 alc880_pin_5stack_init_verbs },
16ded525
TI
3096 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3097 .dac_nids = alc880_dac_nids,
3098 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3099 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3100 .channel_mode = alc880_fivestack_modes,
3101 .input_mux = &alc880_capture_source,
3102 },
b6482d48
TI
3103 [ALC880_6ST] = {
3104 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3105 .init_verbs = { alc880_volume_init_verbs,
3106 alc880_pin_6stack_init_verbs },
b6482d48
TI
3107 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3108 .dac_nids = alc880_6st_dac_nids,
3109 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3110 .channel_mode = alc880_sixstack_modes,
3111 .input_mux = &alc880_6stack_capture_source,
3112 },
16ded525 3113 [ALC880_6ST_DIG] = {
e9edcee0 3114 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3115 .init_verbs = { alc880_volume_init_verbs,
3116 alc880_pin_6stack_init_verbs },
16ded525
TI
3117 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3118 .dac_nids = alc880_6st_dac_nids,
3119 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3120 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3121 .channel_mode = alc880_sixstack_modes,
3122 .input_mux = &alc880_6stack_capture_source,
3123 },
3124 [ALC880_W810] = {
e9edcee0 3125 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3126 .init_verbs = { alc880_volume_init_verbs,
3127 alc880_pin_w810_init_verbs,
b0af0de5 3128 alc880_gpio2_init_verbs },
16ded525
TI
3129 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3130 .dac_nids = alc880_w810_dac_nids,
3131 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3132 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3133 .channel_mode = alc880_w810_modes,
3134 .input_mux = &alc880_capture_source,
3135 },
3136 [ALC880_Z71V] = {
e9edcee0 3137 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3138 .init_verbs = { alc880_volume_init_verbs,
3139 alc880_pin_z71v_init_verbs },
16ded525
TI
3140 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3141 .dac_nids = alc880_z71v_dac_nids,
3142 .dig_out_nid = ALC880_DIGOUT_NID,
3143 .hp_nid = 0x03,
e9edcee0
TI
3144 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3145 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3146 .input_mux = &alc880_capture_source,
3147 },
3148 [ALC880_F1734] = {
e9edcee0 3149 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3150 .init_verbs = { alc880_volume_init_verbs,
3151 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3152 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3153 .dac_nids = alc880_f1734_dac_nids,
3154 .hp_nid = 0x02,
3155 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3156 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3157 .input_mux = &alc880_f1734_capture_source,
3158 .unsol_event = alc880_uniwill_p53_unsol_event,
3159 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3160 },
3161 [ALC880_ASUS] = {
e9edcee0 3162 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3163 .init_verbs = { alc880_volume_init_verbs,
3164 alc880_pin_asus_init_verbs,
e9edcee0
TI
3165 alc880_gpio1_init_verbs },
3166 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3167 .dac_nids = alc880_asus_dac_nids,
3168 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3169 .channel_mode = alc880_asus_modes,
4e195a7b 3170 .need_dac_fix = 1,
16ded525
TI
3171 .input_mux = &alc880_capture_source,
3172 },
3173 [ALC880_ASUS_DIG] = {
e9edcee0 3174 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3175 .init_verbs = { alc880_volume_init_verbs,
3176 alc880_pin_asus_init_verbs,
e9edcee0
TI
3177 alc880_gpio1_init_verbs },
3178 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3179 .dac_nids = alc880_asus_dac_nids,
16ded525 3180 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3181 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3182 .channel_mode = alc880_asus_modes,
4e195a7b 3183 .need_dac_fix = 1,
16ded525
TI
3184 .input_mux = &alc880_capture_source,
3185 },
df694daa
KY
3186 [ALC880_ASUS_DIG2] = {
3187 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3188 .init_verbs = { alc880_volume_init_verbs,
3189 alc880_pin_asus_init_verbs,
df694daa
KY
3190 alc880_gpio2_init_verbs }, /* use GPIO2 */
3191 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3192 .dac_nids = alc880_asus_dac_nids,
3193 .dig_out_nid = ALC880_DIGOUT_NID,
3194 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3195 .channel_mode = alc880_asus_modes,
4e195a7b 3196 .need_dac_fix = 1,
df694daa
KY
3197 .input_mux = &alc880_capture_source,
3198 },
16ded525 3199 [ALC880_ASUS_W1V] = {
e9edcee0 3200 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3201 .init_verbs = { alc880_volume_init_verbs,
3202 alc880_pin_asus_init_verbs,
e9edcee0
TI
3203 alc880_gpio1_init_verbs },
3204 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3205 .dac_nids = alc880_asus_dac_nids,
16ded525 3206 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3207 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3208 .channel_mode = alc880_asus_modes,
4e195a7b 3209 .need_dac_fix = 1,
16ded525
TI
3210 .input_mux = &alc880_capture_source,
3211 },
3212 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3213 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3214 .init_verbs = { alc880_volume_init_verbs,
3215 alc880_pin_asus_init_verbs },
e9edcee0
TI
3216 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3217 .dac_nids = alc880_asus_dac_nids,
16ded525 3218 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3219 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3220 .channel_mode = alc880_asus_modes,
4e195a7b 3221 .need_dac_fix = 1,
16ded525
TI
3222 .input_mux = &alc880_capture_source,
3223 },
ccc656ce
KY
3224 [ALC880_UNIWILL] = {
3225 .mixers = { alc880_uniwill_mixer },
3226 .init_verbs = { alc880_volume_init_verbs,
3227 alc880_uniwill_init_verbs },
3228 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3229 .dac_nids = alc880_asus_dac_nids,
3230 .dig_out_nid = ALC880_DIGOUT_NID,
3231 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3232 .channel_mode = alc880_threestack_modes,
3233 .need_dac_fix = 1,
3234 .input_mux = &alc880_capture_source,
3235 .unsol_event = alc880_uniwill_unsol_event,
3236 .init_hook = alc880_uniwill_automute,
3237 },
3238 [ALC880_UNIWILL_P53] = {
3239 .mixers = { alc880_uniwill_p53_mixer },
3240 .init_verbs = { alc880_volume_init_verbs,
3241 alc880_uniwill_p53_init_verbs },
3242 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3243 .dac_nids = alc880_asus_dac_nids,
3244 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3245 .channel_mode = alc880_threestack_modes,
3246 .input_mux = &alc880_capture_source,
3247 .unsol_event = alc880_uniwill_p53_unsol_event,
3248 .init_hook = alc880_uniwill_p53_hp_automute,
3249 },
3250 [ALC880_FUJITSU] = {
f12ab1e0 3251 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3252 alc880_pcbeep_mixer, },
3253 .init_verbs = { alc880_volume_init_verbs,
3254 alc880_uniwill_p53_init_verbs,
3255 alc880_beep_init_verbs },
3256 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3257 .dac_nids = alc880_dac_nids,
d53d7d9e 3258 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3259 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3260 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3261 .input_mux = &alc880_capture_source,
3262 .unsol_event = alc880_uniwill_p53_unsol_event,
3263 .init_hook = alc880_uniwill_p53_hp_automute,
3264 },
df694daa
KY
3265 [ALC880_CLEVO] = {
3266 .mixers = { alc880_three_stack_mixer },
3267 .init_verbs = { alc880_volume_init_verbs,
3268 alc880_pin_clevo_init_verbs },
3269 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3270 .dac_nids = alc880_dac_nids,
3271 .hp_nid = 0x03,
3272 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3273 .channel_mode = alc880_threestack_modes,
4e195a7b 3274 .need_dac_fix = 1,
df694daa
KY
3275 .input_mux = &alc880_capture_source,
3276 },
ae6b813a
TI
3277 [ALC880_LG] = {
3278 .mixers = { alc880_lg_mixer },
3279 .init_verbs = { alc880_volume_init_verbs,
3280 alc880_lg_init_verbs },
3281 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3282 .dac_nids = alc880_lg_dac_nids,
3283 .dig_out_nid = ALC880_DIGOUT_NID,
3284 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3285 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3286 .need_dac_fix = 1,
ae6b813a
TI
3287 .input_mux = &alc880_lg_capture_source,
3288 .unsol_event = alc880_lg_unsol_event,
3289 .init_hook = alc880_lg_automute,
cb53c626
TI
3290#ifdef CONFIG_SND_HDA_POWER_SAVE
3291 .loopbacks = alc880_lg_loopbacks,
3292#endif
ae6b813a 3293 },
d681518a
TI
3294 [ALC880_LG_LW] = {
3295 .mixers = { alc880_lg_lw_mixer },
3296 .init_verbs = { alc880_volume_init_verbs,
3297 alc880_lg_lw_init_verbs },
0a8c5da3 3298 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3299 .dac_nids = alc880_dac_nids,
3300 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3301 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3302 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3303 .input_mux = &alc880_lg_lw_capture_source,
3304 .unsol_event = alc880_lg_lw_unsol_event,
3305 .init_hook = alc880_lg_lw_automute,
3306 },
df99cd33
TI
3307 [ALC880_MEDION_RIM] = {
3308 .mixers = { alc880_medion_rim_mixer },
3309 .init_verbs = { alc880_volume_init_verbs,
3310 alc880_medion_rim_init_verbs,
3311 alc_gpio2_init_verbs },
3312 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3313 .dac_nids = alc880_dac_nids,
3314 .dig_out_nid = ALC880_DIGOUT_NID,
3315 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3316 .channel_mode = alc880_2_jack_modes,
3317 .input_mux = &alc880_medion_rim_capture_source,
3318 .unsol_event = alc880_medion_rim_unsol_event,
3319 .init_hook = alc880_medion_rim_automute,
3320 },
16ded525
TI
3321#ifdef CONFIG_SND_DEBUG
3322 [ALC880_TEST] = {
e9edcee0
TI
3323 .mixers = { alc880_test_mixer },
3324 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3325 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3326 .dac_nids = alc880_test_dac_nids,
3327 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3328 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3329 .channel_mode = alc880_test_modes,
3330 .input_mux = &alc880_test_capture_source,
3331 },
3332#endif
3333};
3334
e9edcee0
TI
3335/*
3336 * Automatic parse of I/O pins from the BIOS configuration
3337 */
3338
3339#define NUM_CONTROL_ALLOC 32
3340#define NUM_VERB_ALLOC 32
3341
3342enum {
3343 ALC_CTL_WIDGET_VOL,
3344 ALC_CTL_WIDGET_MUTE,
3345 ALC_CTL_BIND_MUTE,
3346};
c8b6bf9b 3347static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3348 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3349 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3350 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3351};
3352
3353/* add dynamic controls */
f12ab1e0
TI
3354static int add_control(struct alc_spec *spec, int type, const char *name,
3355 unsigned long val)
e9edcee0 3356{
c8b6bf9b 3357 struct snd_kcontrol_new *knew;
e9edcee0
TI
3358
3359 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3360 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3361
f12ab1e0
TI
3362 /* array + terminator */
3363 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3364 if (!knew)
e9edcee0
TI
3365 return -ENOMEM;
3366 if (spec->kctl_alloc) {
f12ab1e0
TI
3367 memcpy(knew, spec->kctl_alloc,
3368 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3369 kfree(spec->kctl_alloc);
3370 }
3371 spec->kctl_alloc = knew;
3372 spec->num_kctl_alloc = num;
3373 }
3374
3375 knew = &spec->kctl_alloc[spec->num_kctl_used];
3376 *knew = alc880_control_templates[type];
543537bd 3377 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3378 if (!knew->name)
e9edcee0
TI
3379 return -ENOMEM;
3380 knew->private_value = val;
3381 spec->num_kctl_used++;
3382 return 0;
3383}
3384
3385#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3386#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3387#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3388#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3389#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3390#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3391#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3392#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3393#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3394#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3395#define ALC880_PIN_CD_NID 0x1c
3396
3397/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3398static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3399 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3400{
3401 hda_nid_t nid;
3402 int assigned[4];
3403 int i, j;
3404
3405 memset(assigned, 0, sizeof(assigned));
b0af0de5 3406 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3407
3408 /* check the pins hardwired to audio widget */
3409 for (i = 0; i < cfg->line_outs; i++) {
3410 nid = cfg->line_out_pins[i];
3411 if (alc880_is_fixed_pin(nid)) {
3412 int idx = alc880_fixed_pin_idx(nid);
5014f193 3413 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3414 assigned[idx] = 1;
3415 }
3416 }
3417 /* left pins can be connect to any audio widget */
3418 for (i = 0; i < cfg->line_outs; i++) {
3419 nid = cfg->line_out_pins[i];
3420 if (alc880_is_fixed_pin(nid))
3421 continue;
3422 /* search for an empty channel */
3423 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3424 if (!assigned[j]) {
3425 spec->multiout.dac_nids[i] =
3426 alc880_idx_to_dac(j);
e9edcee0
TI
3427 assigned[j] = 1;
3428 break;
3429 }
3430 }
3431 }
3432 spec->multiout.num_dacs = cfg->line_outs;
3433 return 0;
3434}
3435
3436/* add playback controls from the parsed DAC table */
df694daa
KY
3437static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3438 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3439{
3440 char name[32];
f12ab1e0
TI
3441 static const char *chname[4] = {
3442 "Front", "Surround", NULL /*CLFE*/, "Side"
3443 };
e9edcee0
TI
3444 hda_nid_t nid;
3445 int i, err;
3446
3447 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3448 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3449 continue;
3450 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3451 if (i == 2) {
3452 /* Center/LFE */
f12ab1e0
TI
3453 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3454 "Center Playback Volume",
3455 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3456 HDA_OUTPUT));
3457 if (err < 0)
e9edcee0 3458 return err;
f12ab1e0
TI
3459 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3460 "LFE Playback Volume",
3461 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3462 HDA_OUTPUT));
3463 if (err < 0)
e9edcee0 3464 return err;
f12ab1e0
TI
3465 err = add_control(spec, ALC_CTL_BIND_MUTE,
3466 "Center Playback Switch",
3467 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3468 HDA_INPUT));
3469 if (err < 0)
e9edcee0 3470 return err;
f12ab1e0
TI
3471 err = add_control(spec, ALC_CTL_BIND_MUTE,
3472 "LFE Playback Switch",
3473 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3474 HDA_INPUT));
3475 if (err < 0)
e9edcee0
TI
3476 return err;
3477 } else {
3478 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3479 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3480 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3481 HDA_OUTPUT));
3482 if (err < 0)
e9edcee0
TI
3483 return err;
3484 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3485 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3486 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3487 HDA_INPUT));
3488 if (err < 0)
e9edcee0
TI
3489 return err;
3490 }
3491 }
e9edcee0
TI
3492 return 0;
3493}
3494
8d88bc3d
TI
3495/* add playback controls for speaker and HP outputs */
3496static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3497 const char *pfx)
e9edcee0
TI
3498{
3499 hda_nid_t nid;
3500 int err;
8d88bc3d 3501 char name[32];
e9edcee0 3502
f12ab1e0 3503 if (!pin)
e9edcee0
TI
3504 return 0;
3505
3506 if (alc880_is_fixed_pin(pin)) {
3507 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3508 /* specify the DAC as the extra output */
f12ab1e0 3509 if (!spec->multiout.hp_nid)
e9edcee0 3510 spec->multiout.hp_nid = nid;
82bc955f
TI
3511 else
3512 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3513 /* control HP volume/switch on the output mixer amp */
3514 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3515 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3516 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3517 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3518 if (err < 0)
e9edcee0 3519 return err;
8d88bc3d 3520 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3521 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3522 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3523 if (err < 0)
e9edcee0
TI
3524 return err;
3525 } else if (alc880_is_multi_pin(pin)) {
3526 /* set manual connection */
e9edcee0 3527 /* we have only a switch on HP-out PIN */
8d88bc3d 3528 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3529 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3530 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3531 if (err < 0)
e9edcee0
TI
3532 return err;
3533 }
3534 return 0;
3535}
3536
3537/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3538static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3539 const char *ctlname,
df694daa 3540 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3541{
3542 char name[32];
df694daa 3543 int err;
e9edcee0
TI
3544
3545 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3546 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3547 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3548 if (err < 0)
e9edcee0
TI
3549 return err;
3550 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3551 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3552 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3553 if (err < 0)
e9edcee0
TI
3554 return err;
3555 return 0;
3556}
3557
3558/* create playback/capture controls for input pins */
df694daa
KY
3559static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3560 const struct auto_pin_cfg *cfg)
e9edcee0 3561{
e9edcee0 3562 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3563 int i, err, idx;
e9edcee0
TI
3564
3565 for (i = 0; i < AUTO_PIN_LAST; i++) {
3566 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3567 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3568 err = new_analog_input(spec, cfg->input_pins[i],
3569 auto_pin_cfg_labels[i],
df694daa 3570 idx, 0x0b);
e9edcee0
TI
3571 if (err < 0)
3572 return err;
f12ab1e0
TI
3573 imux->items[imux->num_items].label =
3574 auto_pin_cfg_labels[i];
3575 imux->items[imux->num_items].index =
3576 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3577 imux->num_items++;
3578 }
3579 }
3580 return 0;
3581}
3582
f6c7e546
TI
3583static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3584 unsigned int pin_type)
3585{
3586 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3587 pin_type);
3588 /* unmute pin */
d260cdf6
TI
3589 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3590 AMP_OUT_UNMUTE);
f6c7e546
TI
3591}
3592
df694daa
KY
3593static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3594 hda_nid_t nid, int pin_type,
e9edcee0
TI
3595 int dac_idx)
3596{
f6c7e546 3597 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3598 /* need the manual connection? */
3599 if (alc880_is_multi_pin(nid)) {
3600 struct alc_spec *spec = codec->spec;
3601 int idx = alc880_multi_pin_idx(nid);
3602 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3603 AC_VERB_SET_CONNECT_SEL,
3604 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3605 }
3606}
3607
baba8ee9
TI
3608static int get_pin_type(int line_out_type)
3609{
3610 if (line_out_type == AUTO_PIN_HP_OUT)
3611 return PIN_HP;
3612 else
3613 return PIN_OUT;
3614}
3615
e9edcee0
TI
3616static void alc880_auto_init_multi_out(struct hda_codec *codec)
3617{
3618 struct alc_spec *spec = codec->spec;
3619 int i;
bc9f98a9
KY
3620
3621 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3622 for (i = 0; i < spec->autocfg.line_outs; i++) {
3623 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3624 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3625 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3626 }
3627}
3628
8d88bc3d 3629static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3630{
3631 struct alc_spec *spec = codec->spec;
3632 hda_nid_t pin;
3633
82bc955f 3634 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3635 if (pin) /* connect to front */
3636 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3637 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3638 if (pin) /* connect to front */
3639 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3640}
3641
3642static void alc880_auto_init_analog_input(struct hda_codec *codec)
3643{
3644 struct alc_spec *spec = codec->spec;
3645 int i;
3646
3647 for (i = 0; i < AUTO_PIN_LAST; i++) {
3648 hda_nid_t nid = spec->autocfg.input_pins[i];
3649 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3650 snd_hda_codec_write(codec, nid, 0,
3651 AC_VERB_SET_PIN_WIDGET_CONTROL,
3652 i <= AUTO_PIN_FRONT_MIC ?
3653 PIN_VREF80 : PIN_IN);
e9edcee0 3654 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3655 snd_hda_codec_write(codec, nid, 0,
3656 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3657 AMP_OUT_MUTE);
3658 }
3659 }
3660}
3661
3662/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3663/* return 1 if successful, 0 if the proper config is not found,
3664 * or a negative error code
3665 */
e9edcee0
TI
3666static int alc880_parse_auto_config(struct hda_codec *codec)
3667{
3668 struct alc_spec *spec = codec->spec;
3669 int err;
df694daa 3670 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3671
f12ab1e0
TI
3672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3673 alc880_ignore);
3674 if (err < 0)
e9edcee0 3675 return err;
f12ab1e0 3676 if (!spec->autocfg.line_outs)
e9edcee0 3677 return 0; /* can't find valid BIOS pin config */
df694daa 3678
f12ab1e0
TI
3679 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3680 if (err < 0)
3681 return err;
3682 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3683 if (err < 0)
3684 return err;
3685 err = alc880_auto_create_extra_out(spec,
3686 spec->autocfg.speaker_pins[0],
3687 "Speaker");
3688 if (err < 0)
3689 return err;
3690 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3691 "Headphone");
3692 if (err < 0)
3693 return err;
3694 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3695 if (err < 0)
e9edcee0
TI
3696 return err;
3697
3698 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3699
3700 if (spec->autocfg.dig_out_pin)
3701 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3702 if (spec->autocfg.dig_in_pin)
3703 spec->dig_in_nid = ALC880_DIGIN_NID;
3704
3705 if (spec->kctl_alloc)
3706 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3707
3708 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3709
a1e8d2da 3710 spec->num_mux_defs = 1;
e9edcee0
TI
3711 spec->input_mux = &spec->private_imux;
3712
3713 return 1;
3714}
3715
ae6b813a
TI
3716/* additional initialization for auto-configuration model */
3717static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3718{
f6c7e546 3719 struct alc_spec *spec = codec->spec;
e9edcee0 3720 alc880_auto_init_multi_out(codec);
8d88bc3d 3721 alc880_auto_init_extra_out(codec);
e9edcee0 3722 alc880_auto_init_analog_input(codec);
f6c7e546
TI
3723 if (spec->unsol_event)
3724 alc_sku_automute(codec);
e9edcee0
TI
3725}
3726
3727/*
3728 * OK, here we have finally the patch for ALC880
3729 */
3730
1da177e4
LT
3731static int patch_alc880(struct hda_codec *codec)
3732{
3733 struct alc_spec *spec;
3734 int board_config;
df694daa 3735 int err;
1da177e4 3736
e560d8d8 3737 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3738 if (spec == NULL)
3739 return -ENOMEM;
3740
3741 codec->spec = spec;
3742
f5fcc13c
TI
3743 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3744 alc880_models,
3745 alc880_cfg_tbl);
3746 if (board_config < 0) {
9c7f852e
TI
3747 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3748 "trying auto-probe from BIOS...\n");
e9edcee0 3749 board_config = ALC880_AUTO;
1da177e4 3750 }
1da177e4 3751
e9edcee0
TI
3752 if (board_config == ALC880_AUTO) {
3753 /* automatic parse from the BIOS config */
3754 err = alc880_parse_auto_config(codec);
3755 if (err < 0) {
3756 alc_free(codec);
3757 return err;
f12ab1e0 3758 } else if (!err) {
9c7f852e
TI
3759 printk(KERN_INFO
3760 "hda_codec: Cannot set up configuration "
3761 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3762 board_config = ALC880_3ST;
3763 }
1da177e4
LT
3764 }
3765
df694daa
KY
3766 if (board_config != ALC880_AUTO)
3767 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3768
3769 spec->stream_name_analog = "ALC880 Analog";
3770 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3771 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3772 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3773
3774 spec->stream_name_digital = "ALC880 Digital";
3775 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3776 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3777
f12ab1e0 3778 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3779 /* check whether NID 0x07 is valid */
54d17403 3780 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3781 /* get type */
3782 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3783 if (wcap != AC_WID_AUD_IN) {
3784 spec->adc_nids = alc880_adc_nids_alt;
3785 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3786 spec->mixers[spec->num_mixers] =
3787 alc880_capture_alt_mixer;
e9edcee0
TI
3788 spec->num_mixers++;
3789 } else {
3790 spec->adc_nids = alc880_adc_nids;
3791 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3792 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3793 spec->num_mixers++;
3794 }
3795 }
1da177e4 3796
2134ea4f
TI
3797 spec->vmaster_nid = 0x0c;
3798
1da177e4 3799 codec->patch_ops = alc_patch_ops;
e9edcee0 3800 if (board_config == ALC880_AUTO)
ae6b813a 3801 spec->init_hook = alc880_auto_init;
cb53c626
TI
3802#ifdef CONFIG_SND_HDA_POWER_SAVE
3803 if (!spec->loopback.amplist)
3804 spec->loopback.amplist = alc880_loopbacks;
3805#endif
1da177e4
LT
3806
3807 return 0;
3808}
3809
e9edcee0 3810
1da177e4
LT
3811/*
3812 * ALC260 support
3813 */
3814
e9edcee0
TI
3815static hda_nid_t alc260_dac_nids[1] = {
3816 /* front */
3817 0x02,
3818};
3819
3820static hda_nid_t alc260_adc_nids[1] = {
3821 /* ADC0 */
3822 0x04,
3823};
3824
df694daa 3825static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3826 /* ADC1 */
3827 0x05,
3828};
3829
df694daa
KY
3830static hda_nid_t alc260_hp_adc_nids[2] = {
3831 /* ADC1, 0 */
3832 0x05, 0x04
3833};
3834
d57fdac0
JW
3835/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3836 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3837 */
3838static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3839 /* ADC0, ADC1 */
3840 0x04, 0x05
3841};
3842
e9edcee0
TI
3843#define ALC260_DIGOUT_NID 0x03
3844#define ALC260_DIGIN_NID 0x06
3845
3846static struct hda_input_mux alc260_capture_source = {
3847 .num_items = 4,
3848 .items = {
3849 { "Mic", 0x0 },
3850 { "Front Mic", 0x1 },
3851 { "Line", 0x2 },
3852 { "CD", 0x4 },
3853 },
3854};
3855
17e7aec6 3856/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3857 * headphone jack and the internal CD lines since these are the only pins at
3858 * which audio can appear. For flexibility, also allow the option of
3859 * recording the mixer output on the second ADC (ADC0 doesn't have a
3860 * connection to the mixer output).
a9430dd8 3861 */
a1e8d2da
JW
3862static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3863 {
3864 .num_items = 3,
3865 .items = {
3866 { "Mic/Line", 0x0 },
3867 { "CD", 0x4 },
3868 { "Headphone", 0x2 },
3869 },
a9430dd8 3870 },
a1e8d2da
JW
3871 {
3872 .num_items = 4,
3873 .items = {
3874 { "Mic/Line", 0x0 },
3875 { "CD", 0x4 },
3876 { "Headphone", 0x2 },
3877 { "Mixer", 0x5 },
3878 },
3879 },
3880
a9430dd8
JW
3881};
3882
a1e8d2da
JW
3883/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3884 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3885 */
a1e8d2da
JW
3886static struct hda_input_mux alc260_acer_capture_sources[2] = {
3887 {
3888 .num_items = 4,
3889 .items = {
3890 { "Mic", 0x0 },
3891 { "Line", 0x2 },
3892 { "CD", 0x4 },
3893 { "Headphone", 0x5 },
3894 },
3895 },
3896 {
3897 .num_items = 5,
3898 .items = {
3899 { "Mic", 0x0 },
3900 { "Line", 0x2 },
3901 { "CD", 0x4 },
3902 { "Headphone", 0x6 },
3903 { "Mixer", 0x5 },
3904 },
0bfc90e9
JW
3905 },
3906};
1da177e4
LT
3907/*
3908 * This is just place-holder, so there's something for alc_build_pcms to look
3909 * at when it calculates the maximum number of channels. ALC260 has no mixer
3910 * element which allows changing the channel mode, so the verb list is
3911 * never used.
3912 */
d2a6d7dc 3913static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3914 { 2, NULL },
3915};
3916
df694daa
KY
3917
3918/* Mixer combinations
3919 *
3920 * basic: base_output + input + pc_beep + capture
3921 * HP: base_output + input + capture_alt
3922 * HP_3013: hp_3013 + input + capture
3923 * fujitsu: fujitsu + capture
0bfc90e9 3924 * acer: acer + capture
df694daa
KY
3925 */
3926
3927static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3928 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3929 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3930 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3931 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3932 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3933 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3934 { } /* end */
f12ab1e0 3935};
1da177e4 3936
df694daa 3937static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
3938 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3939 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3940 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3941 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3942 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3943 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3944 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3945 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3946 { } /* end */
3947};
3948
3949static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3950 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3951 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3952 { } /* end */
3953};
3954
bec15c3a
TI
3955/* update HP, line and mono out pins according to the master switch */
3956static void alc260_hp_master_update(struct hda_codec *codec,
3957 hda_nid_t hp, hda_nid_t line,
3958 hda_nid_t mono)
3959{
3960 struct alc_spec *spec = codec->spec;
3961 unsigned int val = spec->master_sw ? PIN_HP : 0;
3962 /* change HP and line-out pins */
3963 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3964 val);
3965 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3966 val);
3967 /* mono (speaker) depending on the HP jack sense */
3968 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3969 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3970 val);
3971}
3972
3973static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3974 struct snd_ctl_elem_value *ucontrol)
3975{
3976 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3977 struct alc_spec *spec = codec->spec;
3978 *ucontrol->value.integer.value = spec->master_sw;
3979 return 0;
3980}
3981
3982static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3983 struct snd_ctl_elem_value *ucontrol)
3984{
3985 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3986 struct alc_spec *spec = codec->spec;
3987 int val = !!*ucontrol->value.integer.value;
3988 hda_nid_t hp, line, mono;
3989
3990 if (val == spec->master_sw)
3991 return 0;
3992 spec->master_sw = val;
3993 hp = (kcontrol->private_value >> 16) & 0xff;
3994 line = (kcontrol->private_value >> 8) & 0xff;
3995 mono = kcontrol->private_value & 0xff;
3996 alc260_hp_master_update(codec, hp, line, mono);
3997 return 1;
3998}
3999
4000static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4001 {
4002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4003 .name = "Master Playback Switch",
4004 .info = snd_ctl_boolean_mono_info,
4005 .get = alc260_hp_master_sw_get,
4006 .put = alc260_hp_master_sw_put,
4007 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4008 },
4009 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4010 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4011 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4012 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4013 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4014 HDA_OUTPUT),
4015 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4016 { } /* end */
4017};
4018
4019static struct hda_verb alc260_hp_unsol_verbs[] = {
4020 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4021 {},
4022};
4023
4024static void alc260_hp_automute(struct hda_codec *codec)
4025{
4026 struct alc_spec *spec = codec->spec;
4027 unsigned int present;
4028
4029 present = snd_hda_codec_read(codec, 0x10, 0,
4030 AC_VERB_GET_PIN_SENSE, 0);
4031 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4032 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4033}
4034
4035static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4036{
4037 if ((res >> 26) == ALC880_HP_EVENT)
4038 alc260_hp_automute(codec);
4039}
4040
df694daa 4041static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4042 {
4043 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4044 .name = "Master Playback Switch",
4045 .info = snd_ctl_boolean_mono_info,
4046 .get = alc260_hp_master_sw_get,
4047 .put = alc260_hp_master_sw_put,
4048 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4049 },
df694daa
KY
4050 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4051 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4052 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4053 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4056 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4057 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4058 { } /* end */
4059};
4060
bec15c3a
TI
4061static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4062 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4063 {},
4064};
4065
4066static void alc260_hp_3013_automute(struct hda_codec *codec)
4067{
4068 struct alc_spec *spec = codec->spec;
4069 unsigned int present;
4070
4071 present = snd_hda_codec_read(codec, 0x15, 0,
4072 AC_VERB_GET_PIN_SENSE, 0);
4073 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4074 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4075}
4076
4077static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4078 unsigned int res)
4079{
4080 if ((res >> 26) == ALC880_HP_EVENT)
4081 alc260_hp_3013_automute(codec);
4082}
4083
a1e8d2da
JW
4084/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4085 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4086 */
c8b6bf9b 4087static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4088 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4089 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4090 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4091 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4092 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4093 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4094 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4095 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
4096 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4097 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4098 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4099 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4100 { } /* end */
4101};
4102
a1e8d2da
JW
4103/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4104 * versions of the ALC260 don't act on requests to enable mic bias from NID
4105 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4106 * datasheet doesn't mention this restriction. At this stage it's not clear
4107 * whether this behaviour is intentional or is a hardware bug in chip
4108 * revisions available in early 2006. Therefore for now allow the
4109 * "Headphone Jack Mode" control to span all choices, but if it turns out
4110 * that the lack of mic bias for this NID is intentional we could change the
4111 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4112 *
4113 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4114 * don't appear to make the mic bias available from the "line" jack, even
4115 * though the NID used for this jack (0x14) can supply it. The theory is
4116 * that perhaps Acer have included blocking capacitors between the ALC260
4117 * and the output jack. If this turns out to be the case for all such
4118 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4119 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4120 *
4121 * The C20x Tablet series have a mono internal speaker which is controlled
4122 * via the chip's Mono sum widget and pin complex, so include the necessary
4123 * controls for such models. On models without a "mono speaker" the control
4124 * won't do anything.
a1e8d2da 4125 */
0bfc90e9
JW
4126static struct snd_kcontrol_new alc260_acer_mixer[] = {
4127 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4128 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4129 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4130 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4131 HDA_OUTPUT),
31bffaa9 4132 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4133 HDA_INPUT),
0bfc90e9
JW
4134 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4135 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4137 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4138 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4139 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4140 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4141 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4142 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4143 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4144 { } /* end */
4145};
4146
bc9f98a9
KY
4147/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4148 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4149 */
4150static struct snd_kcontrol_new alc260_will_mixer[] = {
4151 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4152 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4154 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4155 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4156 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4157 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4158 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4159 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4160 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4161 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4162 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4163 { } /* end */
4164};
4165
4166/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4167 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4168 */
4169static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4170 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4171 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4173 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4174 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4175 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4176 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4177 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4178 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4179 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4180 { } /* end */
4181};
4182
df694daa
KY
4183/* capture mixer elements */
4184static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4185 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4186 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4187 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4188 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4189 {
4190 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4191 /* The multiple "Capture Source" controls confuse alsamixer
4192 * So call somewhat different..
df694daa
KY
4193 */
4194 /* .name = "Capture Source", */
4195 .name = "Input Source",
4196 .count = 2,
4197 .info = alc_mux_enum_info,
4198 .get = alc_mux_enum_get,
4199 .put = alc_mux_enum_put,
4200 },
4201 { } /* end */
4202};
4203
4204static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4205 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4206 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4207 {
4208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4209 /* The multiple "Capture Source" controls confuse alsamixer
4210 * So call somewhat different..
df694daa
KY
4211 */
4212 /* .name = "Capture Source", */
4213 .name = "Input Source",
4214 .count = 1,
a9430dd8
JW
4215 .info = alc_mux_enum_info,
4216 .get = alc_mux_enum_get,
4217 .put = alc_mux_enum_put,
4218 },
4219 { } /* end */
4220};
4221
df694daa
KY
4222/*
4223 * initialization verbs
4224 */
1da177e4
LT
4225static struct hda_verb alc260_init_verbs[] = {
4226 /* Line In pin widget for input */
05acb863 4227 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4228 /* CD pin widget for input */
05acb863 4229 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4230 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4231 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4232 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4233 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4234 /* LINE-2 is used for line-out in rear */
05acb863 4235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4236 /* select line-out */
fd56f2db 4237 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4238 /* LINE-OUT pin */
05acb863 4239 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4240 /* enable HP */
05acb863 4241 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4242 /* enable Mono */
05acb863
TI
4243 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4244 /* mute capture amp left and right */
16ded525 4245 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4246 /* set connection select to line in (default select for this ADC) */
4247 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4248 /* mute capture amp left and right */
4249 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4250 /* set connection select to line in (default select for this ADC) */
4251 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4252 /* set vol=0 Line-Out mixer amp left and right */
4253 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4254 /* unmute pin widget amp left and right (no gain on this amp) */
4255 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4256 /* set vol=0 HP mixer amp left and right */
4257 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4258 /* unmute pin widget amp left and right (no gain on this amp) */
4259 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4260 /* set vol=0 Mono mixer amp left and right */
4261 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4262 /* unmute pin widget amp left and right (no gain on this amp) */
4263 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4264 /* unmute LINE-2 out pin */
4265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4266 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4267 * Line In 2 = 0x03
4268 */
cb53c626
TI
4269 /* mute analog inputs */
4270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4275 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4276 /* mute Front out path */
4277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4278 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4279 /* mute Headphone out path */
4280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4281 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4282 /* mute Mono out path */
4283 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4284 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4285 { }
4286};
4287
474167d6 4288#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4289static struct hda_verb alc260_hp_init_verbs[] = {
4290 /* Headphone and output */
4291 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4292 /* mono output */
4293 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4294 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4295 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4296 /* Mic2 (front panel) pin widget for input and vref at 80% */
4297 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4298 /* Line In pin widget for input */
4299 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4300 /* Line-2 pin widget for output */
4301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4302 /* CD pin widget for input */
4303 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4304 /* unmute amp left and right */
4305 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4306 /* set connection select to line in (default select for this ADC) */
4307 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4308 /* unmute Line-Out mixer amp left and right (volume = 0) */
4309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4310 /* mute pin widget amp left and right (no gain on this amp) */
4311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4312 /* unmute HP mixer amp left and right (volume = 0) */
4313 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4314 /* mute pin widget amp left and right (no gain on this amp) */
4315 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4316 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4317 * Line In 2 = 0x03
4318 */
cb53c626
TI
4319 /* mute analog inputs */
4320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4325 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4326 /* Unmute Front out path */
4327 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4328 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4329 /* Unmute Headphone out path */
4330 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4332 /* Unmute Mono out path */
4333 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4334 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4335 { }
4336};
474167d6 4337#endif
df694daa
KY
4338
4339static struct hda_verb alc260_hp_3013_init_verbs[] = {
4340 /* Line out and output */
4341 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4342 /* mono output */
4343 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4344 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4345 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4346 /* Mic2 (front panel) pin widget for input and vref at 80% */
4347 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4348 /* Line In pin widget for input */
4349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4350 /* Headphone pin widget for output */
4351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4352 /* CD pin widget for input */
4353 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4354 /* unmute amp left and right */
4355 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4356 /* set connection select to line in (default select for this ADC) */
4357 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4358 /* unmute Line-Out mixer amp left and right (volume = 0) */
4359 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4360 /* mute pin widget amp left and right (no gain on this amp) */
4361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4362 /* unmute HP mixer amp left and right (volume = 0) */
4363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4364 /* mute pin widget amp left and right (no gain on this amp) */
4365 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4366 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4367 * Line In 2 = 0x03
4368 */
cb53c626
TI
4369 /* mute analog inputs */
4370 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4371 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4373 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4374 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4375 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4376 /* Unmute Front out path */
4377 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4379 /* Unmute Headphone out path */
4380 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4382 /* Unmute Mono out path */
4383 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4384 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4385 { }
4386};
4387
a9430dd8 4388/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4389 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4390 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4391 */
4392static struct hda_verb alc260_fujitsu_init_verbs[] = {
4393 /* Disable all GPIOs */
4394 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4395 /* Internal speaker is connected to headphone pin */
4396 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4397 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4398 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4399 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4400 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4401 /* Ensure all other unused pins are disabled and muted. */
4402 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4403 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4404 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4405 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4406 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4407 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4408 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4409 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4410
4411 /* Disable digital (SPDIF) pins */
4412 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4413 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4414
f7ace40d
JW
4415 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4416 * when acting as an output.
4417 */
4418 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4419
f7ace40d 4420 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4422 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4423 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4425 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4426 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4427 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4428 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4429 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4430
f7ace40d
JW
4431 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4432 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4433 /* Unmute Line1 pin widget output buffer since it starts as an output.
4434 * If the pin mode is changed by the user the pin mode control will
4435 * take care of enabling the pin's input/output buffers as needed.
4436 * Therefore there's no need to enable the input buffer at this
4437 * stage.
cdcd9268 4438 */
f7ace40d 4439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4440 /* Unmute input buffer of pin widget used for Line-in (no equiv
4441 * mixer ctrl)
4442 */
f7ace40d
JW
4443 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4444
4445 /* Mute capture amp left and right */
4446 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4447 /* Set ADC connection select to match default mixer setting - line
4448 * in (on mic1 pin)
4449 */
4450 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4451
4452 /* Do the same for the second ADC: mute capture input amp and
4453 * set ADC connection to line in (on mic1 pin)
4454 */
4455 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4456 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4457
4458 /* Mute all inputs to mixer widget (even unconnected ones) */
4459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4460 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4461 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4462 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4463 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4464 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4467
4468 { }
a9430dd8
JW
4469};
4470
0bfc90e9
JW
4471/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4472 * similar laptops (adapted from Fujitsu init verbs).
4473 */
4474static struct hda_verb alc260_acer_init_verbs[] = {
4475 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4476 * the headphone jack. Turn this on and rely on the standard mute
4477 * methods whenever the user wants to turn these outputs off.
4478 */
4479 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4480 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4481 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4482 /* Internal speaker/Headphone jack is connected to Line-out pin */
4483 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4484 /* Internal microphone/Mic jack is connected to Mic1 pin */
4485 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4486 /* Line In jack is connected to Line1 pin */
4487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4488 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4489 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4490 /* Ensure all other unused pins are disabled and muted. */
4491 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4492 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4493 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4494 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4497 /* Disable digital (SPDIF) pins */
4498 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4499 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4500
4501 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4502 * bus when acting as outputs.
4503 */
4504 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4505 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4506
4507 /* Start with output sum widgets muted and their output gains at min */
4508 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4510 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4512 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4513 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4514 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4515 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4516 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4517
f12ab1e0
TI
4518 /* Unmute Line-out pin widget amp left and right
4519 * (no equiv mixer ctrl)
4520 */
0bfc90e9 4521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4522 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4523 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4524 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4525 * inputs. If the pin mode is changed by the user the pin mode control
4526 * will take care of enabling the pin's input/output buffers as needed.
4527 * Therefore there's no need to enable the input buffer at this
4528 * stage.
4529 */
4530 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4532
4533 /* Mute capture amp left and right */
4534 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4535 /* Set ADC connection select to match default mixer setting - mic
4536 * (on mic1 pin)
4537 */
4538 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4539
4540 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4541 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4542 */
4543 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4544 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4545
4546 /* Mute all inputs to mixer widget (even unconnected ones) */
4547 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4554 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4555
4556 { }
4557};
4558
bc9f98a9
KY
4559static struct hda_verb alc260_will_verbs[] = {
4560 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4561 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4562 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4563 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4564 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4565 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4566 {}
4567};
4568
4569static struct hda_verb alc260_replacer_672v_verbs[] = {
4570 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4571 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4572 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4573
4574 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4575 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4576 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4577
4578 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4579 {}
4580};
4581
4582/* toggle speaker-output according to the hp-jack state */
4583static void alc260_replacer_672v_automute(struct hda_codec *codec)
4584{
4585 unsigned int present;
4586
4587 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4588 present = snd_hda_codec_read(codec, 0x0f, 0,
4589 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4590 if (present) {
82beb8fd
TI
4591 snd_hda_codec_write_cache(codec, 0x01, 0,
4592 AC_VERB_SET_GPIO_DATA, 1);
4593 snd_hda_codec_write_cache(codec, 0x0f, 0,
4594 AC_VERB_SET_PIN_WIDGET_CONTROL,
4595 PIN_HP);
bc9f98a9 4596 } else {
82beb8fd
TI
4597 snd_hda_codec_write_cache(codec, 0x01, 0,
4598 AC_VERB_SET_GPIO_DATA, 0);
4599 snd_hda_codec_write_cache(codec, 0x0f, 0,
4600 AC_VERB_SET_PIN_WIDGET_CONTROL,
4601 PIN_OUT);
bc9f98a9
KY
4602 }
4603}
4604
4605static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4606 unsigned int res)
4607{
4608 if ((res >> 26) == ALC880_HP_EVENT)
4609 alc260_replacer_672v_automute(codec);
4610}
4611
7cf51e48
JW
4612/* Test configuration for debugging, modelled after the ALC880 test
4613 * configuration.
4614 */
4615#ifdef CONFIG_SND_DEBUG
4616static hda_nid_t alc260_test_dac_nids[1] = {
4617 0x02,
4618};
4619static hda_nid_t alc260_test_adc_nids[2] = {
4620 0x04, 0x05,
4621};
a1e8d2da
JW
4622/* For testing the ALC260, each input MUX needs its own definition since
4623 * the signal assignments are different. This assumes that the first ADC
4624 * is NID 0x04.
17e7aec6 4625 */
a1e8d2da
JW
4626static struct hda_input_mux alc260_test_capture_sources[2] = {
4627 {
4628 .num_items = 7,
4629 .items = {
4630 { "MIC1 pin", 0x0 },
4631 { "MIC2 pin", 0x1 },
4632 { "LINE1 pin", 0x2 },
4633 { "LINE2 pin", 0x3 },
4634 { "CD pin", 0x4 },
4635 { "LINE-OUT pin", 0x5 },
4636 { "HP-OUT pin", 0x6 },
4637 },
4638 },
4639 {
4640 .num_items = 8,
4641 .items = {
4642 { "MIC1 pin", 0x0 },
4643 { "MIC2 pin", 0x1 },
4644 { "LINE1 pin", 0x2 },
4645 { "LINE2 pin", 0x3 },
4646 { "CD pin", 0x4 },
4647 { "Mixer", 0x5 },
4648 { "LINE-OUT pin", 0x6 },
4649 { "HP-OUT pin", 0x7 },
4650 },
7cf51e48
JW
4651 },
4652};
4653static struct snd_kcontrol_new alc260_test_mixer[] = {
4654 /* Output driver widgets */
4655 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4656 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4657 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4658 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4659 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4660 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4661
a1e8d2da
JW
4662 /* Modes for retasking pin widgets
4663 * Note: the ALC260 doesn't seem to act on requests to enable mic
4664 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4665 * mention this restriction. At this stage it's not clear whether
4666 * this behaviour is intentional or is a hardware bug in chip
4667 * revisions available at least up until early 2006. Therefore for
4668 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4669 * choices, but if it turns out that the lack of mic bias for these
4670 * NIDs is intentional we could change their modes from
4671 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4672 */
7cf51e48
JW
4673 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4674 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4675 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4676 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4677 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4678 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4679
4680 /* Loopback mixer controls */
4681 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4682 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4683 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4684 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4685 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4686 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4687 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4688 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4689 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4690 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4691 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4692 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4693 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4694 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4695 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4696 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4697
4698 /* Controls for GPIO pins, assuming they are configured as outputs */
4699 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4700 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4701 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4702 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4703
92621f13
JW
4704 /* Switches to allow the digital IO pins to be enabled. The datasheet
4705 * is ambigious as to which NID is which; testing on laptops which
4706 * make this output available should provide clarification.
4707 */
4708 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4709 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4710
f8225f6d
JW
4711 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4712 * this output to turn on an external amplifier.
4713 */
4714 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4715 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4716
7cf51e48
JW
4717 { } /* end */
4718};
4719static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4720 /* Enable all GPIOs as outputs with an initial value of 0 */
4721 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4722 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4723 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4724
7cf51e48
JW
4725 /* Enable retasking pins as output, initially without power amp */
4726 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4727 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4730 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4731 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4732
92621f13
JW
4733 /* Disable digital (SPDIF) pins initially, but users can enable
4734 * them via a mixer switch. In the case of SPDIF-out, this initverb
4735 * payload also sets the generation to 0, output to be in "consumer"
4736 * PCM format, copyright asserted, no pre-emphasis and no validity
4737 * control.
4738 */
7cf51e48
JW
4739 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4740 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4741
f7ace40d 4742 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4743 * OUT1 sum bus when acting as an output.
4744 */
4745 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4746 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4747 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4748 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4749
4750 /* Start with output sum widgets muted and their output gains at min */
4751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4753 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4756 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4757 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4758 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4760
cdcd9268
JW
4761 /* Unmute retasking pin widget output buffers since the default
4762 * state appears to be output. As the pin mode is changed by the
4763 * user the pin mode control will take care of enabling the pin's
4764 * input/output buffers as needed.
4765 */
7cf51e48
JW
4766 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4767 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4770 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4771 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4772 /* Also unmute the mono-out pin widget */
4773 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4774
7cf51e48
JW
4775 /* Mute capture amp left and right */
4776 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4777 /* Set ADC connection select to match default mixer setting (mic1
4778 * pin)
7cf51e48
JW
4779 */
4780 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4781
4782 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4783 * set ADC connection to mic1 pin
7cf51e48
JW
4784 */
4785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4786 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4787
4788 /* Mute all inputs to mixer widget (even unconnected ones) */
4789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4794 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4795 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4796 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4797
4798 { }
4799};
4800#endif
4801
6330079f
TI
4802#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4803#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 4804
a3bcba38
TI
4805#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4806#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4807
df694daa
KY
4808/*
4809 * for BIOS auto-configuration
4810 */
16ded525 4811
df694daa
KY
4812static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4813 const char *pfx)
4814{
4815 hda_nid_t nid_vol;
4816 unsigned long vol_val, sw_val;
4817 char name[32];
4818 int err;
4819
4820 if (nid >= 0x0f && nid < 0x11) {
4821 nid_vol = nid - 0x7;
4822 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4823 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4824 } else if (nid == 0x11) {
4825 nid_vol = nid - 0x7;
4826 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4827 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4828 } else if (nid >= 0x12 && nid <= 0x15) {
4829 nid_vol = 0x08;
4830 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4831 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4832 } else
4833 return 0; /* N/A */
4834
4835 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4836 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4837 if (err < 0)
df694daa
KY
4838 return err;
4839 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4840 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4841 if (err < 0)
df694daa
KY
4842 return err;
4843 return 1;
4844}
4845
4846/* add playback controls from the parsed DAC table */
4847static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4848 const struct auto_pin_cfg *cfg)
4849{
4850 hda_nid_t nid;
4851 int err;
4852
4853 spec->multiout.num_dacs = 1;
4854 spec->multiout.dac_nids = spec->private_dac_nids;
4855 spec->multiout.dac_nids[0] = 0x02;
4856
4857 nid = cfg->line_out_pins[0];
4858 if (nid) {
4859 err = alc260_add_playback_controls(spec, nid, "Front");
4860 if (err < 0)
4861 return err;
4862 }
4863
82bc955f 4864 nid = cfg->speaker_pins[0];
df694daa
KY
4865 if (nid) {
4866 err = alc260_add_playback_controls(spec, nid, "Speaker");
4867 if (err < 0)
4868 return err;
4869 }
4870
eb06ed8f 4871 nid = cfg->hp_pins[0];
df694daa
KY
4872 if (nid) {
4873 err = alc260_add_playback_controls(spec, nid, "Headphone");
4874 if (err < 0)
4875 return err;
4876 }
f12ab1e0 4877 return 0;
df694daa
KY
4878}
4879
4880/* create playback/capture controls for input pins */
4881static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4882 const struct auto_pin_cfg *cfg)
4883{
df694daa
KY
4884 struct hda_input_mux *imux = &spec->private_imux;
4885 int i, err, idx;
4886
4887 for (i = 0; i < AUTO_PIN_LAST; i++) {
4888 if (cfg->input_pins[i] >= 0x12) {
4889 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4890 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4891 auto_pin_cfg_labels[i], idx,
4892 0x07);
df694daa
KY
4893 if (err < 0)
4894 return err;
f12ab1e0
TI
4895 imux->items[imux->num_items].label =
4896 auto_pin_cfg_labels[i];
df694daa
KY
4897 imux->items[imux->num_items].index = idx;
4898 imux->num_items++;
4899 }
f12ab1e0 4900 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4901 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4902 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4903 auto_pin_cfg_labels[i], idx,
4904 0x07);
df694daa
KY
4905 if (err < 0)
4906 return err;
f12ab1e0
TI
4907 imux->items[imux->num_items].label =
4908 auto_pin_cfg_labels[i];
df694daa
KY
4909 imux->items[imux->num_items].index = idx;
4910 imux->num_items++;
4911 }
4912 }
4913 return 0;
4914}
4915
4916static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4917 hda_nid_t nid, int pin_type,
4918 int sel_idx)
4919{
f6c7e546 4920 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
4921 /* need the manual connection? */
4922 if (nid >= 0x12) {
4923 int idx = nid - 0x12;
4924 snd_hda_codec_write(codec, idx + 0x0b, 0,
4925 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4926 }
4927}
4928
4929static void alc260_auto_init_multi_out(struct hda_codec *codec)
4930{
4931 struct alc_spec *spec = codec->spec;
4932 hda_nid_t nid;
4933
bc9f98a9 4934 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4935 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4936 if (nid) {
4937 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4938 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4939 }
df694daa 4940
82bc955f 4941 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4942 if (nid)
4943 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4944
eb06ed8f 4945 nid = spec->autocfg.hp_pins[0];
df694daa 4946 if (nid)
baba8ee9 4947 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4948}
df694daa
KY
4949
4950#define ALC260_PIN_CD_NID 0x16
4951static void alc260_auto_init_analog_input(struct hda_codec *codec)
4952{
4953 struct alc_spec *spec = codec->spec;
4954 int i;
4955
4956 for (i = 0; i < AUTO_PIN_LAST; i++) {
4957 hda_nid_t nid = spec->autocfg.input_pins[i];
4958 if (nid >= 0x12) {
f12ab1e0
TI
4959 snd_hda_codec_write(codec, nid, 0,
4960 AC_VERB_SET_PIN_WIDGET_CONTROL,
4961 i <= AUTO_PIN_FRONT_MIC ?
4962 PIN_VREF80 : PIN_IN);
df694daa 4963 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4964 snd_hda_codec_write(codec, nid, 0,
4965 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4966 AMP_OUT_MUTE);
4967 }
4968 }
4969}
4970
4971/*
4972 * generic initialization of ADC, input mixers and output mixers
4973 */
4974static struct hda_verb alc260_volume_init_verbs[] = {
4975 /*
4976 * Unmute ADC0-1 and set the default input to mic-in
4977 */
4978 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4979 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4980 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4981 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4982
4983 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4984 * mixer widget
f12ab1e0
TI
4985 * Note: PASD motherboards uses the Line In 2 as the input for
4986 * front panel mic (mic 2)
df694daa
KY
4987 */
4988 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4989 /* mute analog inputs */
4990 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4995
4996 /*
4997 * Set up output mixers (0x08 - 0x0a)
4998 */
4999 /* set vol=0 to output mixers */
5000 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5001 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5002 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5003 /* set up input amps for analog loopback */
5004 /* Amp Indices: DAC = 0, mixer = 1 */
5005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5009 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5011
5012 { }
5013};
5014
5015static int alc260_parse_auto_config(struct hda_codec *codec)
5016{
5017 struct alc_spec *spec = codec->spec;
5018 unsigned int wcap;
5019 int err;
5020 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5021
f12ab1e0
TI
5022 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5023 alc260_ignore);
5024 if (err < 0)
df694daa 5025 return err;
f12ab1e0
TI
5026 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5027 if (err < 0)
4a471b7d 5028 return err;
f12ab1e0 5029 if (!spec->kctl_alloc)
df694daa 5030 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5031 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5032 if (err < 0)
df694daa
KY
5033 return err;
5034
5035 spec->multiout.max_channels = 2;
5036
5037 if (spec->autocfg.dig_out_pin)
5038 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5039 if (spec->kctl_alloc)
5040 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5041
5042 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5043
a1e8d2da 5044 spec->num_mux_defs = 1;
df694daa
KY
5045 spec->input_mux = &spec->private_imux;
5046
5047 /* check whether NID 0x04 is valid */
4a471b7d 5048 wcap = get_wcaps(codec, 0x04);
df694daa 5049 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
67ebcb03 5050 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
df694daa
KY
5051 spec->adc_nids = alc260_adc_nids_alt;
5052 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5053 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
5054 } else {
5055 spec->adc_nids = alc260_adc_nids;
5056 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5057 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 5058 }
4a471b7d 5059 spec->num_mixers++;
df694daa
KY
5060
5061 return 1;
5062}
5063
ae6b813a
TI
5064/* additional initialization for auto-configuration model */
5065static void alc260_auto_init(struct hda_codec *codec)
df694daa 5066{
f6c7e546 5067 struct alc_spec *spec = codec->spec;
df694daa
KY
5068 alc260_auto_init_multi_out(codec);
5069 alc260_auto_init_analog_input(codec);
f6c7e546
TI
5070 if (spec->unsol_event)
5071 alc_sku_automute(codec);
df694daa
KY
5072}
5073
cb53c626
TI
5074#ifdef CONFIG_SND_HDA_POWER_SAVE
5075static struct hda_amp_list alc260_loopbacks[] = {
5076 { 0x07, HDA_INPUT, 0 },
5077 { 0x07, HDA_INPUT, 1 },
5078 { 0x07, HDA_INPUT, 2 },
5079 { 0x07, HDA_INPUT, 3 },
5080 { 0x07, HDA_INPUT, 4 },
5081 { } /* end */
5082};
5083#endif
5084
df694daa
KY
5085/*
5086 * ALC260 configurations
5087 */
f5fcc13c
TI
5088static const char *alc260_models[ALC260_MODEL_LAST] = {
5089 [ALC260_BASIC] = "basic",
5090 [ALC260_HP] = "hp",
5091 [ALC260_HP_3013] = "hp-3013",
5092 [ALC260_FUJITSU_S702X] = "fujitsu",
5093 [ALC260_ACER] = "acer",
bc9f98a9
KY
5094 [ALC260_WILL] = "will",
5095 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 5096#ifdef CONFIG_SND_DEBUG
f5fcc13c 5097 [ALC260_TEST] = "test",
7cf51e48 5098#endif
f5fcc13c
TI
5099 [ALC260_AUTO] = "auto",
5100};
5101
5102static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5103 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5104 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5105 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5106 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
5107 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5108 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5109 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5110 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5111 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5112 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5113 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5114 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5115 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5116 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5117 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5118 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5119 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5120 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5121 {}
5122};
5123
5124static struct alc_config_preset alc260_presets[] = {
5125 [ALC260_BASIC] = {
5126 .mixers = { alc260_base_output_mixer,
5127 alc260_input_mixer,
5128 alc260_pc_beep_mixer,
5129 alc260_capture_mixer },
5130 .init_verbs = { alc260_init_verbs },
5131 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5132 .dac_nids = alc260_dac_nids,
5133 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5134 .adc_nids = alc260_adc_nids,
5135 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5136 .channel_mode = alc260_modes,
5137 .input_mux = &alc260_capture_source,
5138 },
5139 [ALC260_HP] = {
bec15c3a 5140 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5141 alc260_input_mixer,
5142 alc260_capture_alt_mixer },
bec15c3a
TI
5143 .init_verbs = { alc260_init_verbs,
5144 alc260_hp_unsol_verbs },
df694daa
KY
5145 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5146 .dac_nids = alc260_dac_nids,
5147 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5148 .adc_nids = alc260_hp_adc_nids,
5149 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5150 .channel_mode = alc260_modes,
5151 .input_mux = &alc260_capture_source,
bec15c3a
TI
5152 .unsol_event = alc260_hp_unsol_event,
5153 .init_hook = alc260_hp_automute,
df694daa
KY
5154 },
5155 [ALC260_HP_3013] = {
5156 .mixers = { alc260_hp_3013_mixer,
5157 alc260_input_mixer,
5158 alc260_capture_alt_mixer },
bec15c3a
TI
5159 .init_verbs = { alc260_hp_3013_init_verbs,
5160 alc260_hp_3013_unsol_verbs },
df694daa
KY
5161 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5162 .dac_nids = alc260_dac_nids,
5163 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5164 .adc_nids = alc260_hp_adc_nids,
5165 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5166 .channel_mode = alc260_modes,
5167 .input_mux = &alc260_capture_source,
bec15c3a
TI
5168 .unsol_event = alc260_hp_3013_unsol_event,
5169 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5170 },
5171 [ALC260_FUJITSU_S702X] = {
5172 .mixers = { alc260_fujitsu_mixer,
5173 alc260_capture_mixer },
5174 .init_verbs = { alc260_fujitsu_init_verbs },
5175 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5176 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5177 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5178 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5179 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5180 .channel_mode = alc260_modes,
a1e8d2da
JW
5181 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5182 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5183 },
0bfc90e9
JW
5184 [ALC260_ACER] = {
5185 .mixers = { alc260_acer_mixer,
5186 alc260_capture_mixer },
5187 .init_verbs = { alc260_acer_init_verbs },
5188 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5189 .dac_nids = alc260_dac_nids,
5190 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5191 .adc_nids = alc260_dual_adc_nids,
5192 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5193 .channel_mode = alc260_modes,
a1e8d2da
JW
5194 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5195 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5196 },
bc9f98a9
KY
5197 [ALC260_WILL] = {
5198 .mixers = { alc260_will_mixer,
5199 alc260_capture_mixer },
5200 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5201 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5202 .dac_nids = alc260_dac_nids,
5203 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5204 .adc_nids = alc260_adc_nids,
5205 .dig_out_nid = ALC260_DIGOUT_NID,
5206 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5207 .channel_mode = alc260_modes,
5208 .input_mux = &alc260_capture_source,
5209 },
5210 [ALC260_REPLACER_672V] = {
5211 .mixers = { alc260_replacer_672v_mixer,
5212 alc260_capture_mixer },
5213 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5214 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5215 .dac_nids = alc260_dac_nids,
5216 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5217 .adc_nids = alc260_adc_nids,
5218 .dig_out_nid = ALC260_DIGOUT_NID,
5219 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5220 .channel_mode = alc260_modes,
5221 .input_mux = &alc260_capture_source,
5222 .unsol_event = alc260_replacer_672v_unsol_event,
5223 .init_hook = alc260_replacer_672v_automute,
5224 },
7cf51e48
JW
5225#ifdef CONFIG_SND_DEBUG
5226 [ALC260_TEST] = {
5227 .mixers = { alc260_test_mixer,
5228 alc260_capture_mixer },
5229 .init_verbs = { alc260_test_init_verbs },
5230 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5231 .dac_nids = alc260_test_dac_nids,
5232 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5233 .adc_nids = alc260_test_adc_nids,
5234 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5235 .channel_mode = alc260_modes,
a1e8d2da
JW
5236 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5237 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5238 },
5239#endif
df694daa
KY
5240};
5241
5242static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5243{
5244 struct alc_spec *spec;
df694daa 5245 int err, board_config;
1da177e4 5246
e560d8d8 5247 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5248 if (spec == NULL)
5249 return -ENOMEM;
5250
5251 codec->spec = spec;
5252
f5fcc13c
TI
5253 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5254 alc260_models,
5255 alc260_cfg_tbl);
5256 if (board_config < 0) {
9c7f852e
TI
5257 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5258 "trying auto-probe from BIOS...\n");
df694daa 5259 board_config = ALC260_AUTO;
16ded525 5260 }
1da177e4 5261
df694daa
KY
5262 if (board_config == ALC260_AUTO) {
5263 /* automatic parse from the BIOS config */
5264 err = alc260_parse_auto_config(codec);
5265 if (err < 0) {
5266 alc_free(codec);
5267 return err;
f12ab1e0 5268 } else if (!err) {
9c7f852e
TI
5269 printk(KERN_INFO
5270 "hda_codec: Cannot set up configuration "
5271 "from BIOS. Using base mode...\n");
df694daa
KY
5272 board_config = ALC260_BASIC;
5273 }
a9430dd8 5274 }
e9edcee0 5275
df694daa
KY
5276 if (board_config != ALC260_AUTO)
5277 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5278
5279 spec->stream_name_analog = "ALC260 Analog";
5280 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5281 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5282
a3bcba38
TI
5283 spec->stream_name_digital = "ALC260 Digital";
5284 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5285 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5286
2134ea4f
TI
5287 spec->vmaster_nid = 0x08;
5288
1da177e4 5289 codec->patch_ops = alc_patch_ops;
df694daa 5290 if (board_config == ALC260_AUTO)
ae6b813a 5291 spec->init_hook = alc260_auto_init;
cb53c626
TI
5292#ifdef CONFIG_SND_HDA_POWER_SAVE
5293 if (!spec->loopback.amplist)
5294 spec->loopback.amplist = alc260_loopbacks;
5295#endif
1da177e4
LT
5296
5297 return 0;
5298}
5299
e9edcee0 5300
1da177e4
LT
5301/*
5302 * ALC882 support
5303 *
5304 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5305 * configuration. Each pin widget can choose any input DACs and a mixer.
5306 * Each ADC is connected from a mixer of all inputs. This makes possible
5307 * 6-channel independent captures.
5308 *
5309 * In addition, an independent DAC for the multi-playback (not used in this
5310 * driver yet).
5311 */
df694daa
KY
5312#define ALC882_DIGOUT_NID 0x06
5313#define ALC882_DIGIN_NID 0x0a
1da177e4 5314
d2a6d7dc 5315static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5316 { 8, NULL }
5317};
5318
5319static hda_nid_t alc882_dac_nids[4] = {
5320 /* front, rear, clfe, rear_surr */
5321 0x02, 0x03, 0x04, 0x05
5322};
5323
df694daa
KY
5324/* identical with ALC880 */
5325#define alc882_adc_nids alc880_adc_nids
5326#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5327
e1406348
TI
5328static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5329static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5330
1da177e4
LT
5331/* input MUX */
5332/* FIXME: should be a matrix-type input source selection */
5333
5334static struct hda_input_mux alc882_capture_source = {
5335 .num_items = 4,
5336 .items = {
5337 { "Mic", 0x0 },
5338 { "Front Mic", 0x1 },
5339 { "Line", 0x2 },
5340 { "CD", 0x4 },
5341 },
5342};
1da177e4
LT
5343#define alc882_mux_enum_info alc_mux_enum_info
5344#define alc882_mux_enum_get alc_mux_enum_get
5345
f12ab1e0
TI
5346static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5347 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5348{
5349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5350 struct alc_spec *spec = codec->spec;
5351 const struct hda_input_mux *imux = spec->input_mux;
5352 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
88c71a99
TI
5353 hda_nid_t nid = spec->capsrc_nids ?
5354 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4
LT
5355 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5356 unsigned int i, idx;
5357
5358 idx = ucontrol->value.enumerated.item[0];
5359 if (idx >= imux->num_items)
5360 idx = imux->num_items - 1;
82beb8fd 5361 if (*cur_val == idx)
1da177e4
LT
5362 return 0;
5363 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5364 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5365 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5366 imux->items[i].index,
47fd830a 5367 HDA_AMP_MUTE, v);
1da177e4
LT
5368 }
5369 *cur_val = idx;
5370 return 1;
5371}
5372
272a527c
KY
5373/*
5374 * 2ch mode
5375 */
5376static struct hda_verb alc882_3ST_ch2_init[] = {
5377 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5378 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5379 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5380 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5381 { } /* end */
5382};
5383
5384/*
5385 * 6ch mode
5386 */
5387static struct hda_verb alc882_3ST_ch6_init[] = {
5388 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5389 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5390 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5391 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5392 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5393 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5394 { } /* end */
5395};
5396
5397static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5398 { 2, alc882_3ST_ch2_init },
5399 { 6, alc882_3ST_ch6_init },
5400};
5401
df694daa
KY
5402/*
5403 * 6ch mode
5404 */
5405static struct hda_verb alc882_sixstack_ch6_init[] = {
5406 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5407 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5408 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5409 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5410 { } /* end */
5411};
5412
5413/*
5414 * 8ch mode
5415 */
5416static struct hda_verb alc882_sixstack_ch8_init[] = {
5417 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5418 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5419 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5420 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5421 { } /* end */
5422};
5423
5424static struct hda_channel_mode alc882_sixstack_modes[2] = {
5425 { 6, alc882_sixstack_ch6_init },
5426 { 8, alc882_sixstack_ch8_init },
5427};
5428
87350ad0
TI
5429/*
5430 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5431 */
5432
5433/*
5434 * 2ch mode
5435 */
5436static struct hda_verb alc885_mbp_ch2_init[] = {
5437 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5438 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5439 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5440 { } /* end */
5441};
5442
5443/*
5444 * 6ch mode
5445 */
5446static struct hda_verb alc885_mbp_ch6_init[] = {
5447 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5448 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5449 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5450 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5451 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5452 { } /* end */
5453};
5454
5455static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5456 { 2, alc885_mbp_ch2_init },
5457 { 6, alc885_mbp_ch6_init },
5458};
5459
5460
1da177e4
LT
5461/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5462 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5463 */
c8b6bf9b 5464static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5465 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5466 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5468 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5471 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5473 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5474 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5476 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5477 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5478 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5479 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5481 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5483 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5484 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5486 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5487 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5488 { } /* end */
5489};
5490
87350ad0 5491static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5493 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5494 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5495 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5496 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5497 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5499 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5500 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5501 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5502 { } /* end */
5503};
bdd148a3
KY
5504static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5505 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5506 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5507 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5508 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5509 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5510 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5512 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5513 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5514 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5515 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5516 { } /* end */
5517};
5518
272a527c
KY
5519static struct snd_kcontrol_new alc882_targa_mixer[] = {
5520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5521 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5522 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5523 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5524 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5525 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5526 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5527 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5528 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5529 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5530 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5531 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5532 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5533 { } /* end */
5534};
5535
5536/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5537 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5538 */
5539static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5541 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5543 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5545 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5546 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5547 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5548 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5549 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5550 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5551 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5552 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5553 { } /* end */
5554};
5555
914759b7
TI
5556static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5557 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5558 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5560 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5561 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5562 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5563 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5565 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5566 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5567 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5568 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5569 { } /* end */
5570};
5571
df694daa
KY
5572static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5573 {
5574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5575 .name = "Channel Mode",
5576 .info = alc_ch_mode_info,
5577 .get = alc_ch_mode_get,
5578 .put = alc_ch_mode_put,
5579 },
5580 { } /* end */
5581};
5582
1da177e4
LT
5583static struct hda_verb alc882_init_verbs[] = {
5584 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5588 /* Rear mixer */
05acb863
TI
5589 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5592 /* CLFE mixer */
05acb863
TI
5593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5595 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5596 /* Side mixer */
05acb863
TI
5597 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5598 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5599 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5600
e9edcee0 5601 /* Front Pin: output 0 (0x0c) */
05acb863 5602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5604 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5605 /* Rear Pin: output 1 (0x0d) */
05acb863 5606 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5607 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5609 /* CLFE Pin: output 2 (0x0e) */
05acb863 5610 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5611 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5612 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5613 /* Side Pin: output 3 (0x0f) */
05acb863 5614 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5615 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5616 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5617 /* Mic (rear) pin: input vref at 80% */
16ded525 5618 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5620 /* Front Mic pin: input vref at 80% */
16ded525 5621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5622 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5623 /* Line In pin: input */
05acb863 5624 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5625 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5626 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5628 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5629 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5630 /* CD pin widget for input */
05acb863 5631 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5632
5633 /* FIXME: use matrix-type input source selection */
5634 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5635 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5636 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5637 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5638 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5639 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5640 /* Input mixer2 */
05acb863
TI
5641 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5642 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5643 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5644 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5645 /* Input mixer3 */
05acb863
TI
5646 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5647 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5648 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5649 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5650 /* ADC1: mute amp left and right */
5651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5652 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5653 /* ADC2: mute amp left and right */
5654 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5655 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5656 /* ADC3: mute amp left and right */
5657 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5658 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5659
5660 { }
5661};
5662
4b146cb0
TI
5663static struct hda_verb alc882_eapd_verbs[] = {
5664 /* change to EAPD mode */
5665 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5666 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5667 { }
4b146cb0
TI
5668};
5669
9102cd1c
TD
5670/* Mac Pro test */
5671static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5672 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5673 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5677 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5678 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5679 { } /* end */
5680};
5681
5682static struct hda_verb alc882_macpro_init_verbs[] = {
5683 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5686 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5687 /* Front Pin: output 0 (0x0c) */
5688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5690 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5691 /* Front Mic pin: input vref at 80% */
5692 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5694 /* Speaker: output */
5695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5697 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5698 /* Headphone output (output 0 - 0x0c) */
5699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5701 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5702
5703 /* FIXME: use matrix-type input source selection */
5704 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5705 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5709 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5710 /* Input mixer2 */
5711 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5712 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5713 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5714 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5715 /* Input mixer3 */
5716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5719 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5720 /* ADC1: mute amp left and right */
5721 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5722 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5723 /* ADC2: mute amp left and right */
5724 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5725 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5726 /* ADC3: mute amp left and right */
5727 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5728 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5729
5730 { }
5731};
f12ab1e0 5732
87350ad0
TI
5733/* Macbook Pro rev3 */
5734static struct hda_verb alc885_mbp3_init_verbs[] = {
5735 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5739 /* Rear mixer */
5740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5743 /* Front Pin: output 0 (0x0c) */
5744 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5746 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5747 /* HP Pin: output 0 (0x0d) */
5748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5750 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5751 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5752 /* Mic (rear) pin: input vref at 80% */
5753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5755 /* Front Mic pin: input vref at 80% */
5756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5758 /* Line In pin: use output 1 when in LineOut mode */
5759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5761 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5762
5763 /* FIXME: use matrix-type input source selection */
5764 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5765 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5770 /* Input mixer2 */
5771 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5772 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5773 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5774 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5775 /* Input mixer3 */
5776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5780 /* ADC1: mute amp left and right */
5781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5782 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5783 /* ADC2: mute amp left and right */
5784 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5785 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5786 /* ADC3: mute amp left and right */
5787 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5788 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5789
5790 { }
5791};
5792
c54728d8
NF
5793/* iMac 24 mixer. */
5794static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5795 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5796 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5797 { } /* end */
5798};
5799
5800/* iMac 24 init verbs. */
5801static struct hda_verb alc885_imac24_init_verbs[] = {
5802 /* Internal speakers: output 0 (0x0c) */
5803 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5805 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5806 /* Internal speakers: output 0 (0x0c) */
5807 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5809 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5810 /* Headphone: output 0 (0x0c) */
5811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5813 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5815 /* Front Mic: input vref at 80% */
5816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5818 { }
5819};
5820
5821/* Toggle speaker-output according to the hp-jack state */
5822static void alc885_imac24_automute(struct hda_codec *codec)
5823{
5824 unsigned int present;
5825
5826 present = snd_hda_codec_read(codec, 0x14, 0,
5827 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5828 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5829 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5830 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5831 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5832}
5833
5834/* Processes unsolicited events. */
5835static void alc885_imac24_unsol_event(struct hda_codec *codec,
5836 unsigned int res)
5837{
5838 /* Headphone insertion or removal. */
5839 if ((res >> 26) == ALC880_HP_EVENT)
5840 alc885_imac24_automute(codec);
5841}
5842
87350ad0
TI
5843static void alc885_mbp3_automute(struct hda_codec *codec)
5844{
5845 unsigned int present;
5846
5847 present = snd_hda_codec_read(codec, 0x15, 0,
5848 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5849 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5850 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5851 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5852 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5853
5854}
5855static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5856 unsigned int res)
5857{
5858 /* Headphone insertion or removal. */
5859 if ((res >> 26) == ALC880_HP_EVENT)
5860 alc885_mbp3_automute(codec);
5861}
5862
5863
272a527c
KY
5864static struct hda_verb alc882_targa_verbs[] = {
5865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5866 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5867
5868 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5869 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5870
5871 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5872 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5873 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5874
5875 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5876 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5877 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5878 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5879 { } /* end */
5880};
5881
5882/* toggle speaker-output according to the hp-jack state */
5883static void alc882_targa_automute(struct hda_codec *codec)
5884{
5885 unsigned int present;
5886
5887 present = snd_hda_codec_read(codec, 0x14, 0,
5888 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5889 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5890 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5891 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5892 present ? 1 : 3);
272a527c
KY
5893}
5894
5895static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5896{
5897 /* Looks like the unsol event is incompatible with the standard
5898 * definition. 4bit tag is placed at 26 bit!
5899 */
5900 if (((res >> 26) == ALC880_HP_EVENT)) {
5901 alc882_targa_automute(codec);
5902 }
5903}
5904
5905static struct hda_verb alc882_asus_a7j_verbs[] = {
5906 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5907 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5908
5909 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5910 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5911 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5912
5913 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5915 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5916
5917 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5918 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5919 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5920 { } /* end */
5921};
5922
914759b7
TI
5923static struct hda_verb alc882_asus_a7m_verbs[] = {
5924 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5925 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5926
5927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5928 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5929 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5930
5931 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5933 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5934
5935 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5936 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5937 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5938 { } /* end */
5939};
5940
9102cd1c
TD
5941static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5942{
5943 unsigned int gpiostate, gpiomask, gpiodir;
5944
5945 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5946 AC_VERB_GET_GPIO_DATA, 0);
5947
5948 if (!muted)
5949 gpiostate |= (1 << pin);
5950 else
5951 gpiostate &= ~(1 << pin);
5952
5953 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5954 AC_VERB_GET_GPIO_MASK, 0);
5955 gpiomask |= (1 << pin);
5956
5957 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5958 AC_VERB_GET_GPIO_DIRECTION, 0);
5959 gpiodir |= (1 << pin);
5960
5961
5962 snd_hda_codec_write(codec, codec->afg, 0,
5963 AC_VERB_SET_GPIO_MASK, gpiomask);
5964 snd_hda_codec_write(codec, codec->afg, 0,
5965 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5966
5967 msleep(1);
5968
5969 snd_hda_codec_write(codec, codec->afg, 0,
5970 AC_VERB_SET_GPIO_DATA, gpiostate);
5971}
5972
7debbe51
TI
5973/* set up GPIO at initialization */
5974static void alc885_macpro_init_hook(struct hda_codec *codec)
5975{
5976 alc882_gpio_mute(codec, 0, 0);
5977 alc882_gpio_mute(codec, 1, 0);
5978}
5979
5980/* set up GPIO and update auto-muting at initialization */
5981static void alc885_imac24_init_hook(struct hda_codec *codec)
5982{
5983 alc885_macpro_init_hook(codec);
5984 alc885_imac24_automute(codec);
5985}
5986
df694daa
KY
5987/*
5988 * generic initialization of ADC, input mixers and output mixers
5989 */
5990static struct hda_verb alc882_auto_init_verbs[] = {
5991 /*
5992 * Unmute ADC0-2 and set the default input to mic-in
5993 */
5994 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5996 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5997 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5998 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5999 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6000
cb53c626 6001 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6002 * mixer widget
f12ab1e0
TI
6003 * Note: PASD motherboards uses the Line In 2 as the input for
6004 * front panel mic (mic 2)
df694daa
KY
6005 */
6006 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 6012
df694daa
KY
6013 /*
6014 * Set up output mixers (0x0c - 0x0f)
6015 */
6016 /* set vol=0 to output mixers */
6017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6019 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6021 /* set up input amps for analog loopback */
6022 /* Amp Indices: DAC = 0, mixer = 1 */
6023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6025 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6027 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6029 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6030 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6031 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6032 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6033
6034 /* FIXME: use matrix-type input source selection */
6035 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6036 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6040 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6041 /* Input mixer2 */
6042 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6043 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6044 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6046 /* Input mixer3 */
6047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6051
6052 { }
6053};
6054
6055/* capture mixer elements */
6056static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6057 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6058 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6059 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6060 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6061 {
6062 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6063 /* The multiple "Capture Source" controls confuse alsamixer
6064 * So call somewhat different..
df694daa
KY
6065 */
6066 /* .name = "Capture Source", */
6067 .name = "Input Source",
6068 .count = 2,
6069 .info = alc882_mux_enum_info,
6070 .get = alc882_mux_enum_get,
6071 .put = alc882_mux_enum_put,
6072 },
6073 { } /* end */
6074};
6075
6076static struct snd_kcontrol_new alc882_capture_mixer[] = {
6077 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6078 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6079 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6080 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6081 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6082 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6083 {
6084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6085 /* The multiple "Capture Source" controls confuse alsamixer
6086 * So call somewhat different..
df694daa
KY
6087 */
6088 /* .name = "Capture Source", */
6089 .name = "Input Source",
6090 .count = 3,
6091 .info = alc882_mux_enum_info,
6092 .get = alc882_mux_enum_get,
6093 .put = alc882_mux_enum_put,
6094 },
6095 { } /* end */
6096};
6097
cb53c626
TI
6098#ifdef CONFIG_SND_HDA_POWER_SAVE
6099#define alc882_loopbacks alc880_loopbacks
6100#endif
6101
df694daa
KY
6102/* pcm configuration: identiacal with ALC880 */
6103#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6104#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6105#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6106#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6107
6108/*
6109 * configuration and preset
6110 */
f5fcc13c
TI
6111static const char *alc882_models[ALC882_MODEL_LAST] = {
6112 [ALC882_3ST_DIG] = "3stack-dig",
6113 [ALC882_6ST_DIG] = "6stack-dig",
6114 [ALC882_ARIMA] = "arima",
bdd148a3 6115 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6116 [ALC882_TARGA] = "targa",
6117 [ALC882_ASUS_A7J] = "asus-a7j",
6118 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6119 [ALC885_MACPRO] = "macpro",
87350ad0 6120 [ALC885_MBP3] = "mbp3",
c54728d8 6121 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6122 [ALC882_AUTO] = "auto",
6123};
6124
6125static struct snd_pci_quirk alc882_cfg_tbl[] = {
6126 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6127 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6128 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6129 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6130 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6131 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6132 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6133 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6134 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6135 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6136 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6137 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6138 {}
6139};
6140
6141static struct alc_config_preset alc882_presets[] = {
6142 [ALC882_3ST_DIG] = {
6143 .mixers = { alc882_base_mixer },
6144 .init_verbs = { alc882_init_verbs },
6145 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6146 .dac_nids = alc882_dac_nids,
6147 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6148 .dig_in_nid = ALC882_DIGIN_NID,
6149 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6150 .channel_mode = alc882_ch_modes,
4e195a7b 6151 .need_dac_fix = 1,
df694daa
KY
6152 .input_mux = &alc882_capture_source,
6153 },
6154 [ALC882_6ST_DIG] = {
6155 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6156 .init_verbs = { alc882_init_verbs },
6157 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6158 .dac_nids = alc882_dac_nids,
6159 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6160 .dig_in_nid = ALC882_DIGIN_NID,
6161 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6162 .channel_mode = alc882_sixstack_modes,
6163 .input_mux = &alc882_capture_source,
6164 },
4b146cb0
TI
6165 [ALC882_ARIMA] = {
6166 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6167 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6168 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6169 .dac_nids = alc882_dac_nids,
6170 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6171 .channel_mode = alc882_sixstack_modes,
6172 .input_mux = &alc882_capture_source,
6173 },
bdd148a3
KY
6174 [ALC882_W2JC] = {
6175 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6176 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6177 alc880_gpio1_init_verbs },
6178 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6179 .dac_nids = alc882_dac_nids,
6180 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6181 .channel_mode = alc880_threestack_modes,
6182 .need_dac_fix = 1,
6183 .input_mux = &alc882_capture_source,
6184 .dig_out_nid = ALC882_DIGOUT_NID,
6185 },
87350ad0
TI
6186 [ALC885_MBP3] = {
6187 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6188 .init_verbs = { alc885_mbp3_init_verbs,
6189 alc880_gpio1_init_verbs },
6190 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6191 .dac_nids = alc882_dac_nids,
6192 .channel_mode = alc885_mbp_6ch_modes,
6193 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6194 .input_mux = &alc882_capture_source,
6195 .dig_out_nid = ALC882_DIGOUT_NID,
6196 .dig_in_nid = ALC882_DIGIN_NID,
6197 .unsol_event = alc885_mbp3_unsol_event,
6198 .init_hook = alc885_mbp3_automute,
6199 },
9102cd1c
TD
6200 [ALC885_MACPRO] = {
6201 .mixers = { alc882_macpro_mixer },
6202 .init_verbs = { alc882_macpro_init_verbs },
6203 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6204 .dac_nids = alc882_dac_nids,
6205 .dig_out_nid = ALC882_DIGOUT_NID,
6206 .dig_in_nid = ALC882_DIGIN_NID,
6207 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6208 .channel_mode = alc882_ch_modes,
6209 .input_mux = &alc882_capture_source,
7debbe51 6210 .init_hook = alc885_macpro_init_hook,
9102cd1c 6211 },
c54728d8
NF
6212 [ALC885_IMAC24] = {
6213 .mixers = { alc885_imac24_mixer },
6214 .init_verbs = { alc885_imac24_init_verbs },
6215 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6216 .dac_nids = alc882_dac_nids,
6217 .dig_out_nid = ALC882_DIGOUT_NID,
6218 .dig_in_nid = ALC882_DIGIN_NID,
6219 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6220 .channel_mode = alc882_ch_modes,
6221 .input_mux = &alc882_capture_source,
6222 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6223 .init_hook = alc885_imac24_init_hook,
c54728d8 6224 },
272a527c
KY
6225 [ALC882_TARGA] = {
6226 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6227 alc882_capture_mixer },
6228 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6229 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6230 .dac_nids = alc882_dac_nids,
6231 .dig_out_nid = ALC882_DIGOUT_NID,
6232 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6233 .adc_nids = alc882_adc_nids,
e1406348 6234 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6235 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6236 .channel_mode = alc882_3ST_6ch_modes,
6237 .need_dac_fix = 1,
6238 .input_mux = &alc882_capture_source,
6239 .unsol_event = alc882_targa_unsol_event,
6240 .init_hook = alc882_targa_automute,
6241 },
6242 [ALC882_ASUS_A7J] = {
6243 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6244 alc882_capture_mixer },
6245 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6246 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6247 .dac_nids = alc882_dac_nids,
6248 .dig_out_nid = ALC882_DIGOUT_NID,
6249 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6250 .adc_nids = alc882_adc_nids,
e1406348 6251 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6252 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6253 .channel_mode = alc882_3ST_6ch_modes,
6254 .need_dac_fix = 1,
6255 .input_mux = &alc882_capture_source,
6256 },
914759b7
TI
6257 [ALC882_ASUS_A7M] = {
6258 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6259 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6260 alc880_gpio1_init_verbs,
6261 alc882_asus_a7m_verbs },
6262 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6263 .dac_nids = alc882_dac_nids,
6264 .dig_out_nid = ALC882_DIGOUT_NID,
6265 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6266 .channel_mode = alc880_threestack_modes,
6267 .need_dac_fix = 1,
6268 .input_mux = &alc882_capture_source,
6269 },
df694daa
KY
6270};
6271
6272
f95474ec
TI
6273/*
6274 * Pin config fixes
6275 */
6276enum {
6277 PINFIX_ABIT_AW9D_MAX
6278};
6279
6280static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6281 { 0x15, 0x01080104 }, /* side */
6282 { 0x16, 0x01011012 }, /* rear */
6283 { 0x17, 0x01016011 }, /* clfe */
6284 { }
6285};
6286
6287static const struct alc_pincfg *alc882_pin_fixes[] = {
6288 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6289};
6290
6291static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6292 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6293 {}
6294};
6295
df694daa
KY
6296/*
6297 * BIOS auto configuration
6298 */
6299static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6300 hda_nid_t nid, int pin_type,
6301 int dac_idx)
6302{
6303 /* set as output */
6304 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6305 int idx;
6306
f6c7e546 6307 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6308 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6309 idx = 4;
6310 else
6311 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6312 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6313
6314}
6315
6316static void alc882_auto_init_multi_out(struct hda_codec *codec)
6317{
6318 struct alc_spec *spec = codec->spec;
6319 int i;
6320
bc9f98a9 6321 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6322 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6323 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6324 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6325 if (nid)
baba8ee9 6326 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6327 i);
df694daa
KY
6328 }
6329}
6330
6331static void alc882_auto_init_hp_out(struct hda_codec *codec)
6332{
6333 struct alc_spec *spec = codec->spec;
6334 hda_nid_t pin;
6335
eb06ed8f 6336 pin = spec->autocfg.hp_pins[0];
df694daa 6337 if (pin) /* connect to front */
f12ab1e0
TI
6338 /* use dac 0 */
6339 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6340 pin = spec->autocfg.speaker_pins[0];
6341 if (pin)
6342 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6343}
6344
6345#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6346#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6347
6348static void alc882_auto_init_analog_input(struct hda_codec *codec)
6349{
6350 struct alc_spec *spec = codec->spec;
6351 int i;
6352
6353 for (i = 0; i < AUTO_PIN_LAST; i++) {
6354 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
6355 unsigned int vref;
6356 if (!nid)
6357 continue;
6358 vref = PIN_IN;
6359 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6360 if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) &
6361 AC_PINCAP_VREF_80)
6362 vref = PIN_VREF80;
df694daa 6363 }
7194cae6
TI
6364 snd_hda_codec_write(codec, nid, 0,
6365 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6366 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6367 snd_hda_codec_write(codec, nid, 0,
6368 AC_VERB_SET_AMP_GAIN_MUTE,
6369 AMP_OUT_MUTE);
df694daa
KY
6370 }
6371}
6372
776e184e
TI
6373/* add mic boosts if needed */
6374static int alc_auto_add_mic_boost(struct hda_codec *codec)
6375{
6376 struct alc_spec *spec = codec->spec;
6377 int err;
6378 hda_nid_t nid;
6379
6380 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6381 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6382 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6383 "Mic Boost",
6384 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6385 if (err < 0)
6386 return err;
6387 }
6388 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6389 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6390 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6391 "Front Mic Boost",
6392 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6393 if (err < 0)
6394 return err;
6395 }
6396 return 0;
6397}
6398
df694daa
KY
6399/* almost identical with ALC880 parser... */
6400static int alc882_parse_auto_config(struct hda_codec *codec)
6401{
6402 struct alc_spec *spec = codec->spec;
6403 int err = alc880_parse_auto_config(codec);
6404
6405 if (err < 0)
6406 return err;
776e184e
TI
6407 else if (!err)
6408 return 0; /* no config found */
6409
6410 err = alc_auto_add_mic_boost(codec);
6411 if (err < 0)
6412 return err;
6413
6414 /* hack - override the init verbs */
6415 spec->init_verbs[0] = alc882_auto_init_verbs;
6416
6417 return 1; /* config found */
df694daa
KY
6418}
6419
ae6b813a
TI
6420/* additional initialization for auto-configuration model */
6421static void alc882_auto_init(struct hda_codec *codec)
df694daa 6422{
f6c7e546 6423 struct alc_spec *spec = codec->spec;
df694daa
KY
6424 alc882_auto_init_multi_out(codec);
6425 alc882_auto_init_hp_out(codec);
6426 alc882_auto_init_analog_input(codec);
f6c7e546
TI
6427 if (spec->unsol_event)
6428 alc_sku_automute(codec);
df694daa
KY
6429}
6430
7943a8ab
TI
6431static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6432
df694daa
KY
6433static int patch_alc882(struct hda_codec *codec)
6434{
6435 struct alc_spec *spec;
6436 int err, board_config;
6437
6438 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6439 if (spec == NULL)
6440 return -ENOMEM;
6441
6442 codec->spec = spec;
6443
f5fcc13c
TI
6444 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6445 alc882_models,
6446 alc882_cfg_tbl);
df694daa
KY
6447
6448 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6449 /* Pick up systems that don't supply PCI SSID */
6450 switch (codec->subsystem_id) {
6451 case 0x106b0c00: /* Mac Pro */
6452 board_config = ALC885_MACPRO;
6453 break;
c54728d8
NF
6454 case 0x106b1000: /* iMac 24 */
6455 board_config = ALC885_IMAC24;
6456 break;
3d5fa2e5 6457 case 0x106b00a1: /* Macbook */
87350ad0
TI
6458 case 0x106b2c00: /* Macbook Pro rev3 */
6459 board_config = ALC885_MBP3;
6460 break;
081d17c4 6461 default:
7943a8ab
TI
6462 /* ALC889A is handled better as ALC888-compatible */
6463 if (codec->revision_id == 0x100103) {
6464 alc_free(codec);
6465 return patch_alc883(codec);
6466 }
081d17c4
TD
6467 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6468 "trying auto-probe from BIOS...\n");
6469 board_config = ALC882_AUTO;
6470 }
df694daa
KY
6471 }
6472
f95474ec
TI
6473 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6474
df694daa
KY
6475 if (board_config == ALC882_AUTO) {
6476 /* automatic parse from the BIOS config */
6477 err = alc882_parse_auto_config(codec);
6478 if (err < 0) {
6479 alc_free(codec);
6480 return err;
f12ab1e0 6481 } else if (!err) {
9c7f852e
TI
6482 printk(KERN_INFO
6483 "hda_codec: Cannot set up configuration "
6484 "from BIOS. Using base mode...\n");
df694daa
KY
6485 board_config = ALC882_3ST_DIG;
6486 }
6487 }
6488
6489 if (board_config != ALC882_AUTO)
6490 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6491
6492 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6493 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6494 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6495 /* FIXME: setup DAC5 */
6496 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6497 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
6498
6499 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6500 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6501 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6502
f12ab1e0 6503 if (!spec->adc_nids && spec->input_mux) {
df694daa 6504 /* check whether NID 0x07 is valid */
4a471b7d 6505 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6506 /* get type */
6507 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6508 if (wcap != AC_WID_AUD_IN) {
6509 spec->adc_nids = alc882_adc_nids_alt;
6510 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6511 spec->capsrc_nids = alc882_capsrc_nids_alt;
f12ab1e0
TI
6512 spec->mixers[spec->num_mixers] =
6513 alc882_capture_alt_mixer;
df694daa
KY
6514 spec->num_mixers++;
6515 } else {
6516 spec->adc_nids = alc882_adc_nids;
6517 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6518 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
6519 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6520 spec->num_mixers++;
6521 }
6522 }
1da177e4 6523
2134ea4f
TI
6524 spec->vmaster_nid = 0x0c;
6525
1da177e4 6526 codec->patch_ops = alc_patch_ops;
df694daa 6527 if (board_config == ALC882_AUTO)
ae6b813a 6528 spec->init_hook = alc882_auto_init;
cb53c626
TI
6529#ifdef CONFIG_SND_HDA_POWER_SAVE
6530 if (!spec->loopback.amplist)
6531 spec->loopback.amplist = alc882_loopbacks;
6532#endif
df694daa
KY
6533
6534 return 0;
6535}
6536
6537/*
9c7f852e
TI
6538 * ALC883 support
6539 *
6540 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6541 * configuration. Each pin widget can choose any input DACs and a mixer.
6542 * Each ADC is connected from a mixer of all inputs. This makes possible
6543 * 6-channel independent captures.
6544 *
6545 * In addition, an independent DAC for the multi-playback (not used in this
6546 * driver yet).
df694daa 6547 */
9c7f852e
TI
6548#define ALC883_DIGOUT_NID 0x06
6549#define ALC883_DIGIN_NID 0x0a
df694daa 6550
9c7f852e
TI
6551static hda_nid_t alc883_dac_nids[4] = {
6552 /* front, rear, clfe, rear_surr */
f32a19e3 6553 0x02, 0x03, 0x04, 0x05
9c7f852e 6554};
df694daa 6555
9c7f852e
TI
6556static hda_nid_t alc883_adc_nids[2] = {
6557 /* ADC1-2 */
6558 0x08, 0x09,
6559};
f12ab1e0 6560
e1406348
TI
6561static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6562
9c7f852e
TI
6563/* input MUX */
6564/* FIXME: should be a matrix-type input source selection */
df694daa 6565
9c7f852e
TI
6566static struct hda_input_mux alc883_capture_source = {
6567 .num_items = 4,
6568 .items = {
6569 { "Mic", 0x0 },
6570 { "Front Mic", 0x1 },
6571 { "Line", 0x2 },
6572 { "CD", 0x4 },
6573 },
6574};
bc9f98a9
KY
6575
6576static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6577 .num_items = 2,
6578 .items = {
6579 { "Mic", 0x1 },
6580 { "Line", 0x2 },
6581 },
6582};
6583
272a527c
KY
6584static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6585 .num_items = 4,
6586 .items = {
6587 { "Mic", 0x0 },
6588 { "iMic", 0x1 },
6589 { "Line", 0x2 },
6590 { "CD", 0x4 },
6591 },
6592};
6593
fb97dc67
J
6594static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6595 .num_items = 2,
6596 .items = {
6597 { "Mic", 0x0 },
6598 { "Int Mic", 0x1 },
6599 },
6600};
6601
9c7f852e
TI
6602#define alc883_mux_enum_info alc_mux_enum_info
6603#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6604/* ALC883 has the ALC882-type input selection */
6605#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6606
9c7f852e
TI
6607/*
6608 * 2ch mode
6609 */
6610static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6611 { 2, NULL }
6612};
6613
6614/*
6615 * 2ch mode
6616 */
6617static struct hda_verb alc883_3ST_ch2_init[] = {
6618 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6619 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6620 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6621 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6622 { } /* end */
6623};
6624
b201131c
TD
6625/*
6626 * 4ch mode
6627 */
6628static struct hda_verb alc883_3ST_ch4_init[] = {
6629 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6630 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6631 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6632 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6633 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6634 { } /* end */
6635};
6636
9c7f852e
TI
6637/*
6638 * 6ch mode
6639 */
6640static struct hda_verb alc883_3ST_ch6_init[] = {
6641 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6642 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6643 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6644 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6645 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6646 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6647 { } /* end */
6648};
6649
b201131c 6650static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6651 { 2, alc883_3ST_ch2_init },
b201131c 6652 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6653 { 6, alc883_3ST_ch6_init },
6654};
6655
6656/*
6657 * 6ch mode
6658 */
6659static struct hda_verb alc883_sixstack_ch6_init[] = {
6660 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6661 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6662 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6663 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6664 { } /* end */
6665};
6666
6667/*
6668 * 8ch mode
6669 */
6670static struct hda_verb alc883_sixstack_ch8_init[] = {
6671 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6672 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6673 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6674 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6675 { } /* end */
6676};
6677
6678static struct hda_channel_mode alc883_sixstack_modes[2] = {
6679 { 6, alc883_sixstack_ch6_init },
6680 { 8, alc883_sixstack_ch8_init },
6681};
6682
b373bdeb
AN
6683static struct hda_verb alc883_medion_eapd_verbs[] = {
6684 /* eanable EAPD on medion laptop */
6685 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6686 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6687 { }
6688};
6689
9c7f852e
TI
6690/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6691 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6692 */
6693
6694static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6697 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6698 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6699 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6700 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6701 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6702 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6703 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6704 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6705 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6711 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6712 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6713 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6714 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6715 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6716 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6717 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6718 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6719 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6720 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6721 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6722 {
6723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6724 /* .name = "Capture Source", */
6725 .name = "Input Source",
6726 .count = 2,
6727 .info = alc883_mux_enum_info,
6728 .get = alc883_mux_enum_get,
6729 .put = alc883_mux_enum_put,
6730 },
df694daa 6731 { } /* end */
834be88d
TI
6732};
6733
a8848bd6
AS
6734static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6735 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6736 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6737 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6738 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6739 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6740 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6741 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6742 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6743 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6746 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6747 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6748 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6749 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6750 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6751 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6752 {
6753 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6754 /* .name = "Capture Source", */
6755 .name = "Input Source",
6756 .count = 2,
6757 .info = alc883_mux_enum_info,
6758 .get = alc883_mux_enum_get,
6759 .put = alc883_mux_enum_put,
6760 },
6761 { } /* end */
6762};
6763
0c4cc443 6764static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
6765 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6766 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6767 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6768 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6772 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6773 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6774 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6775 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6776 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6777 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6778 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6779 {
6780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6781 /* .name = "Capture Source", */
6782 .name = "Input Source",
6783 .count = 2,
6784 .info = alc883_mux_enum_info,
6785 .get = alc883_mux_enum_get,
6786 .put = alc883_mux_enum_put,
6787 },
6788 { } /* end */
6789};
6790
fb97dc67
J
6791static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
6792 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6793 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6794 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6795 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6796 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6797 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6798 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6799 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6800 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6801 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6802 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6803 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6804 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6805 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6806 {
6807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6808 /* .name = "Capture Source", */
6809 .name = "Input Source",
6810 .count = 2,
6811 .info = alc883_mux_enum_info,
6812 .get = alc883_mux_enum_get,
6813 .put = alc883_mux_enum_put,
6814 },
6815 { } /* end */
6816};
6817
9c7f852e
TI
6818static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6819 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6820 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6822 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6823 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6824 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6825 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6827 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6828 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6829 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6830 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6831 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6832 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6833 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6834 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6835 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6836 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6837 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6838 {
6839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6840 /* .name = "Capture Source", */
6841 .name = "Input Source",
6842 .count = 2,
6843 .info = alc883_mux_enum_info,
6844 .get = alc883_mux_enum_get,
6845 .put = alc883_mux_enum_put,
6846 },
6847 { } /* end */
6848};
df694daa 6849
9c7f852e
TI
6850static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6851 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6852 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6853 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6854 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6855 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6856 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6857 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6858 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6860 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6861 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6862 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6863 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6864 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6865 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6866 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6867 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6868 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6869 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6870 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6871 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6872 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6873 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6874 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6875 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6876 {
6877 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6878 /* .name = "Capture Source", */
6879 .name = "Input Source",
6880 .count = 2,
6881 .info = alc883_mux_enum_info,
6882 .get = alc883_mux_enum_get,
6883 .put = alc883_mux_enum_put,
6884 },
6885 { } /* end */
6886};
6887
d1d985f0 6888static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6889 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6890 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6891 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6892 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6893 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6894 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6895 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6896 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6903 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6905 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6906 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6908 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6909 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6910 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6911 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6912
6913 {
6914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6915 /* .name = "Capture Source", */
6916 .name = "Input Source",
6917 .count = 1,
6918 .info = alc883_mux_enum_info,
6919 .get = alc883_mux_enum_get,
6920 .put = alc883_mux_enum_put,
6921 },
6922 { } /* end */
6923};
6924
ccc656ce
KY
6925static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6926 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6928 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6929 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6930 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6931 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6932 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6933 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6934 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6935 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6936 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6937 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6938 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6940 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6941 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6942 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6943 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6944 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6945 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6946 {
6947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6948 /* .name = "Capture Source", */
6949 .name = "Input Source",
6950 .count = 2,
6951 .info = alc883_mux_enum_info,
6952 .get = alc883_mux_enum_get,
6953 .put = alc883_mux_enum_put,
6954 },
6955 { } /* end */
f12ab1e0 6956};
ccc656ce
KY
6957
6958static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6961 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6962 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6963 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6965 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 6966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
6967 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6968 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6969 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
6970 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6971 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6972 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6973 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6974 {
6975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6976 /* .name = "Capture Source", */
6977 .name = "Input Source",
6978 .count = 2,
6979 .info = alc883_mux_enum_info,
6980 .get = alc883_mux_enum_get,
6981 .put = alc883_mux_enum_put,
6982 },
6983 { } /* end */
f12ab1e0 6984};
ccc656ce 6985
bc9f98a9
KY
6986static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6987 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6988 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
6989 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6990 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
6991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6995 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6996 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6997 {
6998 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6999 /* .name = "Capture Source", */
7000 .name = "Input Source",
7001 .count = 1,
7002 .info = alc883_mux_enum_info,
7003 .get = alc883_mux_enum_get,
7004 .put = alc883_mux_enum_put,
7005 },
7006 { } /* end */
f12ab1e0 7007};
bc9f98a9 7008
272a527c
KY
7009static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7010 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7011 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7012 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7017 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7018 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7019 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7020 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7021 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7022 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7023 {
7024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7025 /* .name = "Capture Source", */
7026 .name = "Input Source",
7027 .count = 2,
7028 .info = alc883_mux_enum_info,
7029 .get = alc883_mux_enum_get,
7030 .put = alc883_mux_enum_put,
7031 },
7032 { } /* end */
7033};
7034
7035static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7038 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7039 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7040 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7041 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7045 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7046 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7047 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7048 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7049 {
7050 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7051 /* .name = "Capture Source", */
7052 .name = "Input Source",
7053 .count = 2,
7054 .info = alc883_mux_enum_info,
7055 .get = alc883_mux_enum_get,
7056 .put = alc883_mux_enum_put,
7057 },
7058 { } /* end */
7059};
7060
2880a867 7061static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7063 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7064 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7068 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7070 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7071 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7072 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7073 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7074 {
7075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7076 /* .name = "Capture Source", */
7077 .name = "Input Source",
7078 .count = 2,
7079 .info = alc883_mux_enum_info,
7080 .get = alc883_mux_enum_get,
7081 .put = alc883_mux_enum_put,
7082 },
7083 { } /* end */
d1a991a6 7084};
2880a867 7085
9c7f852e
TI
7086static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7087 {
7088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7089 .name = "Channel Mode",
7090 .info = alc_ch_mode_info,
7091 .get = alc_ch_mode_get,
7092 .put = alc_ch_mode_put,
7093 },
7094 { } /* end */
7095};
7096
7097static struct hda_verb alc883_init_verbs[] = {
7098 /* ADC1: mute amp left and right */
7099 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7100 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7101 /* ADC2: mute amp left and right */
7102 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7103 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7104 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7108 /* Rear mixer */
7109 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7111 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7112 /* CLFE mixer */
7113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7114 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7116 /* Side mixer */
7117 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7118 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7119 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7120
cb53c626
TI
7121 /* mute analog input loopbacks */
7122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7124 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7125 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7126 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7127
9c7f852e
TI
7128 /* Front Pin: output 0 (0x0c) */
7129 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7130 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7131 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7132 /* Rear Pin: output 1 (0x0d) */
7133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7135 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7136 /* CLFE Pin: output 2 (0x0e) */
7137 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7138 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7140 /* Side Pin: output 3 (0x0f) */
7141 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7142 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7143 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7144 /* Mic (rear) pin: input vref at 80% */
7145 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7146 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7147 /* Front Mic pin: input vref at 80% */
7148 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7149 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7150 /* Line In pin: input */
7151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7153 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7154 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7155 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7156 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7157 /* CD pin widget for input */
7158 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7159
7160 /* FIXME: use matrix-type input source selection */
7161 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7162 /* Input mixer2 */
7163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7164 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7165 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7166 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7167 /* Input mixer3 */
7168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7170 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7171 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7172 { }
7173};
7174
a8848bd6
AS
7175/* toggle speaker-output according to the hp-jack state */
7176static void alc883_mitac_hp_automute(struct hda_codec *codec)
7177{
7178 unsigned int present;
7179
7180 present = snd_hda_codec_read(codec, 0x15, 0,
7181 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7182 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7183 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7184 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7185 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7186}
7187
7188/* auto-toggle front mic */
7189/*
7190static void alc883_mitac_mic_automute(struct hda_codec *codec)
7191{
7192 unsigned int present;
7193 unsigned char bits;
7194
7195 present = snd_hda_codec_read(codec, 0x18, 0,
7196 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7197 bits = present ? HDA_AMP_MUTE : 0;
7198 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7199}
7200*/
7201
7202static void alc883_mitac_automute(struct hda_codec *codec)
7203{
7204 alc883_mitac_hp_automute(codec);
7205 /* alc883_mitac_mic_automute(codec); */
7206}
7207
7208static void alc883_mitac_unsol_event(struct hda_codec *codec,
7209 unsigned int res)
7210{
7211 switch (res >> 26) {
7212 case ALC880_HP_EVENT:
7213 alc883_mitac_hp_automute(codec);
7214 break;
7215 case ALC880_MIC_EVENT:
7216 /* alc883_mitac_mic_automute(codec); */
7217 break;
7218 }
7219}
7220
7221static struct hda_verb alc883_mitac_verbs[] = {
7222 /* HP */
7223 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7225 /* Subwoofer */
7226 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7227 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7228
7229 /* enable unsolicited event */
7230 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7231 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7232
7233 { } /* end */
7234};
7235
0c4cc443 7236static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
7237 /* HP */
7238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7240 /* Int speaker */
7241 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7243
7244 /* enable unsolicited event */
7245 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 7246 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
7247
7248 { } /* end */
7249};
7250
fb97dc67
J
7251static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7252 /* HP */
7253 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7255 /* Subwoofer */
7256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7258
7259 /* enable unsolicited event */
7260 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7261
7262 { } /* end */
7263};
7264
ccc656ce
KY
7265static struct hda_verb alc883_tagra_verbs[] = {
7266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7267 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7268
7269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7271
7272 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7273 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7274 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7275
7276 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7277 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7278 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7279 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7280
7281 { } /* end */
7282};
7283
bc9f98a9
KY
7284static struct hda_verb alc883_lenovo_101e_verbs[] = {
7285 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7286 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7287 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7288 { } /* end */
7289};
7290
272a527c
KY
7291static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7292 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7294 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7296 { } /* end */
7297};
7298
7299static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7302 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7303 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7304 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7305 { } /* end */
7306};
7307
189609ae
KY
7308static struct hda_verb alc883_haier_w66_verbs[] = {
7309 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7311
7312 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7313
7314 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7315 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7316 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7317 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7318 { } /* end */
7319};
7320
4723c022 7321static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 7322 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
7323 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7324 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8341de60
CM
7325 { }
7326};
7327
5795b9e6 7328static struct hda_verb alc888_6st_dell_verbs[] = {
5795b9e6
CM
7329 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7330 { }
7331};
7332
4723c022 7333static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7334 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7335 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7336 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7337 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7338 { }
7339};
7340
4723c022 7341static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7342 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7343 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7344 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7345 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7346 { }
7347};
7348
4723c022
CM
7349static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7350 { 2, alc888_3st_hp_2ch_init },
7351 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7352};
7353
272a527c
KY
7354/* toggle front-jack and RCA according to the hp-jack state */
7355static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7356{
7357 unsigned int present;
7358
7359 present = snd_hda_codec_read(codec, 0x1b, 0,
7360 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7361 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7362 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7363 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7364 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7365}
7366
7367/* toggle RCA according to the front-jack state */
7368static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7369{
7370 unsigned int present;
7371
7372 present = snd_hda_codec_read(codec, 0x14, 0,
7373 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7374 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7375 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7376}
47fd830a 7377
272a527c
KY
7378static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7379 unsigned int res)
7380{
7381 if ((res >> 26) == ALC880_HP_EVENT)
7382 alc888_lenovo_ms7195_front_automute(codec);
7383 if ((res >> 26) == ALC880_FRONT_EVENT)
7384 alc888_lenovo_ms7195_rca_automute(codec);
7385}
7386
7387static struct hda_verb alc883_medion_md2_verbs[] = {
7388 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7389 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7390
7391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7392
7393 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7394 { } /* end */
7395};
7396
7397/* toggle speaker-output according to the hp-jack state */
7398static void alc883_medion_md2_automute(struct hda_codec *codec)
7399{
7400 unsigned int present;
7401
7402 present = snd_hda_codec_read(codec, 0x14, 0,
7403 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7404 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7405 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7406}
7407
7408static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7409 unsigned int res)
7410{
7411 if ((res >> 26) == ALC880_HP_EVENT)
7412 alc883_medion_md2_automute(codec);
7413}
7414
ccc656ce
KY
7415/* toggle speaker-output according to the hp-jack state */
7416static void alc883_tagra_automute(struct hda_codec *codec)
7417{
7418 unsigned int present;
f12ab1e0 7419 unsigned char bits;
ccc656ce
KY
7420
7421 present = snd_hda_codec_read(codec, 0x14, 0,
7422 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7423 bits = present ? HDA_AMP_MUTE : 0;
7424 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7425 HDA_AMP_MUTE, bits);
82beb8fd
TI
7426 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7427 present ? 1 : 3);
ccc656ce
KY
7428}
7429
7430static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7431{
7432 if ((res >> 26) == ALC880_HP_EVENT)
7433 alc883_tagra_automute(codec);
7434}
7435
368c7a95 7436/* toggle speaker-output according to the hp-jack state */
0c4cc443 7437static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
368c7a95
J
7438{
7439 unsigned int present;
7440 unsigned char bits;
7441
7442 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7443 & AC_PINSENSE_PRESENCE;
7444 bits = present ? HDA_AMP_MUTE : 0;
7445 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7446 HDA_AMP_MUTE, bits);
7447}
7448
0c4cc443
HRK
7449static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7450{
7451 unsigned int present;
7452
7453 present = snd_hda_codec_read(codec, 0x18, 0,
7454 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7455 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7456 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7457}
7458
7459static void alc883_clevo_m720_automute(struct hda_codec *codec)
7460{
7461 alc883_clevo_m720_hp_automute(codec);
7462 alc883_clevo_m720_mic_automute(codec);
7463}
7464
7465static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
7466 unsigned int res)
7467{
0c4cc443
HRK
7468 switch (res >> 26) {
7469 case ALC880_HP_EVENT:
7470 alc883_clevo_m720_hp_automute(codec);
7471 break;
7472 case ALC880_MIC_EVENT:
7473 alc883_clevo_m720_mic_automute(codec);
7474 break;
7475 }
368c7a95
J
7476}
7477
fb97dc67
J
7478/* toggle speaker-output according to the hp-jack state */
7479static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7480{
7481 unsigned int present;
7482 unsigned char bits;
7483
7484 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7485 & AC_PINSENSE_PRESENCE;
7486 bits = present ? HDA_AMP_MUTE : 0;
7487 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7488 HDA_AMP_MUTE, bits);
7489}
7490
7491static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7492 unsigned int res)
7493{
7494 if ((res >> 26) == ALC880_HP_EVENT)
7495 alc883_2ch_fujitsu_pi2515_automute(codec);
7496}
7497
189609ae
KY
7498static void alc883_haier_w66_automute(struct hda_codec *codec)
7499{
7500 unsigned int present;
7501 unsigned char bits;
7502
7503 present = snd_hda_codec_read(codec, 0x1b, 0,
7504 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7505 bits = present ? 0x80 : 0;
7506 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7507 0x80, bits);
7508}
7509
7510static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7511 unsigned int res)
7512{
7513 if ((res >> 26) == ALC880_HP_EVENT)
7514 alc883_haier_w66_automute(codec);
7515}
7516
bc9f98a9
KY
7517static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7518{
7519 unsigned int present;
f12ab1e0 7520 unsigned char bits;
bc9f98a9
KY
7521
7522 present = snd_hda_codec_read(codec, 0x14, 0,
7523 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7524 bits = present ? HDA_AMP_MUTE : 0;
7525 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7526 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7527}
7528
7529static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7530{
7531 unsigned int present;
f12ab1e0 7532 unsigned char bits;
bc9f98a9
KY
7533
7534 present = snd_hda_codec_read(codec, 0x1b, 0,
7535 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7536 bits = present ? HDA_AMP_MUTE : 0;
7537 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7538 HDA_AMP_MUTE, bits);
7539 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7540 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7541}
7542
7543static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7544 unsigned int res)
7545{
7546 if ((res >> 26) == ALC880_HP_EVENT)
7547 alc883_lenovo_101e_all_automute(codec);
7548 if ((res >> 26) == ALC880_FRONT_EVENT)
7549 alc883_lenovo_101e_ispeaker_automute(codec);
7550}
7551
676a9b53
TI
7552/* toggle speaker-output according to the hp-jack state */
7553static void alc883_acer_aspire_automute(struct hda_codec *codec)
7554{
7555 unsigned int present;
7556
7557 present = snd_hda_codec_read(codec, 0x14, 0,
7558 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7559 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7560 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7561 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7562 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7563}
7564
7565static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7566 unsigned int res)
7567{
7568 if ((res >> 26) == ALC880_HP_EVENT)
7569 alc883_acer_aspire_automute(codec);
7570}
7571
d1a991a6
KY
7572static struct hda_verb alc883_acer_eapd_verbs[] = {
7573 /* HP Pin: output 0 (0x0c) */
7574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7576 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7577 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7578 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7579 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7580 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7581 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7582 /* eanable EAPD on medion laptop */
7583 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7584 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7585 /* enable unsolicited event */
7586 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7587 { }
7588};
7589
5795b9e6
CM
7590static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7591{
7592 unsigned int present;
7593
7594 present = snd_hda_codec_read(codec, 0x1b, 0,
7595 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7596 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7597 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7598 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7599 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7600 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7601 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7602 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7603 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7604}
7605
7606static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7607 unsigned int res)
7608{
7609 switch (res >> 26) {
7610 case ALC880_HP_EVENT:
7611 printk("hp_event\n");
7612 alc888_6st_dell_front_automute(codec);
7613 break;
7614 }
7615}
7616
9c7f852e
TI
7617/*
7618 * generic initialization of ADC, input mixers and output mixers
7619 */
7620static struct hda_verb alc883_auto_init_verbs[] = {
7621 /*
7622 * Unmute ADC0-2 and set the default input to mic-in
7623 */
7624 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7626 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7628
cb53c626 7629 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7630 * mixer widget
f12ab1e0
TI
7631 * Note: PASD motherboards uses the Line In 2 as the input for
7632 * front panel mic (mic 2)
9c7f852e
TI
7633 */
7634 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7637 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7638 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7640
7641 /*
7642 * Set up output mixers (0x0c - 0x0f)
7643 */
7644 /* set vol=0 to output mixers */
7645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7647 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7649 /* set up input amps for analog loopback */
7650 /* Amp Indices: DAC = 0, mixer = 1 */
7651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7653 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7654 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7656 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7657 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7658 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7659 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7660 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7661
7662 /* FIXME: use matrix-type input source selection */
7663 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7664 /* Input mixer1 */
7665 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7667 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7668 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7670 /* Input mixer2 */
7671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7674 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7676
7677 { }
7678};
7679
7680/* capture mixer elements */
7681static struct snd_kcontrol_new alc883_capture_mixer[] = {
7682 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7683 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7684 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7685 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7686 {
7687 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7688 /* The multiple "Capture Source" controls confuse alsamixer
7689 * So call somewhat different..
9c7f852e
TI
7690 */
7691 /* .name = "Capture Source", */
7692 .name = "Input Source",
7693 .count = 2,
7694 .info = alc882_mux_enum_info,
7695 .get = alc882_mux_enum_get,
7696 .put = alc882_mux_enum_put,
7697 },
7698 { } /* end */
7699};
7700
cb53c626
TI
7701#ifdef CONFIG_SND_HDA_POWER_SAVE
7702#define alc883_loopbacks alc880_loopbacks
7703#endif
7704
9c7f852e
TI
7705/* pcm configuration: identiacal with ALC880 */
7706#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7707#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 7708#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
7709#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7710#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7711
7712/*
7713 * configuration and preset
7714 */
f5fcc13c
TI
7715static const char *alc883_models[ALC883_MODEL_LAST] = {
7716 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7717 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7718 [ALC883_3ST_6ch] = "3stack-6ch",
7719 [ALC883_6ST_DIG] = "6stack-dig",
7720 [ALC883_TARGA_DIG] = "targa-dig",
7721 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7722 [ALC883_ACER] = "acer",
2880a867 7723 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7724 [ALC883_MEDION] = "medion",
272a527c 7725 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7726 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7727 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7728 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7729 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7730 [ALC883_HAIER_W66] = "haier-w66",
4723c022 7731 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 7732 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 7733 [ALC883_MITAC] = "mitac",
0c4cc443 7734 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 7735 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
f5fcc13c
TI
7736 [ALC883_AUTO] = "auto",
7737};
7738
7739static struct snd_pci_quirk alc883_cfg_tbl[] = {
7740 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7741 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7742 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7743 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7744 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 7745 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 7746 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7747 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7748 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 7749 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
ac3e3741 7750 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
97ec710c 7751 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 7752 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7753 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7754 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7755 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7756 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7757 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7758 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7759 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 7760 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7761 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 7762 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 7763 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7764 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7765 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7766 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7767 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7768 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7769 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7770 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7771 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7772 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7773 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7774 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
86d34b7e 7775 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7776 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7777 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7778 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7779 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
7780 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
7781 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
ac3e3741 7782 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7783 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7784 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
fb97dc67 7785 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
272a527c 7786 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7787 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7788 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7789 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7790 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 7791 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 7792 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7793 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7794 {}
7795};
7796
7797static struct alc_config_preset alc883_presets[] = {
7798 [ALC883_3ST_2ch_DIG] = {
7799 .mixers = { alc883_3ST_2ch_mixer },
7800 .init_verbs = { alc883_init_verbs },
7801 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7802 .dac_nids = alc883_dac_nids,
7803 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7804 .dig_in_nid = ALC883_DIGIN_NID,
7805 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7806 .channel_mode = alc883_3ST_2ch_modes,
7807 .input_mux = &alc883_capture_source,
7808 },
7809 [ALC883_3ST_6ch_DIG] = {
7810 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7811 .init_verbs = { alc883_init_verbs },
7812 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7813 .dac_nids = alc883_dac_nids,
7814 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7815 .dig_in_nid = ALC883_DIGIN_NID,
7816 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7817 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7818 .need_dac_fix = 1,
9c7f852e 7819 .input_mux = &alc883_capture_source,
f12ab1e0 7820 },
9c7f852e
TI
7821 [ALC883_3ST_6ch] = {
7822 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7823 .init_verbs = { alc883_init_verbs },
7824 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7825 .dac_nids = alc883_dac_nids,
9c7f852e
TI
7826 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7827 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7828 .need_dac_fix = 1,
9c7f852e 7829 .input_mux = &alc883_capture_source,
f12ab1e0 7830 },
9c7f852e
TI
7831 [ALC883_6ST_DIG] = {
7832 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7833 .init_verbs = { alc883_init_verbs },
7834 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7835 .dac_nids = alc883_dac_nids,
7836 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7837 .dig_in_nid = ALC883_DIGIN_NID,
7838 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7839 .channel_mode = alc883_sixstack_modes,
7840 .input_mux = &alc883_capture_source,
7841 },
ccc656ce
KY
7842 [ALC883_TARGA_DIG] = {
7843 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7844 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7845 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7846 .dac_nids = alc883_dac_nids,
7847 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7848 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7849 .channel_mode = alc883_3ST_6ch_modes,
7850 .need_dac_fix = 1,
7851 .input_mux = &alc883_capture_source,
7852 .unsol_event = alc883_tagra_unsol_event,
7853 .init_hook = alc883_tagra_automute,
7854 },
7855 [ALC883_TARGA_2ch_DIG] = {
7856 .mixers = { alc883_tagra_2ch_mixer},
7857 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7859 .dac_nids = alc883_dac_nids,
7860 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7862 .channel_mode = alc883_3ST_2ch_modes,
7863 .input_mux = &alc883_capture_source,
7864 .unsol_event = alc883_tagra_unsol_event,
7865 .init_hook = alc883_tagra_automute,
7866 },
bab282b9 7867 [ALC883_ACER] = {
676a9b53 7868 .mixers = { alc883_base_mixer },
bab282b9
VA
7869 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7870 * and the headphone jack. Turn this on and rely on the
7871 * standard mute methods whenever the user wants to turn
7872 * these outputs off.
7873 */
7874 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7875 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7876 .dac_nids = alc883_dac_nids,
bab282b9
VA
7877 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7878 .channel_mode = alc883_3ST_2ch_modes,
7879 .input_mux = &alc883_capture_source,
7880 },
2880a867 7881 [ALC883_ACER_ASPIRE] = {
676a9b53 7882 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7883 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7884 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7885 .dac_nids = alc883_dac_nids,
7886 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
7887 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7888 .channel_mode = alc883_3ST_2ch_modes,
7889 .input_mux = &alc883_capture_source,
676a9b53
TI
7890 .unsol_event = alc883_acer_aspire_unsol_event,
7891 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7892 },
c07584c8
TD
7893 [ALC883_MEDION] = {
7894 .mixers = { alc883_fivestack_mixer,
7895 alc883_chmode_mixer },
7896 .init_verbs = { alc883_init_verbs,
b373bdeb 7897 alc883_medion_eapd_verbs },
c07584c8
TD
7898 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7899 .dac_nids = alc883_dac_nids,
c07584c8
TD
7900 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7901 .channel_mode = alc883_sixstack_modes,
7902 .input_mux = &alc883_capture_source,
b373bdeb 7903 },
272a527c
KY
7904 [ALC883_MEDION_MD2] = {
7905 .mixers = { alc883_medion_md2_mixer},
7906 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7907 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7908 .dac_nids = alc883_dac_nids,
7909 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7910 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7911 .channel_mode = alc883_3ST_2ch_modes,
7912 .input_mux = &alc883_capture_source,
7913 .unsol_event = alc883_medion_md2_unsol_event,
7914 .init_hook = alc883_medion_md2_automute,
7915 },
b373bdeb 7916 [ALC883_LAPTOP_EAPD] = {
676a9b53 7917 .mixers = { alc883_base_mixer },
b373bdeb
AN
7918 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7919 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7920 .dac_nids = alc883_dac_nids,
b373bdeb
AN
7921 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7922 .channel_mode = alc883_3ST_2ch_modes,
7923 .input_mux = &alc883_capture_source,
7924 },
0c4cc443
HRK
7925 [ALC883_CLEVO_M720] = {
7926 .mixers = { alc883_clevo_m720_mixer },
7927 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
7928 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7929 .dac_nids = alc883_dac_nids,
7930 .dig_out_nid = ALC883_DIGOUT_NID,
7931 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7932 .channel_mode = alc883_3ST_2ch_modes,
7933 .input_mux = &alc883_capture_source,
0c4cc443
HRK
7934 .unsol_event = alc883_clevo_m720_unsol_event,
7935 .init_hook = alc883_clevo_m720_automute,
368c7a95 7936 },
bc9f98a9
KY
7937 [ALC883_LENOVO_101E_2ch] = {
7938 .mixers = { alc883_lenovo_101e_2ch_mixer},
7939 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7940 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7941 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
7942 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7943 .channel_mode = alc883_3ST_2ch_modes,
7944 .input_mux = &alc883_lenovo_101e_capture_source,
7945 .unsol_event = alc883_lenovo_101e_unsol_event,
7946 .init_hook = alc883_lenovo_101e_all_automute,
7947 },
272a527c
KY
7948 [ALC883_LENOVO_NB0763] = {
7949 .mixers = { alc883_lenovo_nb0763_mixer },
7950 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7951 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7952 .dac_nids = alc883_dac_nids,
272a527c
KY
7953 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7954 .channel_mode = alc883_3ST_2ch_modes,
7955 .need_dac_fix = 1,
7956 .input_mux = &alc883_lenovo_nb0763_capture_source,
7957 .unsol_event = alc883_medion_md2_unsol_event,
7958 .init_hook = alc883_medion_md2_automute,
7959 },
7960 [ALC888_LENOVO_MS7195_DIG] = {
7961 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7962 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7963 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7964 .dac_nids = alc883_dac_nids,
7965 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7966 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7967 .channel_mode = alc883_3ST_6ch_modes,
7968 .need_dac_fix = 1,
7969 .input_mux = &alc883_capture_source,
7970 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7971 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7972 },
7973 [ALC883_HAIER_W66] = {
7974 .mixers = { alc883_tagra_2ch_mixer},
7975 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7976 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7977 .dac_nids = alc883_dac_nids,
7978 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
7979 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7980 .channel_mode = alc883_3ST_2ch_modes,
7981 .input_mux = &alc883_capture_source,
7982 .unsol_event = alc883_haier_w66_unsol_event,
7983 .init_hook = alc883_haier_w66_automute,
eea6419e 7984 },
4723c022 7985 [ALC888_3ST_HP] = {
eea6419e 7986 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 7987 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7988 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7989 .dac_nids = alc883_dac_nids,
4723c022
CM
7990 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7991 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7992 .need_dac_fix = 1,
7993 .input_mux = &alc883_capture_source,
7994 },
5795b9e6 7995 [ALC888_6ST_DELL] = {
f24dbdc6 7996 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
7997 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7998 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7999 .dac_nids = alc883_dac_nids,
8000 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
8001 .dig_in_nid = ALC883_DIGIN_NID,
8002 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8003 .channel_mode = alc883_sixstack_modes,
8004 .input_mux = &alc883_capture_source,
8005 .unsol_event = alc888_6st_dell_unsol_event,
8006 .init_hook = alc888_6st_dell_front_automute,
8007 },
a8848bd6
AS
8008 [ALC883_MITAC] = {
8009 .mixers = { alc883_mitac_mixer },
8010 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8011 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8012 .dac_nids = alc883_dac_nids,
a8848bd6
AS
8013 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8014 .channel_mode = alc883_3ST_2ch_modes,
8015 .input_mux = &alc883_capture_source,
8016 .unsol_event = alc883_mitac_unsol_event,
8017 .init_hook = alc883_mitac_automute,
8018 },
fb97dc67
J
8019 [ALC883_FUJITSU_PI2515] = {
8020 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8021 .init_verbs = { alc883_init_verbs,
8022 alc883_2ch_fujitsu_pi2515_verbs},
8023 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8024 .dac_nids = alc883_dac_nids,
8025 .dig_out_nid = ALC883_DIGOUT_NID,
8026 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8027 .channel_mode = alc883_3ST_2ch_modes,
8028 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8029 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8030 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8031 },
9c7f852e
TI
8032};
8033
8034
8035/*
8036 * BIOS auto configuration
8037 */
8038static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8039 hda_nid_t nid, int pin_type,
8040 int dac_idx)
8041{
8042 /* set as output */
8043 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
8044 int idx;
8045
f6c7e546 8046 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
8047 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8048 idx = 4;
8049 else
8050 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
8051 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8052
8053}
8054
8055static void alc883_auto_init_multi_out(struct hda_codec *codec)
8056{
8057 struct alc_spec *spec = codec->spec;
8058 int i;
8059
bc9f98a9 8060 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 8061 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 8062 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 8063 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 8064 if (nid)
baba8ee9 8065 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 8066 i);
9c7f852e
TI
8067 }
8068}
8069
8070static void alc883_auto_init_hp_out(struct hda_codec *codec)
8071{
8072 struct alc_spec *spec = codec->spec;
8073 hda_nid_t pin;
8074
eb06ed8f 8075 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
8076 if (pin) /* connect to front */
8077 /* use dac 0 */
8078 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
8079 pin = spec->autocfg.speaker_pins[0];
8080 if (pin)
8081 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
8082}
8083
8084#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8085#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8086
8087static void alc883_auto_init_analog_input(struct hda_codec *codec)
8088{
8089 struct alc_spec *spec = codec->spec;
8090 int i;
8091
8092 for (i = 0; i < AUTO_PIN_LAST; i++) {
8093 hda_nid_t nid = spec->autocfg.input_pins[i];
8094 if (alc883_is_input_pin(nid)) {
8095 snd_hda_codec_write(codec, nid, 0,
8096 AC_VERB_SET_PIN_WIDGET_CONTROL,
8097 (i <= AUTO_PIN_FRONT_MIC ?
8098 PIN_VREF80 : PIN_IN));
8099 if (nid != ALC883_PIN_CD_NID)
8100 snd_hda_codec_write(codec, nid, 0,
8101 AC_VERB_SET_AMP_GAIN_MUTE,
8102 AMP_OUT_MUTE);
8103 }
8104 }
8105}
8106
8107/* almost identical with ALC880 parser... */
8108static int alc883_parse_auto_config(struct hda_codec *codec)
8109{
8110 struct alc_spec *spec = codec->spec;
8111 int err = alc880_parse_auto_config(codec);
8112
8113 if (err < 0)
8114 return err;
776e184e
TI
8115 else if (!err)
8116 return 0; /* no config found */
8117
8118 err = alc_auto_add_mic_boost(codec);
8119 if (err < 0)
8120 return err;
8121
8122 /* hack - override the init verbs */
8123 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
8124 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8125 spec->num_mixers++;
776e184e
TI
8126
8127 return 1; /* config found */
9c7f852e
TI
8128}
8129
8130/* additional initialization for auto-configuration model */
8131static void alc883_auto_init(struct hda_codec *codec)
8132{
f6c7e546 8133 struct alc_spec *spec = codec->spec;
9c7f852e
TI
8134 alc883_auto_init_multi_out(codec);
8135 alc883_auto_init_hp_out(codec);
8136 alc883_auto_init_analog_input(codec);
f6c7e546
TI
8137 if (spec->unsol_event)
8138 alc_sku_automute(codec);
9c7f852e
TI
8139}
8140
8141static int patch_alc883(struct hda_codec *codec)
8142{
8143 struct alc_spec *spec;
8144 int err, board_config;
8145
8146 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8147 if (spec == NULL)
8148 return -ENOMEM;
8149
8150 codec->spec = spec;
8151
f5fcc13c
TI
8152 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8153 alc883_models,
8154 alc883_cfg_tbl);
8155 if (board_config < 0) {
9c7f852e
TI
8156 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8157 "trying auto-probe from BIOS...\n");
8158 board_config = ALC883_AUTO;
8159 }
8160
8161 if (board_config == ALC883_AUTO) {
8162 /* automatic parse from the BIOS config */
8163 err = alc883_parse_auto_config(codec);
8164 if (err < 0) {
8165 alc_free(codec);
8166 return err;
f12ab1e0 8167 } else if (!err) {
9c7f852e
TI
8168 printk(KERN_INFO
8169 "hda_codec: Cannot set up configuration "
8170 "from BIOS. Using base mode...\n");
8171 board_config = ALC883_3ST_2ch_DIG;
8172 }
8173 }
8174
8175 if (board_config != ALC883_AUTO)
8176 setup_preset(spec, &alc883_presets[board_config]);
8177
8178 spec->stream_name_analog = "ALC883 Analog";
8179 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8180 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8181 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e
TI
8182
8183 spec->stream_name_digital = "ALC883 Digital";
8184 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8185 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8186
e1406348
TI
8187 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8188 spec->adc_nids = alc883_adc_nids;
8189 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8190
2134ea4f
TI
8191 spec->vmaster_nid = 0x0c;
8192
9c7f852e
TI
8193 codec->patch_ops = alc_patch_ops;
8194 if (board_config == ALC883_AUTO)
8195 spec->init_hook = alc883_auto_init;
cb53c626
TI
8196#ifdef CONFIG_SND_HDA_POWER_SAVE
8197 if (!spec->loopback.amplist)
8198 spec->loopback.amplist = alc883_loopbacks;
8199#endif
9c7f852e
TI
8200
8201 return 0;
8202}
8203
8204/*
8205 * ALC262 support
8206 */
8207
8208#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8209#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8210
8211#define alc262_dac_nids alc260_dac_nids
8212#define alc262_adc_nids alc882_adc_nids
8213#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
8214#define alc262_capsrc_nids alc882_capsrc_nids
8215#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
8216
8217#define alc262_modes alc260_modes
8218#define alc262_capture_source alc882_capture_source
8219
8220static struct snd_kcontrol_new alc262_base_mixer[] = {
8221 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8222 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8223 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8224 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8225 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8226 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8227 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8228 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8229 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8230 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8231 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8232 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8233 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8234 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
8235 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8237 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8238 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8239 { } /* end */
8240};
8241
ccc656ce
KY
8242static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8244 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8251 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
8252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8254 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 8255 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8256 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
8257 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8259 { } /* end */
8260};
8261
ce875f07
TI
8262/* update HP, line and mono-out pins according to the master switch */
8263static void alc262_hp_master_update(struct hda_codec *codec)
8264{
8265 struct alc_spec *spec = codec->spec;
8266 int val = spec->master_sw;
8267
8268 /* HP & line-out */
8269 snd_hda_codec_write_cache(codec, 0x1b, 0,
8270 AC_VERB_SET_PIN_WIDGET_CONTROL,
8271 val ? PIN_HP : 0);
8272 snd_hda_codec_write_cache(codec, 0x15, 0,
8273 AC_VERB_SET_PIN_WIDGET_CONTROL,
8274 val ? PIN_HP : 0);
8275 /* mono (speaker) depending on the HP jack sense */
8276 val = val && !spec->jack_present;
8277 snd_hda_codec_write_cache(codec, 0x16, 0,
8278 AC_VERB_SET_PIN_WIDGET_CONTROL,
8279 val ? PIN_OUT : 0);
8280}
8281
8282static void alc262_hp_bpc_automute(struct hda_codec *codec)
8283{
8284 struct alc_spec *spec = codec->spec;
8285 unsigned int presence;
8286 presence = snd_hda_codec_read(codec, 0x1b, 0,
8287 AC_VERB_GET_PIN_SENSE, 0);
8288 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8289 alc262_hp_master_update(codec);
8290}
8291
8292static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8293{
8294 if ((res >> 26) != ALC880_HP_EVENT)
8295 return;
8296 alc262_hp_bpc_automute(codec);
8297}
8298
8299static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8300{
8301 struct alc_spec *spec = codec->spec;
8302 unsigned int presence;
8303 presence = snd_hda_codec_read(codec, 0x15, 0,
8304 AC_VERB_GET_PIN_SENSE, 0);
8305 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8306 alc262_hp_master_update(codec);
8307}
8308
8309static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8310 unsigned int res)
8311{
8312 if ((res >> 26) != ALC880_HP_EVENT)
8313 return;
8314 alc262_hp_wildwest_automute(codec);
8315}
8316
8317static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8318 struct snd_ctl_elem_value *ucontrol)
8319{
8320 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8321 struct alc_spec *spec = codec->spec;
8322 *ucontrol->value.integer.value = spec->master_sw;
8323 return 0;
8324}
8325
8326static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8327 struct snd_ctl_elem_value *ucontrol)
8328{
8329 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8330 struct alc_spec *spec = codec->spec;
8331 int val = !!*ucontrol->value.integer.value;
8332
8333 if (val == spec->master_sw)
8334 return 0;
8335 spec->master_sw = val;
8336 alc262_hp_master_update(codec);
8337 return 1;
8338}
8339
9c7f852e 8340static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
8341 {
8342 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8343 .name = "Master Playback Switch",
8344 .info = snd_ctl_boolean_mono_info,
8345 .get = alc262_hp_master_sw_get,
8346 .put = alc262_hp_master_sw_put,
8347 },
9c7f852e
TI
8348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8349 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
8351 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8352 HDA_OUTPUT),
8353 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8354 HDA_OUTPUT),
9c7f852e
TI
8355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8356 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8357 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8358 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8359 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8360 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
8361 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8362 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8363 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8364 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8365 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8366 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8367 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8368 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8369 { } /* end */
8370};
8371
cd7509a4 8372static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
8373 {
8374 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8375 .name = "Master Playback Switch",
8376 .info = snd_ctl_boolean_mono_info,
8377 .get = alc262_hp_master_sw_get,
8378 .put = alc262_hp_master_sw_put,
8379 },
cd7509a4
KY
8380 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8381 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8382 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8383 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
8384 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8385 HDA_OUTPUT),
8386 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8387 HDA_OUTPUT),
cd7509a4
KY
8388 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8389 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 8390 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
8391 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8392 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8393 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8394 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8395 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8396 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8397 { } /* end */
8398};
8399
8400static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8401 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8402 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8403 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
8404 { } /* end */
8405};
8406
66d2a9d6
KY
8407/* mute/unmute internal speaker according to the hp jack and mute state */
8408static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8409{
8410 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
8411
8412 if (force || !spec->sense_updated) {
8413 unsigned int present;
8414 present = snd_hda_codec_read(codec, 0x15, 0,
8415 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 8416 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
8417 spec->sense_updated = 1;
8418 }
4bb26130
TI
8419 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8420 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
8421}
8422
8423static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8424 unsigned int res)
8425{
8426 if ((res >> 26) != ALC880_HP_EVENT)
8427 return;
8428 alc262_hp_t5735_automute(codec, 1);
8429}
8430
8431static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8432{
8433 alc262_hp_t5735_automute(codec, 1);
8434}
8435
8436static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
8437 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8438 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
8439 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8443 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8444 { } /* end */
8445};
8446
8447static struct hda_verb alc262_hp_t5735_verbs[] = {
8448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8449 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8450
8451 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8452 { }
8453};
8454
8c427226 8455static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
8456 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
8458 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8459 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
8460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8462 { } /* end */
8463};
8464
8465static struct hda_verb alc262_hp_rp5700_verbs[] = {
8466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8467 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8468 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8469 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8470 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8471 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8473 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8475 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8476 {}
8477};
8478
8479static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8480 .num_items = 1,
8481 .items = {
8482 { "Line", 0x1 },
8483 },
8484};
8485
0724ea2a
TI
8486/* bind hp and internal speaker mute (with plug check) */
8487static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8488 struct snd_ctl_elem_value *ucontrol)
8489{
8490 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8491 long *valp = ucontrol->value.integer.value;
8492 int change;
8493
8494 /* change hp mute */
8495 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8496 HDA_AMP_MUTE,
8497 valp[0] ? 0 : HDA_AMP_MUTE);
8498 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8499 HDA_AMP_MUTE,
8500 valp[1] ? 0 : HDA_AMP_MUTE);
8501 if (change) {
8502 /* change speaker according to HP jack state */
8503 struct alc_spec *spec = codec->spec;
8504 unsigned int mute;
8505 if (spec->jack_present)
8506 mute = HDA_AMP_MUTE;
8507 else
8508 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8509 HDA_OUTPUT, 0);
8510 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8511 HDA_AMP_MUTE, mute);
8512 }
8513 return change;
8514}
5b31954e 8515
272a527c 8516static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
8517 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8518 {
8519 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8520 .name = "Master Playback Switch",
8521 .info = snd_hda_mixer_amp_switch_info,
8522 .get = snd_hda_mixer_amp_switch_get,
8523 .put = alc262_sony_master_sw_put,
8524 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8525 },
272a527c
KY
8526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8528 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8529 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8530 { } /* end */
8531};
8532
83c34218
KY
8533static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8534 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8535 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8539 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8540 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8541 { } /* end */
8542};
272a527c 8543
9c7f852e
TI
8544#define alc262_capture_mixer alc882_capture_mixer
8545#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8546
8547/*
8548 * generic initialization of ADC, input mixers and output mixers
8549 */
8550static struct hda_verb alc262_init_verbs[] = {
8551 /*
8552 * Unmute ADC0-2 and set the default input to mic-in
8553 */
8554 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8555 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8556 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8558 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8560
cb53c626 8561 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8562 * mixer widget
f12ab1e0
TI
8563 * Note: PASD motherboards uses the Line In 2 as the input for
8564 * front panel mic (mic 2)
9c7f852e
TI
8565 */
8566 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8568 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8569 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8570 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8571 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8572
8573 /*
df694daa
KY
8574 * Set up output mixers (0x0c - 0x0e)
8575 */
8576 /* set vol=0 to output mixers */
8577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8579 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8580 /* set up input amps for analog loopback */
8581 /* Amp Indices: DAC = 0, mixer = 1 */
8582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8585 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8587 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8588
8589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8591 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8593 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8595
8596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8597 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8601
8602 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8603 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8604
8605 /* FIXME: use matrix-type input source selection */
8606 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8612 /* Input mixer2 */
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8617 /* Input mixer3 */
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8622
8623 { }
8624};
1da177e4 8625
ccc656ce
KY
8626static struct hda_verb alc262_hippo_unsol_verbs[] = {
8627 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8628 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8629 {}
8630};
8631
8632static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8634 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8635 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8636
8637 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8638 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8639 {}
8640};
8641
272a527c
KY
8642static struct hda_verb alc262_sony_unsol_verbs[] = {
8643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8646
8647 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 8649 {}
272a527c
KY
8650};
8651
ccc656ce 8652/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8653static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8654{
8655 struct alc_spec *spec = codec->spec;
8656 unsigned int mute;
5b31954e 8657 unsigned int present;
ccc656ce 8658
5b31954e
TI
8659 /* need to execute and sync at first */
8660 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8661 present = snd_hda_codec_read(codec, 0x15, 0,
8662 AC_VERB_GET_PIN_SENSE, 0);
8663 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8664 if (spec->jack_present) {
8665 /* mute internal speaker */
47fd830a
TI
8666 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8667 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8668 } else {
8669 /* unmute internal speaker if necessary */
8670 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8671 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8672 HDA_AMP_MUTE, mute);
ccc656ce
KY
8673 }
8674}
8675
8676/* unsolicited event for HP jack sensing */
8677static void alc262_hippo_unsol_event(struct hda_codec *codec,
8678 unsigned int res)
8679{
8680 if ((res >> 26) != ALC880_HP_EVENT)
8681 return;
5b31954e 8682 alc262_hippo_automute(codec);
ccc656ce
KY
8683}
8684
5b31954e 8685static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8686{
ccc656ce 8687 unsigned int mute;
5b31954e 8688 unsigned int present;
ccc656ce 8689
5b31954e
TI
8690 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8691 present = snd_hda_codec_read(codec, 0x1b, 0,
8692 AC_VERB_GET_PIN_SENSE, 0);
8693 present = (present & 0x80000000) != 0;
8694 if (present) {
ccc656ce 8695 /* mute internal speaker */
47fd830a
TI
8696 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8697 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8698 } else {
8699 /* unmute internal speaker if necessary */
8700 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8701 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8702 HDA_AMP_MUTE, mute);
ccc656ce
KY
8703 }
8704}
8705
8706/* unsolicited event for HP jack sensing */
8707static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8708 unsigned int res)
8709{
8710 if ((res >> 26) != ALC880_HP_EVENT)
8711 return;
5b31954e 8712 alc262_hippo1_automute(codec);
ccc656ce
KY
8713}
8714
834be88d
TI
8715/*
8716 * fujitsu model
5d9fab2d
TV
8717 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
8718 * 0x1b = port replicator headphone out
834be88d
TI
8719 */
8720
8721#define ALC_HP_EVENT 0x37
8722
8723static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8724 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
8726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
8728 {}
8729};
8730
0e31daf7
J
8731static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
8732 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8734 {}
8735};
8736
834be88d 8737static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8738 .num_items = 3,
834be88d
TI
8739 .items = {
8740 { "Mic", 0x0 },
39d3ed38 8741 { "Int Mic", 0x1 },
834be88d
TI
8742 { "CD", 0x4 },
8743 },
8744};
8745
9c7f852e
TI
8746static struct hda_input_mux alc262_HP_capture_source = {
8747 .num_items = 5,
8748 .items = {
8749 { "Mic", 0x0 },
accbe498 8750 { "Front Mic", 0x1 },
9c7f852e
TI
8751 { "Line", 0x2 },
8752 { "CD", 0x4 },
8753 { "AUX IN", 0x6 },
8754 },
8755};
8756
accbe498 8757static struct hda_input_mux alc262_HP_D7000_capture_source = {
8758 .num_items = 4,
8759 .items = {
8760 { "Mic", 0x0 },
8761 { "Front Mic", 0x2 },
8762 { "Line", 0x1 },
8763 { "CD", 0x4 },
8764 },
8765};
8766
ebc7a406 8767/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
8768static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8769{
8770 struct alc_spec *spec = codec->spec;
8771 unsigned int mute;
8772
f12ab1e0 8773 if (force || !spec->sense_updated) {
ebc7a406 8774 unsigned int present;
834be88d
TI
8775 /* need to execute and sync at first */
8776 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
8777 /* check laptop HP jack */
8778 present = snd_hda_codec_read(codec, 0x14, 0,
8779 AC_VERB_GET_PIN_SENSE, 0);
8780 /* need to execute and sync at first */
8781 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8782 /* check docking HP jack */
8783 present |= snd_hda_codec_read(codec, 0x1b, 0,
8784 AC_VERB_GET_PIN_SENSE, 0);
8785 if (present & AC_PINSENSE_PRESENCE)
8786 spec->jack_present = 1;
8787 else
8788 spec->jack_present = 0;
834be88d
TI
8789 spec->sense_updated = 1;
8790 }
ebc7a406
TI
8791 /* unmute internal speaker only if both HPs are unplugged and
8792 * master switch is on
8793 */
8794 if (spec->jack_present)
8795 mute = HDA_AMP_MUTE;
8796 else
834be88d 8797 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
8798 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8799 HDA_AMP_MUTE, mute);
834be88d
TI
8800}
8801
8802/* unsolicited event for HP jack sensing */
8803static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8804 unsigned int res)
8805{
8806 if ((res >> 26) != ALC_HP_EVENT)
8807 return;
8808 alc262_fujitsu_automute(codec, 1);
8809}
8810
ebc7a406
TI
8811static void alc262_fujitsu_init_hook(struct hda_codec *codec)
8812{
8813 alc262_fujitsu_automute(codec, 1);
8814}
8815
834be88d 8816/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8817static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8818 .ops = &snd_hda_bind_vol,
8819 .values = {
8820 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8821 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8822 0
8823 },
8824};
834be88d 8825
0e31daf7
J
8826/* mute/unmute internal speaker according to the hp jack and mute state */
8827static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
8828{
8829 struct alc_spec *spec = codec->spec;
8830 unsigned int mute;
8831
8832 if (force || !spec->sense_updated) {
8833 unsigned int present_int_hp;
8834 /* need to execute and sync at first */
8835 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8836 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
8837 AC_VERB_GET_PIN_SENSE, 0);
8838 spec->jack_present = (present_int_hp & 0x80000000) != 0;
8839 spec->sense_updated = 1;
8840 }
8841 if (spec->jack_present) {
8842 /* mute internal speaker */
8843 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8844 HDA_AMP_MUTE, HDA_AMP_MUTE);
8845 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8846 HDA_AMP_MUTE, HDA_AMP_MUTE);
8847 } else {
8848 /* unmute internal speaker if necessary */
8849 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8850 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8851 HDA_AMP_MUTE, mute);
8852 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8853 HDA_AMP_MUTE, mute);
8854 }
8855}
8856
8857/* unsolicited event for HP jack sensing */
8858static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
8859 unsigned int res)
8860{
8861 if ((res >> 26) != ALC_HP_EVENT)
8862 return;
8863 alc262_lenovo_3000_automute(codec, 1);
8864}
8865
834be88d
TI
8866/* bind hp and internal speaker mute (with plug check) */
8867static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8868 struct snd_ctl_elem_value *ucontrol)
8869{
8870 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8871 long *valp = ucontrol->value.integer.value;
8872 int change;
8873
5d9fab2d
TV
8874 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8875 HDA_AMP_MUTE,
8876 valp ? 0 : HDA_AMP_MUTE);
8877 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8878 HDA_AMP_MUTE,
8879 valp ? 0 : HDA_AMP_MUTE);
8880
82beb8fd
TI
8881 if (change)
8882 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8883 return change;
8884}
8885
8886static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8887 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8888 {
8889 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8890 .name = "Master Playback Switch",
8891 .info = snd_hda_mixer_amp_switch_info,
8892 .get = snd_hda_mixer_amp_switch_get,
8893 .put = alc262_fujitsu_master_sw_put,
8894 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8895 },
8896 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8897 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
06a9c30c
TV
8898 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
8899 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
834be88d
TI
8900 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8903 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8905 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8906 { } /* end */
8907};
8908
0e31daf7
J
8909/* bind hp and internal speaker mute (with plug check) */
8910static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
8911 struct snd_ctl_elem_value *ucontrol)
8912{
8913 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8914 long *valp = ucontrol->value.integer.value;
8915 int change;
8916
8917 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8918 HDA_AMP_MUTE,
8919 valp ? 0 : HDA_AMP_MUTE);
8920
8921 if (change)
8922 alc262_lenovo_3000_automute(codec, 0);
8923 return change;
8924}
8925
8926static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
8927 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8928 {
8929 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8930 .name = "Master Playback Switch",
8931 .info = snd_hda_mixer_amp_switch_info,
8932 .get = snd_hda_mixer_amp_switch_get,
8933 .put = alc262_lenovo_3000_master_sw_put,
8934 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
8935 },
8936 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8937 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8938 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8941 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8942 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8943 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8944 { } /* end */
8945};
8946
304dcaac
TI
8947/* additional init verbs for Benq laptops */
8948static struct hda_verb alc262_EAPD_verbs[] = {
8949 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8950 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8951 {}
8952};
8953
83c34218
KY
8954static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8955 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8956 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8957
8958 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8959 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8960 {}
8961};
8962
f651b50b
TD
8963/* Samsung Q1 Ultra Vista model setup */
8964static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
8965 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8966 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
8967 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8968 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8969 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 8970 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
8971 { } /* end */
8972};
8973
8974static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
8975 /* output mixer */
8976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8979 /* speaker */
8980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8981 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8983 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8984 /* HP */
f651b50b 8985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
8986 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8987 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8989 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8990 /* internal mic */
8991 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8992 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8993 /* ADC, choose mic */
8994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8999 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9000 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9001 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9002 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9003 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
9004 {}
9005};
9006
f651b50b
TD
9007/* mute/unmute internal speaker according to the hp jack and mute state */
9008static void alc262_ultra_automute(struct hda_codec *codec)
9009{
9010 struct alc_spec *spec = codec->spec;
9011 unsigned int mute;
f651b50b 9012
bb9f76cd
TI
9013 mute = 0;
9014 /* auto-mute only when HP is used as HP */
9015 if (!spec->cur_mux[0]) {
9016 unsigned int present;
9017 /* need to execute and sync at first */
9018 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9019 present = snd_hda_codec_read(codec, 0x15, 0,
9020 AC_VERB_GET_PIN_SENSE, 0);
9021 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9022 if (spec->jack_present)
9023 mute = HDA_AMP_MUTE;
f651b50b 9024 }
bb9f76cd
TI
9025 /* mute/unmute internal speaker */
9026 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9027 HDA_AMP_MUTE, mute);
9028 /* mute/unmute HP */
9029 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9030 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
9031}
9032
9033/* unsolicited event for HP jack sensing */
9034static void alc262_ultra_unsol_event(struct hda_codec *codec,
9035 unsigned int res)
9036{
9037 if ((res >> 26) != ALC880_HP_EVENT)
9038 return;
9039 alc262_ultra_automute(codec);
9040}
9041
bb9f76cd
TI
9042static struct hda_input_mux alc262_ultra_capture_source = {
9043 .num_items = 2,
9044 .items = {
9045 { "Mic", 0x1 },
9046 { "Headphone", 0x7 },
9047 },
9048};
9049
9050static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9051 struct snd_ctl_elem_value *ucontrol)
9052{
9053 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9054 struct alc_spec *spec = codec->spec;
9055 int ret;
9056
9057 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9058 if (!ret)
9059 return 0;
9060 /* reprogram the HP pin as mic or HP according to the input source */
9061 snd_hda_codec_write_cache(codec, 0x15, 0,
9062 AC_VERB_SET_PIN_WIDGET_CONTROL,
9063 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9064 alc262_ultra_automute(codec); /* mute/unmute HP */
9065 return ret;
9066}
9067
9068static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9069 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9070 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9071 {
9072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9073 .name = "Capture Source",
9074 .info = alc882_mux_enum_info,
9075 .get = alc882_mux_enum_get,
9076 .put = alc262_ultra_mux_enum_put,
9077 },
9078 { } /* end */
9079};
9080
df694daa 9081/* add playback controls from the parsed DAC table */
f12ab1e0
TI
9082static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9083 const struct auto_pin_cfg *cfg)
df694daa
KY
9084{
9085 hda_nid_t nid;
9086 int err;
9087
9088 spec->multiout.num_dacs = 1; /* only use one dac */
9089 spec->multiout.dac_nids = spec->private_dac_nids;
9090 spec->multiout.dac_nids[0] = 2;
9091
9092 nid = cfg->line_out_pins[0];
9093 if (nid) {
f12ab1e0
TI
9094 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9095 "Front Playback Volume",
9096 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9097 if (err < 0)
df694daa 9098 return err;
f12ab1e0
TI
9099 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9100 "Front Playback Switch",
9101 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9102 if (err < 0)
df694daa
KY
9103 return err;
9104 }
9105
82bc955f 9106 nid = cfg->speaker_pins[0];
df694daa
KY
9107 if (nid) {
9108 if (nid == 0x16) {
f12ab1e0
TI
9109 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9110 "Speaker Playback Volume",
9111 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9112 HDA_OUTPUT));
9113 if (err < 0)
df694daa 9114 return err;
f12ab1e0
TI
9115 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9116 "Speaker Playback Switch",
9117 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9118 HDA_OUTPUT));
9119 if (err < 0)
df694daa
KY
9120 return err;
9121 } else {
f12ab1e0
TI
9122 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9123 "Speaker Playback Switch",
9124 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9125 HDA_OUTPUT));
9126 if (err < 0)
df694daa
KY
9127 return err;
9128 }
9129 }
eb06ed8f 9130 nid = cfg->hp_pins[0];
df694daa
KY
9131 if (nid) {
9132 /* spec->multiout.hp_nid = 2; */
9133 if (nid == 0x16) {
f12ab1e0
TI
9134 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9135 "Headphone Playback Volume",
9136 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9137 HDA_OUTPUT));
9138 if (err < 0)
df694daa 9139 return err;
f12ab1e0
TI
9140 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9141 "Headphone Playback Switch",
9142 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9143 HDA_OUTPUT));
9144 if (err < 0)
df694daa
KY
9145 return err;
9146 } else {
f12ab1e0
TI
9147 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9148 "Headphone Playback Switch",
9149 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9150 HDA_OUTPUT));
9151 if (err < 0)
df694daa
KY
9152 return err;
9153 }
9154 }
f12ab1e0 9155 return 0;
df694daa
KY
9156}
9157
9158/* identical with ALC880 */
f12ab1e0
TI
9159#define alc262_auto_create_analog_input_ctls \
9160 alc880_auto_create_analog_input_ctls
df694daa
KY
9161
9162/*
9163 * generic initialization of ADC, input mixers and output mixers
9164 */
9165static struct hda_verb alc262_volume_init_verbs[] = {
9166 /*
9167 * Unmute ADC0-2 and set the default input to mic-in
9168 */
9169 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9170 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9171 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9173 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9174 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9175
cb53c626 9176 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 9177 * mixer widget
f12ab1e0
TI
9178 * Note: PASD motherboards uses the Line In 2 as the input for
9179 * front panel mic (mic 2)
df694daa
KY
9180 */
9181 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9183 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9184 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9185 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9186 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
9187
9188 /*
9189 * Set up output mixers (0x0c - 0x0f)
9190 */
9191 /* set vol=0 to output mixers */
9192 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9193 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9195
9196 /* set up input amps for analog loopback */
9197 /* Amp Indices: DAC = 0, mixer = 1 */
9198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9202 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9203 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9204
9205 /* FIXME: use matrix-type input source selection */
9206 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9207 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9212 /* Input mixer2 */
9213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9217 /* Input mixer3 */
9218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9222
9223 { }
9224};
9225
9c7f852e
TI
9226static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9227 /*
9228 * Unmute ADC0-2 and set the default input to mic-in
9229 */
9230 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9232 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9234 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9235 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9236
cb53c626 9237 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9238 * mixer widget
f12ab1e0
TI
9239 * Note: PASD motherboards uses the Line In 2 as the input for
9240 * front panel mic (mic 2)
9c7f852e
TI
9241 */
9242 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
9250
9251 /*
9252 * Set up output mixers (0x0c - 0x0e)
9253 */
9254 /* set vol=0 to output mixers */
9255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9258
9259 /* set up input amps for analog loopback */
9260 /* Amp Indices: DAC = 0, mixer = 1 */
9261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9263 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9264 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9265 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9266 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9267
ce875f07 9268 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
9269 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9270 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9271
9272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9273 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9274
9275 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9277
9278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9280 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9282 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9283
9284 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9285 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9286 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9287 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9288 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9289 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9290
9291
9292 /* FIXME: use matrix-type input source selection */
9293 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9294 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9299 /* Input mixer2 */
9300 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9301 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9302 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9304 /* Input mixer3 */
9305 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9307 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9309
ce875f07
TI
9310 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9311
9c7f852e
TI
9312 { }
9313};
9314
cd7509a4
KY
9315static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9316 /*
9317 * Unmute ADC0-2 and set the default input to mic-in
9318 */
9319 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9321 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9322 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9323 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9324 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9325
cb53c626 9326 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
9327 * mixer widget
9328 * Note: PASD motherboards uses the Line In 2 as the input for front
9329 * panel mic (mic 2)
9330 */
9331 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9332 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9333 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9334 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
9340 /*
9341 * Set up output mixers (0x0c - 0x0e)
9342 */
9343 /* set vol=0 to output mixers */
9344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9345 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9346 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9347
9348 /* set up input amps for analog loopback */
9349 /* Amp Indices: DAC = 0, mixer = 1 */
9350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9356
9357
9358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9359 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9360 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9361 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9363 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9364 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9365
9366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9368
9369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9370 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9371
9372 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9374 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9375 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9376 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9377 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9378
9379 /* FIXME: use matrix-type input source selection */
9380 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9381 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9382 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9383 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9387 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9389 /* Input mixer2 */
9390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9393 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9394 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9395 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9396 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9397 /* Input mixer3 */
9398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9399 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9402 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9403 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9404 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9405
ce875f07
TI
9406 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9407
cd7509a4
KY
9408 { }
9409};
9410
cb53c626
TI
9411#ifdef CONFIG_SND_HDA_POWER_SAVE
9412#define alc262_loopbacks alc880_loopbacks
9413#endif
9414
df694daa
KY
9415/* pcm configuration: identiacal with ALC880 */
9416#define alc262_pcm_analog_playback alc880_pcm_analog_playback
9417#define alc262_pcm_analog_capture alc880_pcm_analog_capture
9418#define alc262_pcm_digital_playback alc880_pcm_digital_playback
9419#define alc262_pcm_digital_capture alc880_pcm_digital_capture
9420
9421/*
9422 * BIOS auto configuration
9423 */
9424static int alc262_parse_auto_config(struct hda_codec *codec)
9425{
9426 struct alc_spec *spec = codec->spec;
9427 int err;
9428 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9429
f12ab1e0
TI
9430 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9431 alc262_ignore);
9432 if (err < 0)
df694daa 9433 return err;
f12ab1e0 9434 if (!spec->autocfg.line_outs)
df694daa 9435 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
9436 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9437 if (err < 0)
9438 return err;
9439 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9440 if (err < 0)
df694daa
KY
9441 return err;
9442
9443 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9444
9445 if (spec->autocfg.dig_out_pin)
9446 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9447 if (spec->autocfg.dig_in_pin)
9448 spec->dig_in_nid = ALC262_DIGIN_NID;
9449
9450 if (spec->kctl_alloc)
9451 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9452
9453 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 9454 spec->num_mux_defs = 1;
df694daa
KY
9455 spec->input_mux = &spec->private_imux;
9456
776e184e
TI
9457 err = alc_auto_add_mic_boost(codec);
9458 if (err < 0)
9459 return err;
9460
df694daa
KY
9461 return 1;
9462}
9463
9464#define alc262_auto_init_multi_out alc882_auto_init_multi_out
9465#define alc262_auto_init_hp_out alc882_auto_init_hp_out
9466#define alc262_auto_init_analog_input alc882_auto_init_analog_input
9467
9468
9469/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 9470static void alc262_auto_init(struct hda_codec *codec)
df694daa 9471{
f6c7e546 9472 struct alc_spec *spec = codec->spec;
df694daa
KY
9473 alc262_auto_init_multi_out(codec);
9474 alc262_auto_init_hp_out(codec);
9475 alc262_auto_init_analog_input(codec);
f6c7e546
TI
9476 if (spec->unsol_event)
9477 alc_sku_automute(codec);
df694daa
KY
9478}
9479
9480/*
9481 * configuration and preset
9482 */
f5fcc13c
TI
9483static const char *alc262_models[ALC262_MODEL_LAST] = {
9484 [ALC262_BASIC] = "basic",
9485 [ALC262_HIPPO] = "hippo",
9486 [ALC262_HIPPO_1] = "hippo_1",
9487 [ALC262_FUJITSU] = "fujitsu",
9488 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 9489 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 9490 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 9491 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 9492 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
9493 [ALC262_BENQ_T31] = "benq-t31",
9494 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 9495 [ALC262_ULTRA] = "ultra",
0e31daf7 9496 [ALC262_LENOVO_3000] = "lenovo-3000",
f5fcc13c
TI
9497 [ALC262_AUTO] = "auto",
9498};
9499
9500static struct snd_pci_quirk alc262_cfg_tbl[] = {
9501 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9502 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 9503 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
9504 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9505 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 9506 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 9507 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 9508 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 9509 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 9510 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9511 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9512 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9513 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9514 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9515 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9516 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9517 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
9518 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9519 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9520 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
9521 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9522 ALC262_HP_TC_T5735),
8c427226 9523 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 9524 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 9525 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 9526 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 9527 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
9528 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9529 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 9530 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 9531 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
bb9f76cd 9532 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
0e31daf7 9533 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
9534 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9535 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9536 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
9537 {}
9538};
9539
9540static struct alc_config_preset alc262_presets[] = {
9541 [ALC262_BASIC] = {
9542 .mixers = { alc262_base_mixer },
9543 .init_verbs = { alc262_init_verbs },
9544 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9545 .dac_nids = alc262_dac_nids,
9546 .hp_nid = 0x03,
9547 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9548 .channel_mode = alc262_modes,
a3bcba38 9549 .input_mux = &alc262_capture_source,
df694daa 9550 },
ccc656ce
KY
9551 [ALC262_HIPPO] = {
9552 .mixers = { alc262_base_mixer },
9553 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9554 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9555 .dac_nids = alc262_dac_nids,
9556 .hp_nid = 0x03,
9557 .dig_out_nid = ALC262_DIGOUT_NID,
9558 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9559 .channel_mode = alc262_modes,
9560 .input_mux = &alc262_capture_source,
9561 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9562 .init_hook = alc262_hippo_automute,
ccc656ce
KY
9563 },
9564 [ALC262_HIPPO_1] = {
9565 .mixers = { alc262_hippo1_mixer },
9566 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9567 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9568 .dac_nids = alc262_dac_nids,
9569 .hp_nid = 0x02,
9570 .dig_out_nid = ALC262_DIGOUT_NID,
9571 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9572 .channel_mode = alc262_modes,
9573 .input_mux = &alc262_capture_source,
9574 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 9575 .init_hook = alc262_hippo1_automute,
ccc656ce 9576 },
834be88d
TI
9577 [ALC262_FUJITSU] = {
9578 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
9579 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9580 alc262_fujitsu_unsol_verbs },
834be88d
TI
9581 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9582 .dac_nids = alc262_dac_nids,
9583 .hp_nid = 0x03,
9584 .dig_out_nid = ALC262_DIGOUT_NID,
9585 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9586 .channel_mode = alc262_modes,
9587 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 9588 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 9589 .init_hook = alc262_fujitsu_init_hook,
834be88d 9590 },
9c7f852e
TI
9591 [ALC262_HP_BPC] = {
9592 .mixers = { alc262_HP_BPC_mixer },
9593 .init_verbs = { alc262_HP_BPC_init_verbs },
9594 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9595 .dac_nids = alc262_dac_nids,
9596 .hp_nid = 0x03,
9597 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9598 .channel_mode = alc262_modes,
9599 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
9600 .unsol_event = alc262_hp_bpc_unsol_event,
9601 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 9602 },
cd7509a4
KY
9603 [ALC262_HP_BPC_D7000_WF] = {
9604 .mixers = { alc262_HP_BPC_WildWest_mixer },
9605 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9606 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9607 .dac_nids = alc262_dac_nids,
9608 .hp_nid = 0x03,
9609 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9610 .channel_mode = alc262_modes,
accbe498 9611 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9612 .unsol_event = alc262_hp_wildwest_unsol_event,
9613 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9614 },
cd7509a4
KY
9615 [ALC262_HP_BPC_D7000_WL] = {
9616 .mixers = { alc262_HP_BPC_WildWest_mixer,
9617 alc262_HP_BPC_WildWest_option_mixer },
9618 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9619 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9620 .dac_nids = alc262_dac_nids,
9621 .hp_nid = 0x03,
9622 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9623 .channel_mode = alc262_modes,
accbe498 9624 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9625 .unsol_event = alc262_hp_wildwest_unsol_event,
9626 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9627 },
66d2a9d6
KY
9628 [ALC262_HP_TC_T5735] = {
9629 .mixers = { alc262_hp_t5735_mixer },
9630 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9631 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9632 .dac_nids = alc262_dac_nids,
9633 .hp_nid = 0x03,
9634 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9635 .channel_mode = alc262_modes,
9636 .input_mux = &alc262_capture_source,
9637 .unsol_event = alc262_hp_t5735_unsol_event,
9638 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
9639 },
9640 [ALC262_HP_RP5700] = {
9641 .mixers = { alc262_hp_rp5700_mixer },
9642 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9643 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9644 .dac_nids = alc262_dac_nids,
9645 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9646 .channel_mode = alc262_modes,
9647 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 9648 },
304dcaac
TI
9649 [ALC262_BENQ_ED8] = {
9650 .mixers = { alc262_base_mixer },
9651 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9652 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9653 .dac_nids = alc262_dac_nids,
9654 .hp_nid = 0x03,
9655 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9656 .channel_mode = alc262_modes,
9657 .input_mux = &alc262_capture_source,
f12ab1e0 9658 },
272a527c
KY
9659 [ALC262_SONY_ASSAMD] = {
9660 .mixers = { alc262_sony_mixer },
9661 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9662 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9663 .dac_nids = alc262_dac_nids,
9664 .hp_nid = 0x02,
9665 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9666 .channel_mode = alc262_modes,
9667 .input_mux = &alc262_capture_source,
9668 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9669 .init_hook = alc262_hippo_automute,
83c34218
KY
9670 },
9671 [ALC262_BENQ_T31] = {
9672 .mixers = { alc262_benq_t31_mixer },
9673 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9674 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9675 .dac_nids = alc262_dac_nids,
9676 .hp_nid = 0x03,
9677 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9678 .channel_mode = alc262_modes,
9679 .input_mux = &alc262_capture_source,
9680 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9681 .init_hook = alc262_hippo_automute,
272a527c 9682 },
f651b50b 9683 [ALC262_ULTRA] = {
bb9f76cd
TI
9684 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
9685 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
9686 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9687 .dac_nids = alc262_dac_nids,
f651b50b
TD
9688 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9689 .channel_mode = alc262_modes,
9690 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
9691 .adc_nids = alc262_adc_nids, /* ADC0 */
9692 .capsrc_nids = alc262_capsrc_nids,
9693 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
9694 .unsol_event = alc262_ultra_unsol_event,
9695 .init_hook = alc262_ultra_automute,
9696 },
0e31daf7
J
9697 [ALC262_LENOVO_3000] = {
9698 .mixers = { alc262_lenovo_3000_mixer },
9699 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9700 alc262_lenovo_3000_unsol_verbs },
9701 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9702 .dac_nids = alc262_dac_nids,
9703 .hp_nid = 0x03,
9704 .dig_out_nid = ALC262_DIGOUT_NID,
9705 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9706 .channel_mode = alc262_modes,
9707 .input_mux = &alc262_fujitsu_capture_source,
9708 .unsol_event = alc262_lenovo_3000_unsol_event,
9709 },
df694daa
KY
9710};
9711
9712static int patch_alc262(struct hda_codec *codec)
9713{
9714 struct alc_spec *spec;
9715 int board_config;
9716 int err;
9717
dc041e0b 9718 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
9719 if (spec == NULL)
9720 return -ENOMEM;
9721
9722 codec->spec = spec;
9723#if 0
f12ab1e0
TI
9724 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9725 * under-run
9726 */
df694daa
KY
9727 {
9728 int tmp;
9729 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9730 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9731 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9732 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9733 }
9734#endif
9735
f5fcc13c
TI
9736 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9737 alc262_models,
9738 alc262_cfg_tbl);
cd7509a4 9739
f5fcc13c 9740 if (board_config < 0) {
9c7f852e
TI
9741 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9742 "trying auto-probe from BIOS...\n");
df694daa
KY
9743 board_config = ALC262_AUTO;
9744 }
9745
9746 if (board_config == ALC262_AUTO) {
9747 /* automatic parse from the BIOS config */
9748 err = alc262_parse_auto_config(codec);
9749 if (err < 0) {
9750 alc_free(codec);
9751 return err;
f12ab1e0 9752 } else if (!err) {
9c7f852e
TI
9753 printk(KERN_INFO
9754 "hda_codec: Cannot set up configuration "
9755 "from BIOS. Using base mode...\n");
df694daa
KY
9756 board_config = ALC262_BASIC;
9757 }
9758 }
9759
9760 if (board_config != ALC262_AUTO)
9761 setup_preset(spec, &alc262_presets[board_config]);
9762
9763 spec->stream_name_analog = "ALC262 Analog";
9764 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9765 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9766
9767 spec->stream_name_digital = "ALC262 Digital";
9768 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9769 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9770
f12ab1e0 9771 if (!spec->adc_nids && spec->input_mux) {
df694daa 9772 /* check whether NID 0x07 is valid */
4a471b7d
TI
9773 unsigned int wcap = get_wcaps(codec, 0x07);
9774
f12ab1e0
TI
9775 /* get type */
9776 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9777 if (wcap != AC_WID_AUD_IN) {
9778 spec->adc_nids = alc262_adc_nids_alt;
9779 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 9780 spec->capsrc_nids = alc262_capsrc_nids_alt;
f12ab1e0
TI
9781 spec->mixers[spec->num_mixers] =
9782 alc262_capture_alt_mixer;
df694daa
KY
9783 spec->num_mixers++;
9784 } else {
9785 spec->adc_nids = alc262_adc_nids;
9786 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 9787 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
9788 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9789 spec->num_mixers++;
9790 }
9791 }
9792
2134ea4f
TI
9793 spec->vmaster_nid = 0x0c;
9794
df694daa
KY
9795 codec->patch_ops = alc_patch_ops;
9796 if (board_config == ALC262_AUTO)
ae6b813a 9797 spec->init_hook = alc262_auto_init;
cb53c626
TI
9798#ifdef CONFIG_SND_HDA_POWER_SAVE
9799 if (!spec->loopback.amplist)
9800 spec->loopback.amplist = alc262_loopbacks;
9801#endif
834be88d 9802
df694daa
KY
9803 return 0;
9804}
9805
a361d84b
KY
9806/*
9807 * ALC268 channel source setting (2 channel)
9808 */
9809#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9810#define alc268_modes alc260_modes
9811
9812static hda_nid_t alc268_dac_nids[2] = {
9813 /* front, hp */
9814 0x02, 0x03
9815};
9816
9817static hda_nid_t alc268_adc_nids[2] = {
9818 /* ADC0-1 */
9819 0x08, 0x07
9820};
9821
9822static hda_nid_t alc268_adc_nids_alt[1] = {
9823 /* ADC0 */
9824 0x08
9825};
9826
e1406348
TI
9827static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9828
a361d84b
KY
9829static struct snd_kcontrol_new alc268_base_mixer[] = {
9830 /* output mixer control */
9831 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9832 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9833 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9836 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9837 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9838 { }
9839};
9840
aef9d318
TI
9841/* bind Beep switches of both NID 0x0f and 0x10 */
9842static struct hda_bind_ctls alc268_bind_beep_sw = {
9843 .ops = &snd_hda_bind_sw,
9844 .values = {
9845 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
9846 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
9847 0
9848 },
9849};
9850
9851static struct snd_kcontrol_new alc268_beep_mixer[] = {
9852 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
9853 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
9854 { }
9855};
9856
d1a991a6
KY
9857static struct hda_verb alc268_eapd_verbs[] = {
9858 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9859 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9860 { }
9861};
9862
d273809e
TI
9863/* Toshiba specific */
9864#define alc268_toshiba_automute alc262_hippo_automute
9865
9866static struct hda_verb alc268_toshiba_verbs[] = {
9867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9868 { } /* end */
9869};
9870
9871/* Acer specific */
889c4395 9872/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9873static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9874 .ops = &snd_hda_bind_vol,
9875 .values = {
9876 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9877 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9878 0
9879 },
9880};
9881
889c4395
TI
9882/* mute/unmute internal speaker according to the hp jack and mute state */
9883static void alc268_acer_automute(struct hda_codec *codec, int force)
9884{
9885 struct alc_spec *spec = codec->spec;
9886 unsigned int mute;
9887
9888 if (force || !spec->sense_updated) {
9889 unsigned int present;
9890 present = snd_hda_codec_read(codec, 0x14, 0,
9891 AC_VERB_GET_PIN_SENSE, 0);
9892 spec->jack_present = (present & 0x80000000) != 0;
9893 spec->sense_updated = 1;
9894 }
9895 if (spec->jack_present)
9896 mute = HDA_AMP_MUTE; /* mute internal speaker */
9897 else /* unmute internal speaker if necessary */
9898 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9899 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9900 HDA_AMP_MUTE, mute);
9901}
9902
9903
9904/* bind hp and internal speaker mute (with plug check) */
9905static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9906 struct snd_ctl_elem_value *ucontrol)
9907{
9908 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9909 long *valp = ucontrol->value.integer.value;
9910 int change;
9911
9912 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9913 HDA_AMP_MUTE,
9914 valp[0] ? 0 : HDA_AMP_MUTE);
9915 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9916 HDA_AMP_MUTE,
9917 valp[1] ? 0 : HDA_AMP_MUTE);
9918 if (change)
9919 alc268_acer_automute(codec, 0);
9920 return change;
9921}
d273809e
TI
9922
9923static struct snd_kcontrol_new alc268_acer_mixer[] = {
9924 /* output mixer control */
9925 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9926 {
9927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9928 .name = "Master Playback Switch",
9929 .info = snd_hda_mixer_amp_switch_info,
9930 .get = snd_hda_mixer_amp_switch_get,
9931 .put = alc268_acer_master_sw_put,
9932 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9933 },
33bf17ab
TI
9934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9935 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9936 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9937 { }
9938};
9939
9940static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
9941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
9942 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
9943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9944 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
9945 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9946 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
9947
9948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9949 { }
9950};
9951
9952/* unsolicited event for HP jack sensing */
9953static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9954 unsigned int res)
9955{
889c4395 9956 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9957 return;
9958 alc268_toshiba_automute(codec);
9959}
9960
9961static void alc268_acer_unsol_event(struct hda_codec *codec,
9962 unsigned int res)
9963{
889c4395 9964 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9965 return;
9966 alc268_acer_automute(codec, 1);
9967}
9968
889c4395
TI
9969static void alc268_acer_init_hook(struct hda_codec *codec)
9970{
9971 alc268_acer_automute(codec, 1);
9972}
9973
3866f0b0
TI
9974static struct snd_kcontrol_new alc268_dell_mixer[] = {
9975 /* output mixer control */
9976 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9977 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9978 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9979 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9981 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9982 { }
9983};
9984
9985static struct hda_verb alc268_dell_verbs[] = {
9986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9987 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9988 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9989 { }
9990};
9991
9992/* mute/unmute internal speaker according to the hp jack and mute state */
9993static void alc268_dell_automute(struct hda_codec *codec)
9994{
9995 unsigned int present;
9996 unsigned int mute;
9997
9998 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9999 if (present & 0x80000000)
10000 mute = HDA_AMP_MUTE;
10001 else
10002 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10003 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10004 HDA_AMP_MUTE, mute);
10005}
10006
10007static void alc268_dell_unsol_event(struct hda_codec *codec,
10008 unsigned int res)
10009{
10010 if ((res >> 26) != ALC880_HP_EVENT)
10011 return;
10012 alc268_dell_automute(codec);
10013}
10014
10015#define alc268_dell_init_hook alc268_dell_automute
10016
eb5a6621
HRK
10017static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10018 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10019 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10020 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10021 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10022 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10023 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10024 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10025 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10026 { }
10027};
10028
10029static struct hda_verb alc267_quanta_il1_verbs[] = {
10030 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10031 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10032 { }
10033};
10034
10035static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10036{
10037 unsigned int present;
10038
10039 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10040 & AC_PINSENSE_PRESENCE;
10041 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10042 present ? 0 : PIN_OUT);
10043}
10044
10045static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10046{
10047 unsigned int present;
10048
10049 present = snd_hda_codec_read(codec, 0x18, 0,
10050 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10051 snd_hda_codec_write(codec, 0x23, 0,
10052 AC_VERB_SET_CONNECT_SEL,
10053 present ? 0x00 : 0x01);
10054}
10055
10056static void alc267_quanta_il1_automute(struct hda_codec *codec)
10057{
10058 alc267_quanta_il1_hp_automute(codec);
10059 alc267_quanta_il1_mic_automute(codec);
10060}
10061
10062static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10063 unsigned int res)
10064{
10065 switch (res >> 26) {
10066 case ALC880_HP_EVENT:
10067 alc267_quanta_il1_hp_automute(codec);
10068 break;
10069 case ALC880_MIC_EVENT:
10070 alc267_quanta_il1_mic_automute(codec);
10071 break;
10072 }
10073}
10074
a361d84b
KY
10075/*
10076 * generic initialization of ADC, input mixers and output mixers
10077 */
10078static struct hda_verb alc268_base_init_verbs[] = {
10079 /* Unmute DAC0-1 and set vol = 0 */
10080 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10081 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10082 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10083 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10084 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10085 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10086
10087 /*
10088 * Set up output mixers (0x0c - 0x0e)
10089 */
10090 /* set vol=0 to output mixers */
10091 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10092 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10094 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10095
10096 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10097 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10098
10099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10102 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10103 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10105 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10106 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10107
10108 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10110 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10111 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10112 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10113 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10114 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
10115
10116 /* set PCBEEP vol = 0, mute connections */
10117 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10118 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10119 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 10120
a9b3aa8a
JZ
10121 /* Unmute Selector 23h,24h and set the default input to mic-in */
10122
10123 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10125 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 10127
a361d84b
KY
10128 { }
10129};
10130
10131/*
10132 * generic initialization of ADC, input mixers and output mixers
10133 */
10134static struct hda_verb alc268_volume_init_verbs[] = {
10135 /* set output DAC */
10136 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10137 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10138 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10139 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10140
10141 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10142 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10143 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10144 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10145 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10146
10147 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10148 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10150 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10151 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10152
10153 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10154 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10155 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10156 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10157
aef9d318
TI
10158 /* set PCBEEP vol = 0, mute connections */
10159 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10161 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
10162
10163 { }
10164};
10165
10166#define alc268_mux_enum_info alc_mux_enum_info
10167#define alc268_mux_enum_get alc_mux_enum_get
e1406348 10168#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
10169
10170static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10171 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10172 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10173 {
10174 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10175 /* The multiple "Capture Source" controls confuse alsamixer
10176 * So call somewhat different..
a361d84b
KY
10177 */
10178 /* .name = "Capture Source", */
10179 .name = "Input Source",
10180 .count = 1,
10181 .info = alc268_mux_enum_info,
10182 .get = alc268_mux_enum_get,
10183 .put = alc268_mux_enum_put,
10184 },
10185 { } /* end */
10186};
10187
10188static struct snd_kcontrol_new alc268_capture_mixer[] = {
10189 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10190 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10191 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
10192 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
10193 {
10194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10195 /* The multiple "Capture Source" controls confuse alsamixer
10196 * So call somewhat different..
a361d84b
KY
10197 */
10198 /* .name = "Capture Source", */
10199 .name = "Input Source",
10200 .count = 2,
10201 .info = alc268_mux_enum_info,
10202 .get = alc268_mux_enum_get,
10203 .put = alc268_mux_enum_put,
10204 },
10205 { } /* end */
10206};
10207
10208static struct hda_input_mux alc268_capture_source = {
10209 .num_items = 4,
10210 .items = {
10211 { "Mic", 0x0 },
10212 { "Front Mic", 0x1 },
10213 { "Line", 0x2 },
10214 { "CD", 0x3 },
10215 },
10216};
10217
0ccb541c
TI
10218static struct hda_input_mux alc268_acer_capture_source = {
10219 .num_items = 3,
10220 .items = {
10221 { "Mic", 0x0 },
10222 { "Internal Mic", 0x6 },
10223 { "Line", 0x2 },
10224 },
10225};
10226
86c53bd2
JW
10227#ifdef CONFIG_SND_DEBUG
10228static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
10229 /* Volume widgets */
10230 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10231 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10232 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10233 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
10234 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
10235 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
10236 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
10237 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
10238 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
10239 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
10240 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
10241 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
10242 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
10243 /* The below appears problematic on some hardwares */
10244 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
10245 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10246 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
10247 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
10248 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
10249
10250 /* Modes for retasking pin widgets */
10251 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
10252 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
10253 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
10254 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
10255
10256 /* Controls for GPIO pins, assuming they are configured as outputs */
10257 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
10258 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
10259 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
10260 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
10261
10262 /* Switches to allow the digital SPDIF output pin to be enabled.
10263 * The ALC268 does not have an SPDIF input.
10264 */
10265 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
10266
10267 /* A switch allowing EAPD to be enabled. Some laptops seem to use
10268 * this output to turn on an external amplifier.
10269 */
10270 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
10271 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
10272
10273 { } /* end */
10274};
10275#endif
10276
a361d84b
KY
10277/* create input playback/capture controls for the given pin */
10278static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
10279 const char *ctlname, int idx)
10280{
10281 char name[32];
10282 int err;
10283
10284 sprintf(name, "%s Playback Volume", ctlname);
10285 if (nid == 0x14) {
10286 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10287 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
10288 HDA_OUTPUT));
10289 if (err < 0)
10290 return err;
10291 } else if (nid == 0x15) {
10292 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10293 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
10294 HDA_OUTPUT));
10295 if (err < 0)
10296 return err;
10297 } else
10298 return -1;
10299 sprintf(name, "%s Playback Switch", ctlname);
10300 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10301 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
10302 if (err < 0)
10303 return err;
10304 return 0;
10305}
10306
10307/* add playback controls from the parsed DAC table */
10308static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10309 const struct auto_pin_cfg *cfg)
10310{
10311 hda_nid_t nid;
10312 int err;
10313
10314 spec->multiout.num_dacs = 2; /* only use one dac */
10315 spec->multiout.dac_nids = spec->private_dac_nids;
10316 spec->multiout.dac_nids[0] = 2;
10317 spec->multiout.dac_nids[1] = 3;
10318
10319 nid = cfg->line_out_pins[0];
10320 if (nid)
10321 alc268_new_analog_output(spec, nid, "Front", 0);
10322
10323 nid = cfg->speaker_pins[0];
10324 if (nid == 0x1d) {
10325 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10326 "Speaker Playback Volume",
10327 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10328 if (err < 0)
10329 return err;
10330 }
10331 nid = cfg->hp_pins[0];
10332 if (nid)
10333 alc268_new_analog_output(spec, nid, "Headphone", 0);
10334
10335 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10336 if (nid == 0x16) {
10337 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10338 "Mono Playback Switch",
10339 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10340 if (err < 0)
10341 return err;
10342 }
10343 return 0;
10344}
10345
10346/* create playback/capture controls for input pins */
10347static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10348 const struct auto_pin_cfg *cfg)
10349{
10350 struct hda_input_mux *imux = &spec->private_imux;
10351 int i, idx1;
10352
10353 for (i = 0; i < AUTO_PIN_LAST; i++) {
10354 switch(cfg->input_pins[i]) {
10355 case 0x18:
10356 idx1 = 0; /* Mic 1 */
10357 break;
10358 case 0x19:
10359 idx1 = 1; /* Mic 2 */
10360 break;
10361 case 0x1a:
10362 idx1 = 2; /* Line In */
10363 break;
10364 case 0x1c:
10365 idx1 = 3; /* CD */
10366 break;
7194cae6
TI
10367 case 0x12:
10368 case 0x13:
10369 idx1 = 6; /* digital mics */
10370 break;
a361d84b
KY
10371 default:
10372 continue;
10373 }
10374 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10375 imux->items[imux->num_items].index = idx1;
10376 imux->num_items++;
10377 }
10378 return 0;
10379}
10380
10381static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10382{
10383 struct alc_spec *spec = codec->spec;
10384 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10385 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10386 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10387 unsigned int dac_vol1, dac_vol2;
10388
10389 if (speaker_nid) {
10390 snd_hda_codec_write(codec, speaker_nid, 0,
10391 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10392 snd_hda_codec_write(codec, 0x0f, 0,
10393 AC_VERB_SET_AMP_GAIN_MUTE,
10394 AMP_IN_UNMUTE(1));
10395 snd_hda_codec_write(codec, 0x10, 0,
10396 AC_VERB_SET_AMP_GAIN_MUTE,
10397 AMP_IN_UNMUTE(1));
10398 } else {
10399 snd_hda_codec_write(codec, 0x0f, 0,
10400 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10401 snd_hda_codec_write(codec, 0x10, 0,
10402 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10403 }
10404
10405 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10406 if (line_nid == 0x14)
10407 dac_vol2 = AMP_OUT_ZERO;
10408 else if (line_nid == 0x15)
10409 dac_vol1 = AMP_OUT_ZERO;
10410 if (hp_nid == 0x14)
10411 dac_vol2 = AMP_OUT_ZERO;
10412 else if (hp_nid == 0x15)
10413 dac_vol1 = AMP_OUT_ZERO;
10414 if (line_nid != 0x16 || hp_nid != 0x16 ||
10415 spec->autocfg.line_out_pins[1] != 0x16 ||
10416 spec->autocfg.line_out_pins[2] != 0x16)
10417 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10418
10419 snd_hda_codec_write(codec, 0x02, 0,
10420 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10421 snd_hda_codec_write(codec, 0x03, 0,
10422 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10423}
10424
10425/* pcm configuration: identiacal with ALC880 */
10426#define alc268_pcm_analog_playback alc880_pcm_analog_playback
10427#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 10428#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
10429#define alc268_pcm_digital_playback alc880_pcm_digital_playback
10430
10431/*
10432 * BIOS auto configuration
10433 */
10434static int alc268_parse_auto_config(struct hda_codec *codec)
10435{
10436 struct alc_spec *spec = codec->spec;
10437 int err;
10438 static hda_nid_t alc268_ignore[] = { 0 };
10439
10440 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10441 alc268_ignore);
10442 if (err < 0)
10443 return err;
10444 if (!spec->autocfg.line_outs)
10445 return 0; /* can't find valid BIOS pin config */
10446
10447 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10448 if (err < 0)
10449 return err;
10450 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10451 if (err < 0)
10452 return err;
10453
10454 spec->multiout.max_channels = 2;
10455
10456 /* digital only support output */
10457 if (spec->autocfg.dig_out_pin)
10458 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10459
10460 if (spec->kctl_alloc)
10461 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10462
aef9d318
TI
10463 if (spec->autocfg.speaker_pins[0] != 0x1d)
10464 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10465
a361d84b
KY
10466 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10467 spec->num_mux_defs = 1;
10468 spec->input_mux = &spec->private_imux;
10469
776e184e
TI
10470 err = alc_auto_add_mic_boost(codec);
10471 if (err < 0)
10472 return err;
10473
a361d84b
KY
10474 return 1;
10475}
10476
10477#define alc268_auto_init_multi_out alc882_auto_init_multi_out
10478#define alc268_auto_init_hp_out alc882_auto_init_hp_out
10479#define alc268_auto_init_analog_input alc882_auto_init_analog_input
10480
10481/* init callback for auto-configuration model -- overriding the default init */
10482static void alc268_auto_init(struct hda_codec *codec)
10483{
f6c7e546 10484 struct alc_spec *spec = codec->spec;
a361d84b
KY
10485 alc268_auto_init_multi_out(codec);
10486 alc268_auto_init_hp_out(codec);
10487 alc268_auto_init_mono_speaker_out(codec);
10488 alc268_auto_init_analog_input(codec);
f6c7e546
TI
10489 if (spec->unsol_event)
10490 alc_sku_automute(codec);
a361d84b
KY
10491}
10492
10493/*
10494 * configuration and preset
10495 */
10496static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 10497 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 10498 [ALC268_3ST] = "3stack",
983f8ae4 10499 [ALC268_TOSHIBA] = "toshiba",
d273809e 10500 [ALC268_ACER] = "acer",
3866f0b0 10501 [ALC268_DELL] = "dell",
f12462c5 10502 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
10503#ifdef CONFIG_SND_DEBUG
10504 [ALC268_TEST] = "test",
10505#endif
a361d84b
KY
10506 [ALC268_AUTO] = "auto",
10507};
10508
10509static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 10510 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 10511 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 10512 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 10513 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 10514 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
3866f0b0 10515 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 10516 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 10517 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 10518 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 10519 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
378bd6a5 10520 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 10521 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 10522 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
f12462c5 10523 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
10524 {}
10525};
10526
10527static struct alc_config_preset alc268_presets[] = {
eb5a6621
HRK
10528 [ALC267_QUANTA_IL1] = {
10529 .mixers = { alc267_quanta_il1_mixer },
10530 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10531 alc267_quanta_il1_verbs },
10532 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10533 .dac_nids = alc268_dac_nids,
10534 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10535 .adc_nids = alc268_adc_nids_alt,
10536 .hp_nid = 0x03,
10537 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10538 .channel_mode = alc268_modes,
10539 .input_mux = &alc268_capture_source,
10540 .unsol_event = alc267_quanta_il1_unsol_event,
10541 .init_hook = alc267_quanta_il1_automute,
10542 },
a361d84b 10543 [ALC268_3ST] = {
aef9d318
TI
10544 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10545 alc268_beep_mixer },
a361d84b
KY
10546 .init_verbs = { alc268_base_init_verbs },
10547 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10548 .dac_nids = alc268_dac_nids,
10549 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10550 .adc_nids = alc268_adc_nids_alt,
e1406348 10551 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
10552 .hp_nid = 0x03,
10553 .dig_out_nid = ALC268_DIGOUT_NID,
10554 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10555 .channel_mode = alc268_modes,
10556 .input_mux = &alc268_capture_source,
10557 },
d1a991a6 10558 [ALC268_TOSHIBA] = {
aef9d318
TI
10559 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10560 alc268_beep_mixer },
d273809e
TI
10561 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10562 alc268_toshiba_verbs },
d1a991a6
KY
10563 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10564 .dac_nids = alc268_dac_nids,
10565 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10566 .adc_nids = alc268_adc_nids_alt,
e1406348 10567 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
10568 .hp_nid = 0x03,
10569 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10570 .channel_mode = alc268_modes,
10571 .input_mux = &alc268_capture_source,
d273809e
TI
10572 .unsol_event = alc268_toshiba_unsol_event,
10573 .init_hook = alc268_toshiba_automute,
10574 },
10575 [ALC268_ACER] = {
aef9d318
TI
10576 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10577 alc268_beep_mixer },
d273809e
TI
10578 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10579 alc268_acer_verbs },
10580 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10581 .dac_nids = alc268_dac_nids,
10582 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10583 .adc_nids = alc268_adc_nids_alt,
e1406348 10584 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
10585 .hp_nid = 0x02,
10586 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10587 .channel_mode = alc268_modes,
0ccb541c 10588 .input_mux = &alc268_acer_capture_source,
d273809e 10589 .unsol_event = alc268_acer_unsol_event,
889c4395 10590 .init_hook = alc268_acer_init_hook,
d1a991a6 10591 },
3866f0b0 10592 [ALC268_DELL] = {
aef9d318 10593 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
10594 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10595 alc268_dell_verbs },
10596 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10597 .dac_nids = alc268_dac_nids,
10598 .hp_nid = 0x02,
10599 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10600 .channel_mode = alc268_modes,
10601 .unsol_event = alc268_dell_unsol_event,
10602 .init_hook = alc268_dell_init_hook,
10603 .input_mux = &alc268_capture_source,
10604 },
f12462c5 10605 [ALC268_ZEPTO] = {
aef9d318
TI
10606 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10607 alc268_beep_mixer },
f12462c5
MT
10608 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10609 alc268_toshiba_verbs },
10610 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10611 .dac_nids = alc268_dac_nids,
10612 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10613 .adc_nids = alc268_adc_nids_alt,
e1406348 10614 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
10615 .hp_nid = 0x03,
10616 .dig_out_nid = ALC268_DIGOUT_NID,
10617 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10618 .channel_mode = alc268_modes,
10619 .input_mux = &alc268_capture_source,
10620 .unsol_event = alc268_toshiba_unsol_event,
10621 .init_hook = alc268_toshiba_automute
10622 },
86c53bd2
JW
10623#ifdef CONFIG_SND_DEBUG
10624 [ALC268_TEST] = {
10625 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10626 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10627 alc268_volume_init_verbs },
10628 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10629 .dac_nids = alc268_dac_nids,
10630 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10631 .adc_nids = alc268_adc_nids_alt,
e1406348 10632 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
10633 .hp_nid = 0x03,
10634 .dig_out_nid = ALC268_DIGOUT_NID,
10635 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10636 .channel_mode = alc268_modes,
10637 .input_mux = &alc268_capture_source,
10638 },
10639#endif
a361d84b
KY
10640};
10641
10642static int patch_alc268(struct hda_codec *codec)
10643{
10644 struct alc_spec *spec;
10645 int board_config;
10646 int err;
10647
10648 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10649 if (spec == NULL)
10650 return -ENOMEM;
10651
10652 codec->spec = spec;
10653
10654 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10655 alc268_models,
10656 alc268_cfg_tbl);
10657
10658 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10659 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10660 "trying auto-probe from BIOS...\n");
10661 board_config = ALC268_AUTO;
10662 }
10663
10664 if (board_config == ALC268_AUTO) {
10665 /* automatic parse from the BIOS config */
10666 err = alc268_parse_auto_config(codec);
10667 if (err < 0) {
10668 alc_free(codec);
10669 return err;
10670 } else if (!err) {
10671 printk(KERN_INFO
10672 "hda_codec: Cannot set up configuration "
10673 "from BIOS. Using base mode...\n");
10674 board_config = ALC268_3ST;
10675 }
10676 }
10677
10678 if (board_config != ALC268_AUTO)
10679 setup_preset(spec, &alc268_presets[board_config]);
10680
10681 spec->stream_name_analog = "ALC268 Analog";
10682 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10683 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 10684 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b
KY
10685
10686 spec->stream_name_digital = "ALC268 Digital";
10687 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10688
aef9d318
TI
10689 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10690 /* override the amp caps for beep generator */
10691 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10692 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10693 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10694 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10695 (0 << AC_AMPCAP_MUTE_SHIFT));
10696
3866f0b0
TI
10697 if (!spec->adc_nids && spec->input_mux) {
10698 /* check whether NID 0x07 is valid */
10699 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 10700 int i;
3866f0b0
TI
10701
10702 /* get type */
10703 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 10704 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
10705 spec->adc_nids = alc268_adc_nids_alt;
10706 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10707 spec->mixers[spec->num_mixers] =
a361d84b 10708 alc268_capture_alt_mixer;
3866f0b0
TI
10709 spec->num_mixers++;
10710 } else {
10711 spec->adc_nids = alc268_adc_nids;
10712 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10713 spec->mixers[spec->num_mixers] =
10714 alc268_capture_mixer;
10715 spec->num_mixers++;
a361d84b 10716 }
e1406348 10717 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
10718 /* set default input source */
10719 for (i = 0; i < spec->num_adc_nids; i++)
10720 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
10721 0, AC_VERB_SET_CONNECT_SEL,
10722 spec->input_mux->items[0].index);
a361d84b 10723 }
2134ea4f
TI
10724
10725 spec->vmaster_nid = 0x02;
10726
a361d84b
KY
10727 codec->patch_ops = alc_patch_ops;
10728 if (board_config == ALC268_AUTO)
10729 spec->init_hook = alc268_auto_init;
10730
10731 return 0;
10732}
10733
f6a92248
KY
10734/*
10735 * ALC269 channel source setting (2 channel)
10736 */
10737#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10738
10739#define alc269_dac_nids alc260_dac_nids
10740
10741static hda_nid_t alc269_adc_nids[1] = {
10742 /* ADC1 */
10743 0x07,
10744};
10745
10746#define alc269_modes alc260_modes
10747#define alc269_capture_source alc880_lg_lw_capture_source
10748
10749static struct snd_kcontrol_new alc269_base_mixer[] = {
10750 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10751 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10752 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10753 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10755 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10756 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10757 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10758 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10759 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10760 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10761 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10762 { } /* end */
10763};
10764
10765/* capture mixer elements */
10766static struct snd_kcontrol_new alc269_capture_mixer[] = {
10767 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10768 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10769 {
10770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10771 /* The multiple "Capture Source" controls confuse alsamixer
10772 * So call somewhat different..
f6a92248
KY
10773 */
10774 /* .name = "Capture Source", */
10775 .name = "Input Source",
10776 .count = 1,
10777 .info = alc_mux_enum_info,
10778 .get = alc_mux_enum_get,
10779 .put = alc_mux_enum_put,
10780 },
10781 { } /* end */
10782};
10783
10784/*
10785 * generic initialization of ADC, input mixers and output mixers
10786 */
10787static struct hda_verb alc269_init_verbs[] = {
10788 /*
10789 * Unmute ADC0 and set the default input to mic-in
10790 */
10791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10792
10793 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10794 * analog-loopback mixer widget
10795 * Note: PASD motherboards uses the Line In 2 as the input for
10796 * front panel mic (mic 2)
10797 */
10798 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10799 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10800 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10801 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10802 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10803 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10804
10805 /*
10806 * Set up output mixers (0x0c - 0x0e)
10807 */
10808 /* set vol=0 to output mixers */
10809 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10810 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10811
10812 /* set up input amps for analog loopback */
10813 /* Amp Indices: DAC = 0, mixer = 1 */
10814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10817 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10818 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10819 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10820
10821 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10823 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10824 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10825 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10826 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10828
10829 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10832 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10833 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10835 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10836
10837 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10838 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10839
10840 /* FIXME: use matrix-type input source selection */
10841 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10842 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10843 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10844 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10845 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10846 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10847
10848 /* set EAPD */
10849 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10850 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10851 { }
10852};
10853
10854/* add playback controls from the parsed DAC table */
10855static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10856 const struct auto_pin_cfg *cfg)
10857{
10858 hda_nid_t nid;
10859 int err;
10860
10861 spec->multiout.num_dacs = 1; /* only use one dac */
10862 spec->multiout.dac_nids = spec->private_dac_nids;
10863 spec->multiout.dac_nids[0] = 2;
10864
10865 nid = cfg->line_out_pins[0];
10866 if (nid) {
10867 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10868 "Front Playback Volume",
10869 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10870 if (err < 0)
10871 return err;
10872 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10873 "Front Playback Switch",
10874 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10875 if (err < 0)
10876 return err;
10877 }
10878
10879 nid = cfg->speaker_pins[0];
10880 if (nid) {
10881 if (!cfg->line_out_pins[0]) {
10882 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10883 "Speaker Playback Volume",
10884 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10885 HDA_OUTPUT));
10886 if (err < 0)
10887 return err;
10888 }
10889 if (nid == 0x16) {
10890 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10891 "Speaker Playback Switch",
10892 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10893 HDA_OUTPUT));
10894 if (err < 0)
10895 return err;
10896 } else {
10897 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10898 "Speaker Playback Switch",
10899 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10900 HDA_OUTPUT));
10901 if (err < 0)
10902 return err;
10903 }
10904 }
10905 nid = cfg->hp_pins[0];
10906 if (nid) {
10907 /* spec->multiout.hp_nid = 2; */
10908 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10909 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10910 "Headphone Playback Volume",
10911 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10912 HDA_OUTPUT));
10913 if (err < 0)
10914 return err;
10915 }
10916 if (nid == 0x16) {
10917 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10918 "Headphone Playback Switch",
10919 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10920 HDA_OUTPUT));
10921 if (err < 0)
10922 return err;
10923 } else {
10924 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10925 "Headphone Playback Switch",
10926 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10927 HDA_OUTPUT));
10928 if (err < 0)
10929 return err;
10930 }
10931 }
10932 return 0;
10933}
10934
10935#define alc269_auto_create_analog_input_ctls \
10936 alc880_auto_create_analog_input_ctls
10937
10938#ifdef CONFIG_SND_HDA_POWER_SAVE
10939#define alc269_loopbacks alc880_loopbacks
10940#endif
10941
10942/* pcm configuration: identiacal with ALC880 */
10943#define alc269_pcm_analog_playback alc880_pcm_analog_playback
10944#define alc269_pcm_analog_capture alc880_pcm_analog_capture
10945#define alc269_pcm_digital_playback alc880_pcm_digital_playback
10946#define alc269_pcm_digital_capture alc880_pcm_digital_capture
10947
10948/*
10949 * BIOS auto configuration
10950 */
10951static int alc269_parse_auto_config(struct hda_codec *codec)
10952{
10953 struct alc_spec *spec = codec->spec;
10954 int err;
10955 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10956
10957 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10958 alc269_ignore);
10959 if (err < 0)
10960 return err;
10961
10962 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10963 if (err < 0)
10964 return err;
10965 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10966 if (err < 0)
10967 return err;
10968
10969 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10970
10971 if (spec->autocfg.dig_out_pin)
10972 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10973
10974 if (spec->kctl_alloc)
10975 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10976
10977 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10978 spec->num_mux_defs = 1;
10979 spec->input_mux = &spec->private_imux;
10980
10981 err = alc_auto_add_mic_boost(codec);
10982 if (err < 0)
10983 return err;
10984
10985 return 1;
10986}
10987
10988#define alc269_auto_init_multi_out alc882_auto_init_multi_out
10989#define alc269_auto_init_hp_out alc882_auto_init_hp_out
10990#define alc269_auto_init_analog_input alc882_auto_init_analog_input
10991
10992
10993/* init callback for auto-configuration model -- overriding the default init */
10994static void alc269_auto_init(struct hda_codec *codec)
10995{
f6c7e546 10996 struct alc_spec *spec = codec->spec;
f6a92248
KY
10997 alc269_auto_init_multi_out(codec);
10998 alc269_auto_init_hp_out(codec);
10999 alc269_auto_init_analog_input(codec);
f6c7e546
TI
11000 if (spec->unsol_event)
11001 alc_sku_automute(codec);
f6a92248
KY
11002}
11003
11004/*
11005 * configuration and preset
11006 */
11007static const char *alc269_models[ALC269_MODEL_LAST] = {
11008 [ALC269_BASIC] = "basic",
11009};
11010
11011static struct snd_pci_quirk alc269_cfg_tbl[] = {
11012 {}
11013};
11014
11015static struct alc_config_preset alc269_presets[] = {
11016 [ALC269_BASIC] = {
11017 .mixers = { alc269_base_mixer },
11018 .init_verbs = { alc269_init_verbs },
11019 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
11020 .dac_nids = alc269_dac_nids,
11021 .hp_nid = 0x03,
11022 .num_channel_mode = ARRAY_SIZE(alc269_modes),
11023 .channel_mode = alc269_modes,
11024 .input_mux = &alc269_capture_source,
11025 },
11026};
11027
11028static int patch_alc269(struct hda_codec *codec)
11029{
11030 struct alc_spec *spec;
11031 int board_config;
11032 int err;
11033
11034 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11035 if (spec == NULL)
11036 return -ENOMEM;
11037
11038 codec->spec = spec;
11039
11040 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11041 alc269_models,
11042 alc269_cfg_tbl);
11043
11044 if (board_config < 0) {
11045 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
11046 "trying auto-probe from BIOS...\n");
11047 board_config = ALC269_AUTO;
11048 }
11049
11050 if (board_config == ALC269_AUTO) {
11051 /* automatic parse from the BIOS config */
11052 err = alc269_parse_auto_config(codec);
11053 if (err < 0) {
11054 alc_free(codec);
11055 return err;
11056 } else if (!err) {
11057 printk(KERN_INFO
11058 "hda_codec: Cannot set up configuration "
11059 "from BIOS. Using base mode...\n");
11060 board_config = ALC269_BASIC;
11061 }
11062 }
11063
11064 if (board_config != ALC269_AUTO)
11065 setup_preset(spec, &alc269_presets[board_config]);
11066
11067 spec->stream_name_analog = "ALC269 Analog";
11068 spec->stream_analog_playback = &alc269_pcm_analog_playback;
11069 spec->stream_analog_capture = &alc269_pcm_analog_capture;
11070
11071 spec->stream_name_digital = "ALC269 Digital";
11072 spec->stream_digital_playback = &alc269_pcm_digital_playback;
11073 spec->stream_digital_capture = &alc269_pcm_digital_capture;
11074
11075 spec->adc_nids = alc269_adc_nids;
11076 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
11077 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
11078 spec->num_mixers++;
11079
11080 codec->patch_ops = alc_patch_ops;
11081 if (board_config == ALC269_AUTO)
11082 spec->init_hook = alc269_auto_init;
11083#ifdef CONFIG_SND_HDA_POWER_SAVE
11084 if (!spec->loopback.amplist)
11085 spec->loopback.amplist = alc269_loopbacks;
11086#endif
11087
11088 return 0;
11089}
11090
df694daa
KY
11091/*
11092 * ALC861 channel source setting (2/6 channel selection for 3-stack)
11093 */
11094
11095/*
11096 * set the path ways for 2 channel output
11097 * need to set the codec line out and mic 1 pin widgets to inputs
11098 */
11099static struct hda_verb alc861_threestack_ch2_init[] = {
11100 /* set pin widget 1Ah (line in) for input */
11101 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
11102 /* set pin widget 18h (mic1/2) for input, for mic also enable
11103 * the vref
11104 */
df694daa
KY
11105 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11106
9c7f852e
TI
11107 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11108#if 0
11109 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11110 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11111#endif
df694daa
KY
11112 { } /* end */
11113};
11114/*
11115 * 6ch mode
11116 * need to set the codec line out and mic 1 pin widgets to outputs
11117 */
11118static struct hda_verb alc861_threestack_ch6_init[] = {
11119 /* set pin widget 1Ah (line in) for output (Back Surround)*/
11120 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11121 /* set pin widget 18h (mic1) for output (CLFE)*/
11122 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11123
11124 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 11125 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 11126
9c7f852e
TI
11127 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11128#if 0
11129 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11130 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11131#endif
df694daa
KY
11132 { } /* end */
11133};
11134
11135static struct hda_channel_mode alc861_threestack_modes[2] = {
11136 { 2, alc861_threestack_ch2_init },
11137 { 6, alc861_threestack_ch6_init },
11138};
22309c3e
TI
11139/* Set mic1 as input and unmute the mixer */
11140static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
11141 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11142 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11143 { } /* end */
11144};
11145/* Set mic1 as output and mute mixer */
11146static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
11147 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11148 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11149 { } /* end */
11150};
11151
11152static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
11153 { 2, alc861_uniwill_m31_ch2_init },
11154 { 4, alc861_uniwill_m31_ch4_init },
11155};
df694daa 11156
7cdbff94
MD
11157/* Set mic1 and line-in as input and unmute the mixer */
11158static struct hda_verb alc861_asus_ch2_init[] = {
11159 /* set pin widget 1Ah (line in) for input */
11160 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
11161 /* set pin widget 18h (mic1/2) for input, for mic also enable
11162 * the vref
11163 */
7cdbff94
MD
11164 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11165
11166 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11167#if 0
11168 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11169 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11170#endif
11171 { } /* end */
11172};
11173/* Set mic1 nad line-in as output and mute mixer */
11174static struct hda_verb alc861_asus_ch6_init[] = {
11175 /* set pin widget 1Ah (line in) for output (Back Surround)*/
11176 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11177 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11178 /* set pin widget 18h (mic1) for output (CLFE)*/
11179 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11180 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11181 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11182 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11183
11184 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11185#if 0
11186 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11187 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11188#endif
11189 { } /* end */
11190};
11191
11192static struct hda_channel_mode alc861_asus_modes[2] = {
11193 { 2, alc861_asus_ch2_init },
11194 { 6, alc861_asus_ch6_init },
11195};
11196
df694daa
KY
11197/* patch-ALC861 */
11198
11199static struct snd_kcontrol_new alc861_base_mixer[] = {
11200 /* output mixer control */
11201 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11202 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11203 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11204 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11205 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11206
11207 /*Input mixer control */
11208 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11209 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11210 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11211 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11212 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11213 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11215 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11216 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 11218
df694daa
KY
11219 /* Capture mixer control */
11220 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11221 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11222 {
11223 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11224 .name = "Capture Source",
11225 .count = 1,
11226 .info = alc_mux_enum_info,
11227 .get = alc_mux_enum_get,
11228 .put = alc_mux_enum_put,
11229 },
11230 { } /* end */
11231};
11232
11233static struct snd_kcontrol_new alc861_3ST_mixer[] = {
11234 /* output mixer control */
11235 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11236 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11237 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11238 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11239 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11240
11241 /* Input mixer control */
11242 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11243 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11244 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11245 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11246 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11247 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11249 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11250 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 11252
df694daa
KY
11253 /* Capture mixer control */
11254 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11255 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11256 {
11257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11258 .name = "Capture Source",
11259 .count = 1,
11260 .info = alc_mux_enum_info,
11261 .get = alc_mux_enum_get,
11262 .put = alc_mux_enum_put,
11263 },
11264 {
11265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11266 .name = "Channel Mode",
11267 .info = alc_ch_mode_info,
11268 .get = alc_ch_mode_get,
11269 .put = alc_ch_mode_put,
11270 .private_value = ARRAY_SIZE(alc861_threestack_modes),
11271 },
11272 { } /* end */
a53d1aec
TD
11273};
11274
d1d985f0 11275static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
11276 /* output mixer control */
11277 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11279 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11280
11281 /*Capture mixer control */
11282 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11283 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11284 {
11285 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11286 .name = "Capture Source",
11287 .count = 1,
11288 .info = alc_mux_enum_info,
11289 .get = alc_mux_enum_get,
11290 .put = alc_mux_enum_put,
11291 },
11292
11293 { } /* end */
f12ab1e0 11294};
a53d1aec 11295
22309c3e
TI
11296static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
11297 /* output mixer control */
11298 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11299 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11300 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11301 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11302 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11303
11304 /* Input mixer control */
11305 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11306 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11307 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11308 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11309 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11310 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11312 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11313 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 11315
22309c3e
TI
11316 /* Capture mixer control */
11317 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11318 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11319 {
11320 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11321 .name = "Capture Source",
11322 .count = 1,
11323 .info = alc_mux_enum_info,
11324 .get = alc_mux_enum_get,
11325 .put = alc_mux_enum_put,
11326 },
11327 {
11328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11329 .name = "Channel Mode",
11330 .info = alc_ch_mode_info,
11331 .get = alc_ch_mode_get,
11332 .put = alc_ch_mode_put,
11333 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
11334 },
11335 { } /* end */
f12ab1e0 11336};
7cdbff94
MD
11337
11338static struct snd_kcontrol_new alc861_asus_mixer[] = {
11339 /* output mixer control */
11340 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11341 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11342 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11343 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11344 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11345
11346 /* Input mixer control */
11347 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11348 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11349 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11350 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11351 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11352 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11354 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11355 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
11356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
11357
7cdbff94
MD
11358 /* Capture mixer control */
11359 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11360 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11361 {
11362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11363 .name = "Capture Source",
11364 .count = 1,
11365 .info = alc_mux_enum_info,
11366 .get = alc_mux_enum_get,
11367 .put = alc_mux_enum_put,
11368 },
11369 {
11370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11371 .name = "Channel Mode",
11372 .info = alc_ch_mode_info,
11373 .get = alc_ch_mode_get,
11374 .put = alc_ch_mode_put,
11375 .private_value = ARRAY_SIZE(alc861_asus_modes),
11376 },
11377 { }
56bb0cab
TI
11378};
11379
11380/* additional mixer */
d1d985f0 11381static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
11382 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11383 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11384 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
11385 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
11386 { }
11387};
7cdbff94 11388
df694daa
KY
11389/*
11390 * generic initialization of ADC, input mixers and output mixers
11391 */
11392static struct hda_verb alc861_base_init_verbs[] = {
11393 /*
11394 * Unmute ADC0 and set the default input to mic-in
11395 */
11396 /* port-A for surround (rear panel) */
11397 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11398 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
11399 /* port-B for mic-in (rear panel) with vref */
11400 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11401 /* port-C for line-in (rear panel) */
11402 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11403 /* port-D for Front */
11404 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11405 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11406 /* port-E for HP out (front panel) */
11407 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11408 /* route front PCM to HP */
9dece1d7 11409 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
11410 /* port-F for mic-in (front panel) with vref */
11411 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11412 /* port-G for CLFE (rear panel) */
11413 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11414 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11415 /* port-H for side (rear panel) */
11416 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11417 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
11418 /* CD-in */
11419 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11420 /* route front mic to ADC1*/
11421 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11422 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11423
11424 /* Unmute DAC0~3 & spdif out*/
11425 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11426 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11427 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11428 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11430
11431 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11432 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11433 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11434 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11435 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11436
11437 /* Unmute Stereo Mixer 15 */
11438 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11441 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11442
11443 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11444 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11445 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11446 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11447 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11448 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11449 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11450 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11451 /* hp used DAC 3 (Front) */
11452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11453 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11454
11455 { }
11456};
11457
11458static struct hda_verb alc861_threestack_init_verbs[] = {
11459 /*
11460 * Unmute ADC0 and set the default input to mic-in
11461 */
11462 /* port-A for surround (rear panel) */
11463 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11464 /* port-B for mic-in (rear panel) with vref */
11465 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11466 /* port-C for line-in (rear panel) */
11467 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11468 /* port-D for Front */
11469 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11470 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11471 /* port-E for HP out (front panel) */
11472 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11473 /* route front PCM to HP */
9dece1d7 11474 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
11475 /* port-F for mic-in (front panel) with vref */
11476 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11477 /* port-G for CLFE (rear panel) */
11478 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11479 /* port-H for side (rear panel) */
11480 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11481 /* CD-in */
11482 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11483 /* route front mic to ADC1*/
11484 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11486 /* Unmute DAC0~3 & spdif out*/
11487 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11488 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11489 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11490 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11492
11493 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11494 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11495 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11496 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11497 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11498
11499 /* Unmute Stereo Mixer 15 */
11500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11504
11505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11507 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11508 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11510 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11513 /* hp used DAC 3 (Front) */
11514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11516 { }
11517};
22309c3e
TI
11518
11519static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11520 /*
11521 * Unmute ADC0 and set the default input to mic-in
11522 */
11523 /* port-A for surround (rear panel) */
11524 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11525 /* port-B for mic-in (rear panel) with vref */
11526 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11527 /* port-C for line-in (rear panel) */
11528 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11529 /* port-D for Front */
11530 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11531 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11532 /* port-E for HP out (front panel) */
f12ab1e0
TI
11533 /* this has to be set to VREF80 */
11534 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 11535 /* route front PCM to HP */
9dece1d7 11536 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
11537 /* port-F for mic-in (front panel) with vref */
11538 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11539 /* port-G for CLFE (rear panel) */
11540 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11541 /* port-H for side (rear panel) */
11542 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11543 /* CD-in */
11544 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11545 /* route front mic to ADC1*/
11546 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11548 /* Unmute DAC0~3 & spdif out*/
11549 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11550 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11551 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11552 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11554
11555 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11556 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11557 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11558 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11559 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11560
11561 /* Unmute Stereo Mixer 15 */
11562 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
11566
11567 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11569 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11570 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11571 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11572 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11573 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11574 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11575 /* hp used DAC 3 (Front) */
11576 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
11577 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11578 { }
11579};
11580
7cdbff94
MD
11581static struct hda_verb alc861_asus_init_verbs[] = {
11582 /*
11583 * Unmute ADC0 and set the default input to mic-in
11584 */
f12ab1e0
TI
11585 /* port-A for surround (rear panel)
11586 * according to codec#0 this is the HP jack
11587 */
7cdbff94
MD
11588 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11589 /* route front PCM to HP */
11590 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11591 /* port-B for mic-in (rear panel) with vref */
11592 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11593 /* port-C for line-in (rear panel) */
11594 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11595 /* port-D for Front */
11596 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11597 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11598 /* port-E for HP out (front panel) */
f12ab1e0
TI
11599 /* this has to be set to VREF80 */
11600 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 11601 /* route front PCM to HP */
9dece1d7 11602 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
11603 /* port-F for mic-in (front panel) with vref */
11604 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11605 /* port-G for CLFE (rear panel) */
11606 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11607 /* port-H for side (rear panel) */
11608 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11609 /* CD-in */
11610 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11611 /* route front mic to ADC1*/
11612 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11613 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11614 /* Unmute DAC0~3 & spdif out*/
11615 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11616 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11617 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11618 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11620 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11621 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11622 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11623 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11624 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11625
11626 /* Unmute Stereo Mixer 15 */
11627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11628 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11629 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11630 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
11631
11632 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11633 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11634 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11635 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11636 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11637 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11639 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11640 /* hp used DAC 3 (Front) */
11641 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
11642 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11643 { }
11644};
11645
56bb0cab
TI
11646/* additional init verbs for ASUS laptops */
11647static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11648 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11649 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11650 { }
11651};
7cdbff94 11652
df694daa
KY
11653/*
11654 * generic initialization of ADC, input mixers and output mixers
11655 */
11656static struct hda_verb alc861_auto_init_verbs[] = {
11657 /*
11658 * Unmute ADC0 and set the default input to mic-in
11659 */
f12ab1e0 11660 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
11661 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11662
11663 /* Unmute DAC0~3 & spdif out*/
11664 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11666 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11667 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11669
11670 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11671 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11672 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11673 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11674 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11675
11676 /* Unmute Stereo Mixer 15 */
11677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11678 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11680 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11681
11682 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11684 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11686 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11687 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11688 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11689 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11690
11691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11692 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11693 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11695 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11696 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11697 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11698 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 11699
f12ab1e0 11700 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
11701
11702 { }
11703};
11704
a53d1aec
TD
11705static struct hda_verb alc861_toshiba_init_verbs[] = {
11706 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 11707
a53d1aec
TD
11708 { }
11709};
11710
11711/* toggle speaker-output according to the hp-jack state */
11712static void alc861_toshiba_automute(struct hda_codec *codec)
11713{
11714 unsigned int present;
11715
11716 present = snd_hda_codec_read(codec, 0x0f, 0,
11717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11718 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11719 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11720 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11721 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
11722}
11723
11724static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11725 unsigned int res)
11726{
a53d1aec
TD
11727 if ((res >> 26) == ALC880_HP_EVENT)
11728 alc861_toshiba_automute(codec);
11729}
11730
df694daa
KY
11731/* pcm configuration: identiacal with ALC880 */
11732#define alc861_pcm_analog_playback alc880_pcm_analog_playback
11733#define alc861_pcm_analog_capture alc880_pcm_analog_capture
11734#define alc861_pcm_digital_playback alc880_pcm_digital_playback
11735#define alc861_pcm_digital_capture alc880_pcm_digital_capture
11736
11737
11738#define ALC861_DIGOUT_NID 0x07
11739
11740static struct hda_channel_mode alc861_8ch_modes[1] = {
11741 { 8, NULL }
11742};
11743
11744static hda_nid_t alc861_dac_nids[4] = {
11745 /* front, surround, clfe, side */
11746 0x03, 0x06, 0x05, 0x04
11747};
11748
9c7f852e
TI
11749static hda_nid_t alc660_dac_nids[3] = {
11750 /* front, clfe, surround */
11751 0x03, 0x05, 0x06
11752};
11753
df694daa
KY
11754static hda_nid_t alc861_adc_nids[1] = {
11755 /* ADC0-2 */
11756 0x08,
11757};
11758
11759static struct hda_input_mux alc861_capture_source = {
11760 .num_items = 5,
11761 .items = {
11762 { "Mic", 0x0 },
11763 { "Front Mic", 0x3 },
11764 { "Line", 0x1 },
11765 { "CD", 0x4 },
11766 { "Mixer", 0x5 },
11767 },
11768};
11769
11770/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
11771static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11772 const struct auto_pin_cfg *cfg)
df694daa
KY
11773{
11774 int i;
11775 hda_nid_t nid;
11776
11777 spec->multiout.dac_nids = spec->private_dac_nids;
11778 for (i = 0; i < cfg->line_outs; i++) {
11779 nid = cfg->line_out_pins[i];
11780 if (nid) {
11781 if (i >= ARRAY_SIZE(alc861_dac_nids))
11782 continue;
11783 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11784 }
11785 }
11786 spec->multiout.num_dacs = cfg->line_outs;
11787 return 0;
11788}
11789
11790/* add playback controls from the parsed DAC table */
11791static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11792 const struct auto_pin_cfg *cfg)
11793{
11794 char name[32];
f12ab1e0
TI
11795 static const char *chname[4] = {
11796 "Front", "Surround", NULL /*CLFE*/, "Side"
11797 };
df694daa
KY
11798 hda_nid_t nid;
11799 int i, idx, err;
11800
11801 for (i = 0; i < cfg->line_outs; i++) {
11802 nid = spec->multiout.dac_nids[i];
f12ab1e0 11803 if (!nid)
df694daa
KY
11804 continue;
11805 if (nid == 0x05) {
11806 /* Center/LFE */
f12ab1e0
TI
11807 err = add_control(spec, ALC_CTL_BIND_MUTE,
11808 "Center Playback Switch",
11809 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11810 HDA_OUTPUT));
11811 if (err < 0)
df694daa 11812 return err;
f12ab1e0
TI
11813 err = add_control(spec, ALC_CTL_BIND_MUTE,
11814 "LFE Playback Switch",
11815 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11816 HDA_OUTPUT));
11817 if (err < 0)
df694daa
KY
11818 return err;
11819 } else {
f12ab1e0
TI
11820 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11821 idx++)
df694daa
KY
11822 if (nid == alc861_dac_nids[idx])
11823 break;
11824 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
11825 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11826 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11827 HDA_OUTPUT));
11828 if (err < 0)
df694daa
KY
11829 return err;
11830 }
11831 }
11832 return 0;
11833}
11834
11835static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11836{
11837 int err;
11838 hda_nid_t nid;
11839
f12ab1e0 11840 if (!pin)
df694daa
KY
11841 return 0;
11842
11843 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11844 nid = 0x03;
f12ab1e0
TI
11845 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11846 "Headphone Playback Switch",
11847 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11848 if (err < 0)
df694daa
KY
11849 return err;
11850 spec->multiout.hp_nid = nid;
11851 }
11852 return 0;
11853}
11854
11855/* create playback/capture controls for input pins */
f12ab1e0
TI
11856static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11857 const struct auto_pin_cfg *cfg)
df694daa 11858{
df694daa
KY
11859 struct hda_input_mux *imux = &spec->private_imux;
11860 int i, err, idx, idx1;
11861
11862 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 11863 switch (cfg->input_pins[i]) {
df694daa
KY
11864 case 0x0c:
11865 idx1 = 1;
f12ab1e0 11866 idx = 2; /* Line In */
df694daa
KY
11867 break;
11868 case 0x0f:
11869 idx1 = 2;
f12ab1e0 11870 idx = 2; /* Line In */
df694daa
KY
11871 break;
11872 case 0x0d:
11873 idx1 = 0;
f12ab1e0 11874 idx = 1; /* Mic In */
df694daa 11875 break;
f12ab1e0 11876 case 0x10:
df694daa 11877 idx1 = 3;
f12ab1e0 11878 idx = 1; /* Mic In */
df694daa
KY
11879 break;
11880 case 0x11:
11881 idx1 = 4;
f12ab1e0 11882 idx = 0; /* CD */
df694daa
KY
11883 break;
11884 default:
11885 continue;
11886 }
11887
4a471b7d
TI
11888 err = new_analog_input(spec, cfg->input_pins[i],
11889 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
11890 if (err < 0)
11891 return err;
11892
4a471b7d 11893 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 11894 imux->items[imux->num_items].index = idx1;
f12ab1e0 11895 imux->num_items++;
df694daa
KY
11896 }
11897 return 0;
11898}
11899
11900static struct snd_kcontrol_new alc861_capture_mixer[] = {
11901 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11902 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11903
11904 {
11905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11906 /* The multiple "Capture Source" controls confuse alsamixer
11907 * So call somewhat different..
df694daa
KY
11908 */
11909 /* .name = "Capture Source", */
11910 .name = "Input Source",
11911 .count = 1,
11912 .info = alc_mux_enum_info,
11913 .get = alc_mux_enum_get,
11914 .put = alc_mux_enum_put,
11915 },
11916 { } /* end */
11917};
11918
f12ab1e0
TI
11919static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11920 hda_nid_t nid,
df694daa
KY
11921 int pin_type, int dac_idx)
11922{
564c5bea
JL
11923 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11924 pin_type);
11925 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11926 AMP_OUT_UNMUTE);
df694daa
KY
11927}
11928
11929static void alc861_auto_init_multi_out(struct hda_codec *codec)
11930{
11931 struct alc_spec *spec = codec->spec;
11932 int i;
11933
bc9f98a9 11934 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
11935 for (i = 0; i < spec->autocfg.line_outs; i++) {
11936 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11937 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 11938 if (nid)
baba8ee9 11939 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 11940 spec->multiout.dac_nids[i]);
df694daa
KY
11941 }
11942}
11943
11944static void alc861_auto_init_hp_out(struct hda_codec *codec)
11945{
11946 struct alc_spec *spec = codec->spec;
11947 hda_nid_t pin;
11948
eb06ed8f 11949 pin = spec->autocfg.hp_pins[0];
df694daa 11950 if (pin) /* connect to front */
f12ab1e0
TI
11951 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11952 spec->multiout.dac_nids[0]);
f6c7e546
TI
11953 pin = spec->autocfg.speaker_pins[0];
11954 if (pin)
11955 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
11956}
11957
11958static void alc861_auto_init_analog_input(struct hda_codec *codec)
11959{
11960 struct alc_spec *spec = codec->spec;
11961 int i;
11962
11963 for (i = 0; i < AUTO_PIN_LAST; i++) {
11964 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
11965 if (nid >= 0x0c && nid <= 0x11) {
11966 snd_hda_codec_write(codec, nid, 0,
11967 AC_VERB_SET_PIN_WIDGET_CONTROL,
11968 i <= AUTO_PIN_FRONT_MIC ?
11969 PIN_VREF80 : PIN_IN);
df694daa
KY
11970 }
11971 }
11972}
11973
11974/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
11975/* return 1 if successful, 0 if the proper config is not found,
11976 * or a negative error code
11977 */
df694daa
KY
11978static int alc861_parse_auto_config(struct hda_codec *codec)
11979{
11980 struct alc_spec *spec = codec->spec;
11981 int err;
11982 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11983
f12ab1e0
TI
11984 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11985 alc861_ignore);
11986 if (err < 0)
df694daa 11987 return err;
f12ab1e0 11988 if (!spec->autocfg.line_outs)
df694daa
KY
11989 return 0; /* can't find valid BIOS pin config */
11990
f12ab1e0
TI
11991 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11992 if (err < 0)
11993 return err;
11994 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11995 if (err < 0)
11996 return err;
11997 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11998 if (err < 0)
11999 return err;
12000 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
12001 if (err < 0)
df694daa
KY
12002 return err;
12003
12004 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12005
12006 if (spec->autocfg.dig_out_pin)
12007 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
12008
12009 if (spec->kctl_alloc)
12010 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12011
12012 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
12013
a1e8d2da 12014 spec->num_mux_defs = 1;
df694daa
KY
12015 spec->input_mux = &spec->private_imux;
12016
12017 spec->adc_nids = alc861_adc_nids;
12018 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
12019 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
12020 spec->num_mixers++;
12021
12022 return 1;
12023}
12024
ae6b813a
TI
12025/* additional initialization for auto-configuration model */
12026static void alc861_auto_init(struct hda_codec *codec)
df694daa 12027{
f6c7e546 12028 struct alc_spec *spec = codec->spec;
df694daa
KY
12029 alc861_auto_init_multi_out(codec);
12030 alc861_auto_init_hp_out(codec);
12031 alc861_auto_init_analog_input(codec);
f6c7e546
TI
12032 if (spec->unsol_event)
12033 alc_sku_automute(codec);
df694daa
KY
12034}
12035
cb53c626
TI
12036#ifdef CONFIG_SND_HDA_POWER_SAVE
12037static struct hda_amp_list alc861_loopbacks[] = {
12038 { 0x15, HDA_INPUT, 0 },
12039 { 0x15, HDA_INPUT, 1 },
12040 { 0x15, HDA_INPUT, 2 },
12041 { 0x15, HDA_INPUT, 3 },
12042 { } /* end */
12043};
12044#endif
12045
df694daa
KY
12046
12047/*
12048 * configuration and preset
12049 */
f5fcc13c
TI
12050static const char *alc861_models[ALC861_MODEL_LAST] = {
12051 [ALC861_3ST] = "3stack",
12052 [ALC660_3ST] = "3stack-660",
12053 [ALC861_3ST_DIG] = "3stack-dig",
12054 [ALC861_6ST_DIG] = "6stack-dig",
12055 [ALC861_UNIWILL_M31] = "uniwill-m31",
12056 [ALC861_TOSHIBA] = "toshiba",
12057 [ALC861_ASUS] = "asus",
12058 [ALC861_ASUS_LAPTOP] = "asus-laptop",
12059 [ALC861_AUTO] = "auto",
12060};
12061
12062static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 12063 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
12064 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12065 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12066 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 12067 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 12068 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 12069 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
12070 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
12071 * Any other models that need this preset?
12072 */
12073 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
12074 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
12075 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 12076 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
12077 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
12078 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
12079 /* FIXME: the below seems conflict */
12080 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 12081 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 12082 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
12083 {}
12084};
12085
12086static struct alc_config_preset alc861_presets[] = {
12087 [ALC861_3ST] = {
12088 .mixers = { alc861_3ST_mixer },
12089 .init_verbs = { alc861_threestack_init_verbs },
12090 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12091 .dac_nids = alc861_dac_nids,
12092 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12093 .channel_mode = alc861_threestack_modes,
4e195a7b 12094 .need_dac_fix = 1,
df694daa
KY
12095 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12096 .adc_nids = alc861_adc_nids,
12097 .input_mux = &alc861_capture_source,
12098 },
12099 [ALC861_3ST_DIG] = {
12100 .mixers = { alc861_base_mixer },
12101 .init_verbs = { alc861_threestack_init_verbs },
12102 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12103 .dac_nids = alc861_dac_nids,
12104 .dig_out_nid = ALC861_DIGOUT_NID,
12105 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12106 .channel_mode = alc861_threestack_modes,
4e195a7b 12107 .need_dac_fix = 1,
df694daa
KY
12108 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12109 .adc_nids = alc861_adc_nids,
12110 .input_mux = &alc861_capture_source,
12111 },
12112 [ALC861_6ST_DIG] = {
12113 .mixers = { alc861_base_mixer },
12114 .init_verbs = { alc861_base_init_verbs },
12115 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12116 .dac_nids = alc861_dac_nids,
12117 .dig_out_nid = ALC861_DIGOUT_NID,
12118 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
12119 .channel_mode = alc861_8ch_modes,
12120 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12121 .adc_nids = alc861_adc_nids,
12122 .input_mux = &alc861_capture_source,
12123 },
9c7f852e
TI
12124 [ALC660_3ST] = {
12125 .mixers = { alc861_3ST_mixer },
12126 .init_verbs = { alc861_threestack_init_verbs },
12127 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
12128 .dac_nids = alc660_dac_nids,
12129 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12130 .channel_mode = alc861_threestack_modes,
4e195a7b 12131 .need_dac_fix = 1,
9c7f852e
TI
12132 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12133 .adc_nids = alc861_adc_nids,
12134 .input_mux = &alc861_capture_source,
12135 },
22309c3e
TI
12136 [ALC861_UNIWILL_M31] = {
12137 .mixers = { alc861_uniwill_m31_mixer },
12138 .init_verbs = { alc861_uniwill_m31_init_verbs },
12139 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12140 .dac_nids = alc861_dac_nids,
12141 .dig_out_nid = ALC861_DIGOUT_NID,
12142 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
12143 .channel_mode = alc861_uniwill_m31_modes,
12144 .need_dac_fix = 1,
12145 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12146 .adc_nids = alc861_adc_nids,
12147 .input_mux = &alc861_capture_source,
12148 },
a53d1aec
TD
12149 [ALC861_TOSHIBA] = {
12150 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
12151 .init_verbs = { alc861_base_init_verbs,
12152 alc861_toshiba_init_verbs },
a53d1aec
TD
12153 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12154 .dac_nids = alc861_dac_nids,
12155 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12156 .channel_mode = alc883_3ST_2ch_modes,
12157 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12158 .adc_nids = alc861_adc_nids,
12159 .input_mux = &alc861_capture_source,
12160 .unsol_event = alc861_toshiba_unsol_event,
12161 .init_hook = alc861_toshiba_automute,
12162 },
7cdbff94
MD
12163 [ALC861_ASUS] = {
12164 .mixers = { alc861_asus_mixer },
12165 .init_verbs = { alc861_asus_init_verbs },
12166 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12167 .dac_nids = alc861_dac_nids,
12168 .dig_out_nid = ALC861_DIGOUT_NID,
12169 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
12170 .channel_mode = alc861_asus_modes,
12171 .need_dac_fix = 1,
12172 .hp_nid = 0x06,
12173 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12174 .adc_nids = alc861_adc_nids,
12175 .input_mux = &alc861_capture_source,
12176 },
56bb0cab
TI
12177 [ALC861_ASUS_LAPTOP] = {
12178 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
12179 .init_verbs = { alc861_asus_init_verbs,
12180 alc861_asus_laptop_init_verbs },
12181 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12182 .dac_nids = alc861_dac_nids,
12183 .dig_out_nid = ALC861_DIGOUT_NID,
12184 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12185 .channel_mode = alc883_3ST_2ch_modes,
12186 .need_dac_fix = 1,
12187 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12188 .adc_nids = alc861_adc_nids,
12189 .input_mux = &alc861_capture_source,
12190 },
12191};
df694daa
KY
12192
12193
12194static int patch_alc861(struct hda_codec *codec)
12195{
12196 struct alc_spec *spec;
12197 int board_config;
12198 int err;
12199
dc041e0b 12200 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12201 if (spec == NULL)
12202 return -ENOMEM;
12203
f12ab1e0 12204 codec->spec = spec;
df694daa 12205
f5fcc13c
TI
12206 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
12207 alc861_models,
12208 alc861_cfg_tbl);
9c7f852e 12209
f5fcc13c 12210 if (board_config < 0) {
9c7f852e
TI
12211 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
12212 "trying auto-probe from BIOS...\n");
df694daa
KY
12213 board_config = ALC861_AUTO;
12214 }
12215
12216 if (board_config == ALC861_AUTO) {
12217 /* automatic parse from the BIOS config */
12218 err = alc861_parse_auto_config(codec);
12219 if (err < 0) {
12220 alc_free(codec);
12221 return err;
f12ab1e0 12222 } else if (!err) {
9c7f852e
TI
12223 printk(KERN_INFO
12224 "hda_codec: Cannot set up configuration "
12225 "from BIOS. Using base mode...\n");
df694daa
KY
12226 board_config = ALC861_3ST_DIG;
12227 }
12228 }
12229
12230 if (board_config != ALC861_AUTO)
12231 setup_preset(spec, &alc861_presets[board_config]);
12232
12233 spec->stream_name_analog = "ALC861 Analog";
12234 spec->stream_analog_playback = &alc861_pcm_analog_playback;
12235 spec->stream_analog_capture = &alc861_pcm_analog_capture;
12236
12237 spec->stream_name_digital = "ALC861 Digital";
12238 spec->stream_digital_playback = &alc861_pcm_digital_playback;
12239 spec->stream_digital_capture = &alc861_pcm_digital_capture;
12240
2134ea4f
TI
12241 spec->vmaster_nid = 0x03;
12242
df694daa
KY
12243 codec->patch_ops = alc_patch_ops;
12244 if (board_config == ALC861_AUTO)
ae6b813a 12245 spec->init_hook = alc861_auto_init;
cb53c626
TI
12246#ifdef CONFIG_SND_HDA_POWER_SAVE
12247 if (!spec->loopback.amplist)
12248 spec->loopback.amplist = alc861_loopbacks;
12249#endif
df694daa 12250
1da177e4
LT
12251 return 0;
12252}
12253
f32610ed
JS
12254/*
12255 * ALC861-VD support
12256 *
12257 * Based on ALC882
12258 *
12259 * In addition, an independent DAC
12260 */
12261#define ALC861VD_DIGOUT_NID 0x06
12262
12263static hda_nid_t alc861vd_dac_nids[4] = {
12264 /* front, surr, clfe, side surr */
12265 0x02, 0x03, 0x04, 0x05
12266};
12267
12268/* dac_nids for ALC660vd are in a different order - according to
12269 * Realtek's driver.
12270 * This should probably tesult in a different mixer for 6stack models
12271 * of ALC660vd codecs, but for now there is only 3stack mixer
12272 * - and it is the same as in 861vd.
12273 * adc_nids in ALC660vd are (is) the same as in 861vd
12274 */
12275static hda_nid_t alc660vd_dac_nids[3] = {
12276 /* front, rear, clfe, rear_surr */
12277 0x02, 0x04, 0x03
12278};
12279
12280static hda_nid_t alc861vd_adc_nids[1] = {
12281 /* ADC0 */
12282 0x09,
12283};
12284
e1406348
TI
12285static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
12286
f32610ed
JS
12287/* input MUX */
12288/* FIXME: should be a matrix-type input source selection */
12289static struct hda_input_mux alc861vd_capture_source = {
12290 .num_items = 4,
12291 .items = {
12292 { "Mic", 0x0 },
12293 { "Front Mic", 0x1 },
12294 { "Line", 0x2 },
12295 { "CD", 0x4 },
12296 },
12297};
12298
272a527c 12299static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 12300 .num_items = 2,
272a527c 12301 .items = {
b419f346
TD
12302 { "Ext Mic", 0x0 },
12303 { "Int Mic", 0x1 },
272a527c
KY
12304 },
12305};
12306
d1a991a6
KY
12307static struct hda_input_mux alc861vd_hp_capture_source = {
12308 .num_items = 2,
12309 .items = {
12310 { "Front Mic", 0x0 },
12311 { "ATAPI Mic", 0x1 },
12312 },
12313};
12314
f32610ed
JS
12315#define alc861vd_mux_enum_info alc_mux_enum_info
12316#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
12317/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
12318#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
12319
12320/*
12321 * 2ch mode
12322 */
12323static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
12324 { 2, NULL }
12325};
12326
12327/*
12328 * 6ch mode
12329 */
12330static struct hda_verb alc861vd_6stack_ch6_init[] = {
12331 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12332 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12333 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12334 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12335 { } /* end */
12336};
12337
12338/*
12339 * 8ch mode
12340 */
12341static struct hda_verb alc861vd_6stack_ch8_init[] = {
12342 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12343 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12344 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12345 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12346 { } /* end */
12347};
12348
12349static struct hda_channel_mode alc861vd_6stack_modes[2] = {
12350 { 6, alc861vd_6stack_ch6_init },
12351 { 8, alc861vd_6stack_ch8_init },
12352};
12353
12354static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
12355 {
12356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12357 .name = "Channel Mode",
12358 .info = alc_ch_mode_info,
12359 .get = alc_ch_mode_get,
12360 .put = alc_ch_mode_put,
12361 },
12362 { } /* end */
12363};
12364
12365static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
12366 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12367 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12368
12369 {
12370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12371 /* The multiple "Capture Source" controls confuse alsamixer
12372 * So call somewhat different..
f32610ed
JS
12373 */
12374 /* .name = "Capture Source", */
12375 .name = "Input Source",
12376 .count = 1,
12377 .info = alc861vd_mux_enum_info,
12378 .get = alc861vd_mux_enum_get,
12379 .put = alc861vd_mux_enum_put,
12380 },
12381 { } /* end */
12382};
12383
12384/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12385 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12386 */
12387static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
12388 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12390
12391 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12392 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
12393
12394 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
12395 HDA_OUTPUT),
12396 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
12397 HDA_OUTPUT),
12398 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12399 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
12400
12401 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
12402 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
12403
12404 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12405
12406 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12408 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12409
12410 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12411 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12412 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12413
12414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12416
12417 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12418 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12419
12420 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12421 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12422
12423 { } /* end */
12424};
12425
12426static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12427 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12428 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12429
12430 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12431
12432 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12434 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12435
12436 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12438 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12439
12440 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12441 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12442
12443 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12444 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12445
12446 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12447 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12448
12449 { } /* end */
12450};
12451
bdd148a3
KY
12452static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12453 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12454 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12455 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12456
12457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12458
12459 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12460 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12461 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12462
12463 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12466
12467 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12468 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12469
12470 { } /* end */
12471};
12472
b419f346
TD
12473/* Pin assignment: Speaker=0x14, HP = 0x15,
12474 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
12475 */
12476static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
12477 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12478 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
12479 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12480 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
12481 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12482 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12483 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12484 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12485 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12486 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12487 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
12488 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
12489 { } /* end */
12490};
12491
d1a991a6
KY
12492/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12493 * Front Mic=0x18, ATAPI Mic = 0x19,
12494 */
12495static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12496 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12498 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12499 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12500 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12501 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12502 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12503 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12504
12505 { } /* end */
12506};
12507
f32610ed
JS
12508/*
12509 * generic initialization of ADC, input mixers and output mixers
12510 */
12511static struct hda_verb alc861vd_volume_init_verbs[] = {
12512 /*
12513 * Unmute ADC0 and set the default input to mic-in
12514 */
12515 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12516 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12517
12518 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12519 * the analog-loopback mixer widget
12520 */
12521 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
12527
12528 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
12529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 12532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
12533
12534 /*
12535 * Set up output mixers (0x02 - 0x05)
12536 */
12537 /* set vol=0 to output mixers */
12538 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12539 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12540 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12541 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12542
12543 /* set up input amps for analog loopback */
12544 /* Amp Indices: DAC = 0, mixer = 1 */
12545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12547 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12549 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12551 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12552 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12553
12554 { }
12555};
12556
12557/*
12558 * 3-stack pin configuration:
12559 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12560 */
12561static struct hda_verb alc861vd_3stack_init_verbs[] = {
12562 /*
12563 * Set pin mode and muting
12564 */
12565 /* set front pin widgets 0x14 for output */
12566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12567 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12568 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12569
12570 /* Mic (rear) pin: input vref at 80% */
12571 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12572 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12573 /* Front Mic pin: input vref at 80% */
12574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12575 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12576 /* Line In pin: input */
12577 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12578 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12579 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12580 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12581 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12582 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12583 /* CD pin widget for input */
12584 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12585
12586 { }
12587};
12588
12589/*
12590 * 6-stack pin configuration:
12591 */
12592static struct hda_verb alc861vd_6stack_init_verbs[] = {
12593 /*
12594 * Set pin mode and muting
12595 */
12596 /* set front pin widgets 0x14 for output */
12597 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12599 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12600
12601 /* Rear Pin: output 1 (0x0d) */
12602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12604 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12605 /* CLFE Pin: output 2 (0x0e) */
12606 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12607 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12608 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12609 /* Side Pin: output 3 (0x0f) */
12610 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12611 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12612 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12613
12614 /* Mic (rear) pin: input vref at 80% */
12615 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12616 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12617 /* Front Mic pin: input vref at 80% */
12618 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12620 /* Line In pin: input */
12621 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12622 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12623 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12624 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12625 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12626 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12627 /* CD pin widget for input */
12628 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12629
12630 { }
12631};
12632
bdd148a3
KY
12633static struct hda_verb alc861vd_eapd_verbs[] = {
12634 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12635 { }
12636};
12637
12638static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12642 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12643 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12644 {}
12645};
12646
12647/* toggle speaker-output according to the hp-jack state */
12648static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12649{
12650 unsigned int present;
12651 unsigned char bits;
12652
12653 present = snd_hda_codec_read(codec, 0x1b, 0,
12654 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12655 bits = present ? HDA_AMP_MUTE : 0;
12656 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12657 HDA_AMP_MUTE, bits);
bdd148a3
KY
12658}
12659
12660static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12661{
12662 unsigned int present;
12663 unsigned char bits;
12664
12665 present = snd_hda_codec_read(codec, 0x18, 0,
12666 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12667 bits = present ? HDA_AMP_MUTE : 0;
12668 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12669 HDA_AMP_MUTE, bits);
bdd148a3
KY
12670}
12671
12672static void alc861vd_lenovo_automute(struct hda_codec *codec)
12673{
12674 alc861vd_lenovo_hp_automute(codec);
12675 alc861vd_lenovo_mic_automute(codec);
12676}
12677
12678static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12679 unsigned int res)
12680{
12681 switch (res >> 26) {
12682 case ALC880_HP_EVENT:
12683 alc861vd_lenovo_hp_automute(codec);
12684 break;
12685 case ALC880_MIC_EVENT:
12686 alc861vd_lenovo_mic_automute(codec);
12687 break;
12688 }
12689}
12690
272a527c
KY
12691static struct hda_verb alc861vd_dallas_verbs[] = {
12692 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12693 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12694 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12695 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12696
12697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12699 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12701 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12703 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12705
12706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12710 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12711 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12712 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12713 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12714
12715 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12716 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12722 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12723
12724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12728
12729 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12730 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12731 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12732
12733 { } /* end */
12734};
12735
12736/* toggle speaker-output according to the hp-jack state */
12737static void alc861vd_dallas_automute(struct hda_codec *codec)
12738{
12739 unsigned int present;
12740
12741 present = snd_hda_codec_read(codec, 0x15, 0,
12742 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12743 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12744 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
12745}
12746
12747static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12748{
12749 if ((res >> 26) == ALC880_HP_EVENT)
12750 alc861vd_dallas_automute(codec);
12751}
12752
cb53c626
TI
12753#ifdef CONFIG_SND_HDA_POWER_SAVE
12754#define alc861vd_loopbacks alc880_loopbacks
12755#endif
12756
f32610ed
JS
12757/* pcm configuration: identiacal with ALC880 */
12758#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12759#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12760#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12761#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12762
12763/*
12764 * configuration and preset
12765 */
12766static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12767 [ALC660VD_3ST] = "3stack-660",
983f8ae4 12768 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
12769 [ALC861VD_3ST] = "3stack",
12770 [ALC861VD_3ST_DIG] = "3stack-digout",
12771 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 12772 [ALC861VD_LENOVO] = "lenovo",
272a527c 12773 [ALC861VD_DALLAS] = "dallas",
983f8ae4 12774 [ALC861VD_HP] = "hp",
f32610ed
JS
12775 [ALC861VD_AUTO] = "auto",
12776};
12777
12778static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
12779 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12780 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 12781 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 12782 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 12783 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 12784 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 12785 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 12786 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 12787 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 12788 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 12789 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 12790 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
12791 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12792 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 12793 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
12794 {}
12795};
12796
12797static struct alc_config_preset alc861vd_presets[] = {
12798 [ALC660VD_3ST] = {
12799 .mixers = { alc861vd_3st_mixer },
12800 .init_verbs = { alc861vd_volume_init_verbs,
12801 alc861vd_3stack_init_verbs },
12802 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12803 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
12804 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12805 .channel_mode = alc861vd_3stack_2ch_modes,
12806 .input_mux = &alc861vd_capture_source,
12807 },
6963f84c
MC
12808 [ALC660VD_3ST_DIG] = {
12809 .mixers = { alc861vd_3st_mixer },
12810 .init_verbs = { alc861vd_volume_init_verbs,
12811 alc861vd_3stack_init_verbs },
12812 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12813 .dac_nids = alc660vd_dac_nids,
12814 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
12815 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12816 .channel_mode = alc861vd_3stack_2ch_modes,
12817 .input_mux = &alc861vd_capture_source,
12818 },
f32610ed
JS
12819 [ALC861VD_3ST] = {
12820 .mixers = { alc861vd_3st_mixer },
12821 .init_verbs = { alc861vd_volume_init_verbs,
12822 alc861vd_3stack_init_verbs },
12823 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12824 .dac_nids = alc861vd_dac_nids,
12825 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12826 .channel_mode = alc861vd_3stack_2ch_modes,
12827 .input_mux = &alc861vd_capture_source,
12828 },
12829 [ALC861VD_3ST_DIG] = {
12830 .mixers = { alc861vd_3st_mixer },
12831 .init_verbs = { alc861vd_volume_init_verbs,
12832 alc861vd_3stack_init_verbs },
12833 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12834 .dac_nids = alc861vd_dac_nids,
12835 .dig_out_nid = ALC861VD_DIGOUT_NID,
12836 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12837 .channel_mode = alc861vd_3stack_2ch_modes,
12838 .input_mux = &alc861vd_capture_source,
12839 },
12840 [ALC861VD_6ST_DIG] = {
12841 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12842 .init_verbs = { alc861vd_volume_init_verbs,
12843 alc861vd_6stack_init_verbs },
12844 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12845 .dac_nids = alc861vd_dac_nids,
12846 .dig_out_nid = ALC861VD_DIGOUT_NID,
12847 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12848 .channel_mode = alc861vd_6stack_modes,
12849 .input_mux = &alc861vd_capture_source,
12850 },
bdd148a3
KY
12851 [ALC861VD_LENOVO] = {
12852 .mixers = { alc861vd_lenovo_mixer },
12853 .init_verbs = { alc861vd_volume_init_verbs,
12854 alc861vd_3stack_init_verbs,
12855 alc861vd_eapd_verbs,
12856 alc861vd_lenovo_unsol_verbs },
12857 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12858 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
12859 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12860 .channel_mode = alc861vd_3stack_2ch_modes,
12861 .input_mux = &alc861vd_capture_source,
12862 .unsol_event = alc861vd_lenovo_unsol_event,
12863 .init_hook = alc861vd_lenovo_automute,
12864 },
272a527c
KY
12865 [ALC861VD_DALLAS] = {
12866 .mixers = { alc861vd_dallas_mixer },
12867 .init_verbs = { alc861vd_dallas_verbs },
12868 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12869 .dac_nids = alc861vd_dac_nids,
272a527c
KY
12870 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12871 .channel_mode = alc861vd_3stack_2ch_modes,
12872 .input_mux = &alc861vd_dallas_capture_source,
12873 .unsol_event = alc861vd_dallas_unsol_event,
12874 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
12875 },
12876 [ALC861VD_HP] = {
12877 .mixers = { alc861vd_hp_mixer },
12878 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12879 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12880 .dac_nids = alc861vd_dac_nids,
d1a991a6 12881 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
12882 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12883 .channel_mode = alc861vd_3stack_2ch_modes,
12884 .input_mux = &alc861vd_hp_capture_source,
12885 .unsol_event = alc861vd_dallas_unsol_event,
12886 .init_hook = alc861vd_dallas_automute,
12887 },
f32610ed
JS
12888};
12889
12890/*
12891 * BIOS auto configuration
12892 */
12893static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12894 hda_nid_t nid, int pin_type, int dac_idx)
12895{
f6c7e546 12896 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
12897}
12898
12899static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12900{
12901 struct alc_spec *spec = codec->spec;
12902 int i;
12903
bc9f98a9 12904 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
12905 for (i = 0; i <= HDA_SIDE; i++) {
12906 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 12907 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
12908 if (nid)
12909 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 12910 pin_type, i);
f32610ed
JS
12911 }
12912}
12913
12914
12915static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12916{
12917 struct alc_spec *spec = codec->spec;
12918 hda_nid_t pin;
12919
12920 pin = spec->autocfg.hp_pins[0];
12921 if (pin) /* connect to front and use dac 0 */
12922 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
12923 pin = spec->autocfg.speaker_pins[0];
12924 if (pin)
12925 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
12926}
12927
12928#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12929#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12930
12931static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12932{
12933 struct alc_spec *spec = codec->spec;
12934 int i;
12935
12936 for (i = 0; i < AUTO_PIN_LAST; i++) {
12937 hda_nid_t nid = spec->autocfg.input_pins[i];
12938 if (alc861vd_is_input_pin(nid)) {
12939 snd_hda_codec_write(codec, nid, 0,
12940 AC_VERB_SET_PIN_WIDGET_CONTROL,
12941 i <= AUTO_PIN_FRONT_MIC ?
12942 PIN_VREF80 : PIN_IN);
12943 if (nid != ALC861VD_PIN_CD_NID)
12944 snd_hda_codec_write(codec, nid, 0,
12945 AC_VERB_SET_AMP_GAIN_MUTE,
12946 AMP_OUT_MUTE);
12947 }
12948 }
12949}
12950
12951#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12952#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12953
12954/* add playback controls from the parsed DAC table */
12955/* Based on ALC880 version. But ALC861VD has separate,
12956 * different NIDs for mute/unmute switch and volume control */
12957static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12958 const struct auto_pin_cfg *cfg)
12959{
12960 char name[32];
12961 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12962 hda_nid_t nid_v, nid_s;
12963 int i, err;
12964
12965 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 12966 if (!spec->multiout.dac_nids[i])
f32610ed
JS
12967 continue;
12968 nid_v = alc861vd_idx_to_mixer_vol(
12969 alc880_dac_to_idx(
12970 spec->multiout.dac_nids[i]));
12971 nid_s = alc861vd_idx_to_mixer_switch(
12972 alc880_dac_to_idx(
12973 spec->multiout.dac_nids[i]));
12974
12975 if (i == 2) {
12976 /* Center/LFE */
f12ab1e0
TI
12977 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12978 "Center Playback Volume",
12979 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12980 HDA_OUTPUT));
12981 if (err < 0)
f32610ed 12982 return err;
f12ab1e0
TI
12983 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12984 "LFE Playback Volume",
12985 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12986 HDA_OUTPUT));
12987 if (err < 0)
f32610ed 12988 return err;
f12ab1e0
TI
12989 err = add_control(spec, ALC_CTL_BIND_MUTE,
12990 "Center Playback Switch",
12991 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12992 HDA_INPUT));
12993 if (err < 0)
f32610ed 12994 return err;
f12ab1e0
TI
12995 err = add_control(spec, ALC_CTL_BIND_MUTE,
12996 "LFE Playback Switch",
12997 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12998 HDA_INPUT));
12999 if (err < 0)
f32610ed
JS
13000 return err;
13001 } else {
13002 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
13003 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13004 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
13005 HDA_OUTPUT));
13006 if (err < 0)
f32610ed
JS
13007 return err;
13008 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 13009 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 13010 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
13011 HDA_INPUT));
13012 if (err < 0)
f32610ed
JS
13013 return err;
13014 }
13015 }
13016 return 0;
13017}
13018
13019/* add playback controls for speaker and HP outputs */
13020/* Based on ALC880 version. But ALC861VD has separate,
13021 * different NIDs for mute/unmute switch and volume control */
13022static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
13023 hda_nid_t pin, const char *pfx)
13024{
13025 hda_nid_t nid_v, nid_s;
13026 int err;
13027 char name[32];
13028
f12ab1e0 13029 if (!pin)
f32610ed
JS
13030 return 0;
13031
13032 if (alc880_is_fixed_pin(pin)) {
13033 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13034 /* specify the DAC as the extra output */
f12ab1e0 13035 if (!spec->multiout.hp_nid)
f32610ed
JS
13036 spec->multiout.hp_nid = nid_v;
13037 else
13038 spec->multiout.extra_out_nid[0] = nid_v;
13039 /* control HP volume/switch on the output mixer amp */
13040 nid_v = alc861vd_idx_to_mixer_vol(
13041 alc880_fixed_pin_idx(pin));
13042 nid_s = alc861vd_idx_to_mixer_switch(
13043 alc880_fixed_pin_idx(pin));
13044
13045 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
13046 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13047 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
13048 if (err < 0)
f32610ed
JS
13049 return err;
13050 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
13051 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13052 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
13053 if (err < 0)
f32610ed
JS
13054 return err;
13055 } else if (alc880_is_multi_pin(pin)) {
13056 /* set manual connection */
13057 /* we have only a switch on HP-out PIN */
13058 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
13059 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13060 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13061 if (err < 0)
f32610ed
JS
13062 return err;
13063 }
13064 return 0;
13065}
13066
13067/* parse the BIOS configuration and set up the alc_spec
13068 * return 1 if successful, 0 if the proper config is not found,
13069 * or a negative error code
13070 * Based on ALC880 version - had to change it to override
13071 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
13072static int alc861vd_parse_auto_config(struct hda_codec *codec)
13073{
13074 struct alc_spec *spec = codec->spec;
13075 int err;
13076 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
13077
f12ab1e0
TI
13078 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13079 alc861vd_ignore);
13080 if (err < 0)
f32610ed 13081 return err;
f12ab1e0 13082 if (!spec->autocfg.line_outs)
f32610ed
JS
13083 return 0; /* can't find valid BIOS pin config */
13084
f12ab1e0
TI
13085 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13086 if (err < 0)
13087 return err;
13088 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
13089 if (err < 0)
13090 return err;
13091 err = alc861vd_auto_create_extra_out(spec,
13092 spec->autocfg.speaker_pins[0],
13093 "Speaker");
13094 if (err < 0)
13095 return err;
13096 err = alc861vd_auto_create_extra_out(spec,
13097 spec->autocfg.hp_pins[0],
13098 "Headphone");
13099 if (err < 0)
13100 return err;
13101 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
13102 if (err < 0)
f32610ed
JS
13103 return err;
13104
13105 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13106
13107 if (spec->autocfg.dig_out_pin)
13108 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
13109
13110 if (spec->kctl_alloc)
13111 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13112
13113 spec->init_verbs[spec->num_init_verbs++]
13114 = alc861vd_volume_init_verbs;
13115
13116 spec->num_mux_defs = 1;
13117 spec->input_mux = &spec->private_imux;
13118
776e184e
TI
13119 err = alc_auto_add_mic_boost(codec);
13120 if (err < 0)
13121 return err;
13122
f32610ed
JS
13123 return 1;
13124}
13125
13126/* additional initialization for auto-configuration model */
13127static void alc861vd_auto_init(struct hda_codec *codec)
13128{
f6c7e546 13129 struct alc_spec *spec = codec->spec;
f32610ed
JS
13130 alc861vd_auto_init_multi_out(codec);
13131 alc861vd_auto_init_hp_out(codec);
13132 alc861vd_auto_init_analog_input(codec);
f6c7e546
TI
13133 if (spec->unsol_event)
13134 alc_sku_automute(codec);
f32610ed
JS
13135}
13136
13137static int patch_alc861vd(struct hda_codec *codec)
13138{
13139 struct alc_spec *spec;
13140 int err, board_config;
13141
13142 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13143 if (spec == NULL)
13144 return -ENOMEM;
13145
13146 codec->spec = spec;
13147
13148 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
13149 alc861vd_models,
13150 alc861vd_cfg_tbl);
13151
13152 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
13153 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
13154 "ALC861VD, trying auto-probe from BIOS...\n");
13155 board_config = ALC861VD_AUTO;
13156 }
13157
13158 if (board_config == ALC861VD_AUTO) {
13159 /* automatic parse from the BIOS config */
13160 err = alc861vd_parse_auto_config(codec);
13161 if (err < 0) {
13162 alc_free(codec);
13163 return err;
f12ab1e0 13164 } else if (!err) {
f32610ed
JS
13165 printk(KERN_INFO
13166 "hda_codec: Cannot set up configuration "
13167 "from BIOS. Using base mode...\n");
13168 board_config = ALC861VD_3ST;
13169 }
13170 }
13171
13172 if (board_config != ALC861VD_AUTO)
13173 setup_preset(spec, &alc861vd_presets[board_config]);
13174
13175 spec->stream_name_analog = "ALC861VD Analog";
13176 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13177 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13178
13179 spec->stream_name_digital = "ALC861VD Digital";
13180 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13181 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13182
13183 spec->adc_nids = alc861vd_adc_nids;
13184 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 13185 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed
JS
13186
13187 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
13188 spec->num_mixers++;
13189
2134ea4f
TI
13190 spec->vmaster_nid = 0x02;
13191
f32610ed
JS
13192 codec->patch_ops = alc_patch_ops;
13193
13194 if (board_config == ALC861VD_AUTO)
13195 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
13196#ifdef CONFIG_SND_HDA_POWER_SAVE
13197 if (!spec->loopback.amplist)
13198 spec->loopback.amplist = alc861vd_loopbacks;
13199#endif
f32610ed
JS
13200
13201 return 0;
13202}
13203
bc9f98a9
KY
13204/*
13205 * ALC662 support
13206 *
13207 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
13208 * configuration. Each pin widget can choose any input DACs and a mixer.
13209 * Each ADC is connected from a mixer of all inputs. This makes possible
13210 * 6-channel independent captures.
13211 *
13212 * In addition, an independent DAC for the multi-playback (not used in this
13213 * driver yet).
13214 */
13215#define ALC662_DIGOUT_NID 0x06
13216#define ALC662_DIGIN_NID 0x0a
13217
13218static hda_nid_t alc662_dac_nids[4] = {
13219 /* front, rear, clfe, rear_surr */
13220 0x02, 0x03, 0x04
13221};
13222
13223static hda_nid_t alc662_adc_nids[1] = {
13224 /* ADC1-2 */
13225 0x09,
13226};
e1406348 13227
77a261b7 13228static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
e1406348 13229
bc9f98a9
KY
13230/* input MUX */
13231/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
13232static struct hda_input_mux alc662_capture_source = {
13233 .num_items = 4,
13234 .items = {
13235 { "Mic", 0x0 },
13236 { "Front Mic", 0x1 },
13237 { "Line", 0x2 },
13238 { "CD", 0x4 },
13239 },
13240};
13241
13242static struct hda_input_mux alc662_lenovo_101e_capture_source = {
13243 .num_items = 2,
13244 .items = {
13245 { "Mic", 0x1 },
13246 { "Line", 0x2 },
13247 },
13248};
291702f0
KY
13249
13250static struct hda_input_mux alc662_eeepc_capture_source = {
13251 .num_items = 2,
13252 .items = {
13253 { "i-Mic", 0x1 },
13254 { "e-Mic", 0x0 },
13255 },
13256};
13257
6dda9f4a
KY
13258static struct hda_input_mux alc663_capture_source = {
13259 .num_items = 3,
13260 .items = {
13261 { "Mic", 0x0 },
13262 { "Front Mic", 0x1 },
13263 { "Line", 0x2 },
13264 },
13265};
13266
13267static struct hda_input_mux alc663_m51va_capture_source = {
13268 .num_items = 2,
13269 .items = {
13270 { "Ext-Mic", 0x0 },
13271 { "D-Mic", 0x9 },
13272 },
13273};
13274
bc9f98a9
KY
13275#define alc662_mux_enum_info alc_mux_enum_info
13276#define alc662_mux_enum_get alc_mux_enum_get
e1406348 13277#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 13278
bc9f98a9
KY
13279/*
13280 * 2ch mode
13281 */
13282static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
13283 { 2, NULL }
13284};
13285
13286/*
13287 * 2ch mode
13288 */
13289static struct hda_verb alc662_3ST_ch2_init[] = {
13290 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
13291 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13292 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
13293 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13294 { } /* end */
13295};
13296
13297/*
13298 * 6ch mode
13299 */
13300static struct hda_verb alc662_3ST_ch6_init[] = {
13301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13303 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
13304 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13305 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13306 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
13307 { } /* end */
13308};
13309
13310static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
13311 { 2, alc662_3ST_ch2_init },
13312 { 6, alc662_3ST_ch6_init },
13313};
13314
13315/*
13316 * 2ch mode
13317 */
13318static struct hda_verb alc662_sixstack_ch6_init[] = {
13319 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13320 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13321 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13322 { } /* end */
13323};
13324
13325/*
13326 * 6ch mode
13327 */
13328static struct hda_verb alc662_sixstack_ch8_init[] = {
13329 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13330 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13331 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13332 { } /* end */
13333};
13334
13335static struct hda_channel_mode alc662_5stack_modes[2] = {
13336 { 2, alc662_sixstack_ch6_init },
13337 { 6, alc662_sixstack_ch8_init },
13338};
13339
13340/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13341 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13342 */
13343
13344static struct snd_kcontrol_new alc662_base_mixer[] = {
13345 /* output mixer control */
13346 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 13347 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 13348 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 13349 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
13350 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13351 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
13352 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13353 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
13354 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13355
13356 /*Input mixer control */
13357 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
13358 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
13359 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
13360 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
13361 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
13362 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
13363 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
13364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
13365 { } /* end */
13366};
13367
13368static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
13369 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 13370 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
13371 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13372 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13373 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13374 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13375 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13378 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13379 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13380 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13381 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
13382 { } /* end */
13383};
13384
13385static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
13386 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 13387 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 13388 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 13389 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
13390 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13391 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
13392 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13393 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
13394 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13395 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13396 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13397 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13398 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13399 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13402 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13403 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13404 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
13405 { } /* end */
13406};
13407
13408static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13409 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13410 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
13411 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13412 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
13413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
13418 { } /* end */
13419};
13420
291702f0 13421static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 13422 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 13423
b4818494
HRK
13424 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13425 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
13426
13427 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13428 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13429 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13430
13431 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13432 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13433 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13434 { } /* end */
13435};
13436
8c427226 13437static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
13438 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13439 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
13440 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13441 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13442 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13443 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13444 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13445 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 13446 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
13447 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13448 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13449 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13450 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13451 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13452 { } /* end */
13453};
13454
6dda9f4a
KY
13455static struct snd_kcontrol_new alc663_m51va_mixer[] = {
13456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13457 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13460 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13461 HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT),
13462 { } /* end */
13463};
13464
13465static struct snd_kcontrol_new alc663_g71v_mixer[] = {
13466 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13467 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13468 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13469 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13470 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13471
13472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13474 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13475 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13476 { } /* end */
13477};
13478
13479static struct snd_kcontrol_new alc663_g50v_mixer[] = {
13480 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13481 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13483
13484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13486 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13487 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13490 { } /* end */
13491};
13492
bc9f98a9
KY
13493static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13494 {
13495 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13496 .name = "Channel Mode",
13497 .info = alc_ch_mode_info,
13498 .get = alc_ch_mode_get,
13499 .put = alc_ch_mode_put,
13500 },
13501 { } /* end */
13502};
13503
13504static struct hda_verb alc662_init_verbs[] = {
13505 /* ADC: mute amp left and right */
13506 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13507 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13508 /* Front mixer: unmute input/output amp left and right (volume = 0) */
13509
cb53c626
TI
13510 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13511 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13512 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 13515
b60dd394
KY
13516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13521 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13522
13523 /* Front Pin: output 0 (0x0c) */
13524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13526
13527 /* Rear Pin: output 1 (0x0d) */
13528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13530
13531 /* CLFE Pin: output 2 (0x0e) */
13532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13533 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13534
13535 /* Mic (rear) pin: input vref at 80% */
13536 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13537 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13538 /* Front Mic pin: input vref at 80% */
13539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13541 /* Line In pin: input */
13542 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13544 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13545 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13546 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13547 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13548 /* CD pin widget for input */
13549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13550
13551 /* FIXME: use matrix-type input source selection */
13552 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13553 /* Input mixer */
13554 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13555 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13556 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13557 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
13558
13559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6dda9f4a
KY
13563
13564 /* always trun on EAPD */
13565 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13566 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13567
bc9f98a9
KY
13568 { }
13569};
13570
13571static struct hda_verb alc662_sue_init_verbs[] = {
13572 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13573 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
13574 {}
13575};
13576
13577static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13578 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13579 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13580 {}
bc9f98a9
KY
13581};
13582
8c427226
KY
13583/* Set Unsolicited Event*/
13584static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13586 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13587 {}
13588};
13589
bc9f98a9
KY
13590/*
13591 * generic initialization of ADC, input mixers and output mixers
13592 */
13593static struct hda_verb alc662_auto_init_verbs[] = {
13594 /*
13595 * Unmute ADC and set the default input to mic-in
13596 */
13597 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13598 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13599
13600 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13601 * mixer widget
13602 * Note: PASD motherboards uses the Line In 2 as the input for front
13603 * panel mic (mic 2)
13604 */
13605 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13607 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13608 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13609 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13610 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
13611
13612 /*
13613 * Set up output mixers (0x0c - 0x0f)
13614 */
13615 /* set vol=0 to output mixers */
13616 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13617 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13618 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13619
13620 /* set up input amps for analog loopback */
13621 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
13622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13623 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13624 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13625 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13626 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13627 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13628
13629
13630 /* FIXME: use matrix-type input source selection */
13631 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13632 /* Input mixer */
13633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 13634 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
13635 { }
13636};
13637
6dda9f4a
KY
13638static struct hda_verb alc663_m51va_init_verbs[] = {
13639 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13640 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13641 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
13642
13643 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
13644
13645 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13646 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13647 {}
13648};
13649
13650static struct hda_verb alc663_g71v_init_verbs[] = {
13651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13652 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
13653 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
13654
13655 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13656 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13657 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
13658
13659 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13660 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
13661 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
13662 {}
13663};
13664
13665static struct hda_verb alc663_g50v_init_verbs[] = {
13666 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13667 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13668 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
13669
13670 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13671 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13672 {}
13673};
13674
bc9f98a9
KY
13675/* capture mixer elements */
13676static struct snd_kcontrol_new alc662_capture_mixer[] = {
13677 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13678 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13679 {
13680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13681 /* The multiple "Capture Source" controls confuse alsamixer
13682 * So call somewhat different..
bc9f98a9
KY
13683 */
13684 /* .name = "Capture Source", */
13685 .name = "Input Source",
13686 .count = 1,
6e7939bb
HRK
13687 .info = alc662_mux_enum_info,
13688 .get = alc662_mux_enum_get,
13689 .put = alc662_mux_enum_put,
bc9f98a9
KY
13690 },
13691 { } /* end */
13692};
13693
13694static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13695{
13696 unsigned int present;
f12ab1e0 13697 unsigned char bits;
bc9f98a9
KY
13698
13699 present = snd_hda_codec_read(codec, 0x14, 0,
13700 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13701 bits = present ? HDA_AMP_MUTE : 0;
13702 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13703 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13704}
13705
13706static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13707{
13708 unsigned int present;
f12ab1e0 13709 unsigned char bits;
bc9f98a9
KY
13710
13711 present = snd_hda_codec_read(codec, 0x1b, 0,
13712 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13713 bits = present ? HDA_AMP_MUTE : 0;
13714 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13715 HDA_AMP_MUTE, bits);
13716 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13717 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13718}
13719
13720static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13721 unsigned int res)
13722{
13723 if ((res >> 26) == ALC880_HP_EVENT)
13724 alc662_lenovo_101e_all_automute(codec);
13725 if ((res >> 26) == ALC880_FRONT_EVENT)
13726 alc662_lenovo_101e_ispeaker_automute(codec);
13727}
13728
291702f0
KY
13729static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13730{
13731 unsigned int present;
13732
13733 present = snd_hda_codec_read(codec, 0x18, 0,
13734 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13735 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13736 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13737 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13738 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13739 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13740 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13741 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13742 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13743}
13744
13745/* unsolicited event for HP jack sensing */
13746static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13747 unsigned int res)
13748{
13749 if ((res >> 26) == ALC880_HP_EVENT)
13750 alc262_hippo1_automute( codec );
13751
13752 if ((res >> 26) == ALC880_MIC_EVENT)
13753 alc662_eeepc_mic_automute(codec);
13754}
13755
13756static void alc662_eeepc_inithook(struct hda_codec *codec)
13757{
13758 alc262_hippo1_automute( codec );
13759 alc662_eeepc_mic_automute(codec);
13760}
13761
8c427226
KY
13762static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13763{
13764 unsigned int mute;
13765 unsigned int present;
13766
13767 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13768 present = snd_hda_codec_read(codec, 0x14, 0,
13769 AC_VERB_GET_PIN_SENSE, 0);
13770 present = (present & 0x80000000) != 0;
13771 if (present) {
13772 /* mute internal speaker */
13773 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13774 HDA_AMP_MUTE, HDA_AMP_MUTE);
13775 } else {
13776 /* unmute internal speaker if necessary */
13777 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13778 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13779 HDA_AMP_MUTE, mute);
13780 }
13781}
13782
13783/* unsolicited event for HP jack sensing */
13784static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13785 unsigned int res)
13786{
13787 if ((res >> 26) == ALC880_HP_EVENT)
13788 alc662_eeepc_ep20_automute(codec);
13789}
13790
13791static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13792{
13793 alc662_eeepc_ep20_automute(codec);
13794}
13795
6dda9f4a
KY
13796static void alc663_m51va_speaker_automute(struct hda_codec *codec)
13797{
13798 unsigned int present;
13799 unsigned char bits;
13800
13801 present = snd_hda_codec_read(codec, 0x21, 0,
13802 AC_VERB_GET_PIN_SENSE, 0)
13803 & AC_PINSENSE_PRESENCE;
13804 bits = present ? HDA_AMP_MUTE : 0;
13805 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13806 HDA_AMP_MUTE, bits);
13807}
13808
13809static void alc663_m51va_mic_automute(struct hda_codec *codec)
13810{
13811 unsigned int present;
13812
13813 present = snd_hda_codec_read(codec, 0x18, 0,
13814 AC_VERB_GET_PIN_SENSE, 0)
13815 & AC_PINSENSE_PRESENCE;
13816 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13817 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13818 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13819 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13820 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13821 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
13822 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13823 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
13824}
13825
13826static void alc663_m51va_unsol_event(struct hda_codec *codec,
13827 unsigned int res)
13828{
13829 switch (res >> 26) {
13830 case ALC880_HP_EVENT:
13831 alc663_m51va_speaker_automute(codec);
13832 break;
13833 case ALC880_MIC_EVENT:
13834 alc663_m51va_mic_automute(codec);
13835 break;
13836 }
13837}
13838
13839static void alc663_m51va_inithook(struct hda_codec *codec)
13840{
13841 alc663_m51va_speaker_automute(codec);
13842 alc663_m51va_mic_automute(codec);
13843}
13844
13845static void alc663_g71v_hp_automute(struct hda_codec *codec)
13846{
13847 unsigned int present;
13848 unsigned char bits;
13849
13850 present = snd_hda_codec_read(codec, 0x21, 0,
13851 AC_VERB_GET_PIN_SENSE, 0)
13852 & AC_PINSENSE_PRESENCE;
13853 bits = present ? HDA_AMP_MUTE : 0;
13854 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13855 HDA_AMP_MUTE, bits);
13856 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13857 HDA_AMP_MUTE, bits);
13858}
13859
13860static void alc663_g71v_front_automute(struct hda_codec *codec)
13861{
13862 unsigned int present;
13863 unsigned char bits;
13864
13865 present = snd_hda_codec_read(codec, 0x15, 0,
13866 AC_VERB_GET_PIN_SENSE, 0)
13867 & AC_PINSENSE_PRESENCE;
13868 bits = present ? HDA_AMP_MUTE : 0;
13869 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13870 HDA_AMP_MUTE, bits);
13871}
13872
13873static void alc663_g71v_unsol_event(struct hda_codec *codec,
13874 unsigned int res)
13875{
13876 switch (res >> 26) {
13877 case ALC880_HP_EVENT:
13878 alc663_g71v_hp_automute(codec);
13879 break;
13880 case ALC880_FRONT_EVENT:
13881 alc663_g71v_front_automute(codec);
13882 break;
13883 case ALC880_MIC_EVENT:
13884 alc662_eeepc_mic_automute(codec);
13885 break;
13886 }
13887}
13888
13889static void alc663_g71v_inithook(struct hda_codec *codec)
13890{
13891 alc663_g71v_front_automute(codec);
13892 alc663_g71v_hp_automute(codec);
13893 alc662_eeepc_mic_automute(codec);
13894}
13895
13896static void alc663_g50v_unsol_event(struct hda_codec *codec,
13897 unsigned int res)
13898{
13899 switch (res >> 26) {
13900 case ALC880_HP_EVENT:
13901 alc663_m51va_speaker_automute(codec);
13902 break;
13903 case ALC880_MIC_EVENT:
13904 alc662_eeepc_mic_automute(codec);
13905 break;
13906 }
13907}
13908
13909static void alc663_g50v_inithook(struct hda_codec *codec)
13910{
13911 alc663_m51va_speaker_automute(codec);
13912 alc662_eeepc_mic_automute(codec);
13913}
13914
cb53c626
TI
13915#ifdef CONFIG_SND_HDA_POWER_SAVE
13916#define alc662_loopbacks alc880_loopbacks
13917#endif
13918
bc9f98a9
KY
13919
13920/* pcm configuration: identiacal with ALC880 */
13921#define alc662_pcm_analog_playback alc880_pcm_analog_playback
13922#define alc662_pcm_analog_capture alc880_pcm_analog_capture
13923#define alc662_pcm_digital_playback alc880_pcm_digital_playback
13924#define alc662_pcm_digital_capture alc880_pcm_digital_capture
13925
13926/*
13927 * configuration and preset
13928 */
13929static const char *alc662_models[ALC662_MODEL_LAST] = {
13930 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13931 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13932 [ALC662_3ST_6ch] = "3stack-6ch",
13933 [ALC662_5ST_DIG] = "6stack-dig",
13934 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 13935 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 13936 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
6dda9f4a
KY
13937 [ALC663_ASUS_M51VA] = "m51va",
13938 [ALC663_ASUS_G71V] = "g71v",
13939 [ALC663_ASUS_H13] = "h13",
13940 [ALC663_ASUS_G50V] = "g50v",
bc9f98a9
KY
13941 [ALC662_AUTO] = "auto",
13942};
13943
13944static struct snd_pci_quirk alc662_cfg_tbl[] = {
6dda9f4a
KY
13945 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
13946 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
13947 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
3da23cac 13948 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
291702f0 13949 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 13950 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
ac3e3741 13951 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
6dda9f4a
KY
13952 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
13953 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
13954 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
bc9f98a9
KY
13955 {}
13956};
13957
13958static struct alc_config_preset alc662_presets[] = {
13959 [ALC662_3ST_2ch_DIG] = {
291702f0 13960 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
13961 .init_verbs = { alc662_init_verbs },
13962 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13963 .dac_nids = alc662_dac_nids,
13964 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13965 .dig_in_nid = ALC662_DIGIN_NID,
13966 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13967 .channel_mode = alc662_3ST_2ch_modes,
13968 .input_mux = &alc662_capture_source,
13969 },
13970 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
13971 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13972 alc662_capture_mixer },
bc9f98a9
KY
13973 .init_verbs = { alc662_init_verbs },
13974 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13975 .dac_nids = alc662_dac_nids,
13976 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13977 .dig_in_nid = ALC662_DIGIN_NID,
13978 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13979 .channel_mode = alc662_3ST_6ch_modes,
13980 .need_dac_fix = 1,
13981 .input_mux = &alc662_capture_source,
f12ab1e0 13982 },
bc9f98a9 13983 [ALC662_3ST_6ch] = {
291702f0
KY
13984 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13985 alc662_capture_mixer },
bc9f98a9
KY
13986 .init_verbs = { alc662_init_verbs },
13987 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13988 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13989 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13990 .channel_mode = alc662_3ST_6ch_modes,
13991 .need_dac_fix = 1,
13992 .input_mux = &alc662_capture_source,
f12ab1e0 13993 },
bc9f98a9 13994 [ALC662_5ST_DIG] = {
291702f0
KY
13995 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13996 alc662_capture_mixer },
bc9f98a9
KY
13997 .init_verbs = { alc662_init_verbs },
13998 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13999 .dac_nids = alc662_dac_nids,
14000 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
14001 .dig_in_nid = ALC662_DIGIN_NID,
14002 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
14003 .channel_mode = alc662_5stack_modes,
14004 .input_mux = &alc662_capture_source,
14005 },
14006 [ALC662_LENOVO_101E] = {
291702f0 14007 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
14008 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
14009 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14010 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
14011 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14012 .channel_mode = alc662_3ST_2ch_modes,
14013 .input_mux = &alc662_lenovo_101e_capture_source,
14014 .unsol_event = alc662_lenovo_101e_unsol_event,
14015 .init_hook = alc662_lenovo_101e_all_automute,
14016 },
291702f0
KY
14017 [ALC662_ASUS_EEEPC_P701] = {
14018 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
14019 .init_verbs = { alc662_init_verbs,
14020 alc662_eeepc_sue_init_verbs },
14021 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14022 .dac_nids = alc662_dac_nids,
291702f0
KY
14023 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14024 .channel_mode = alc662_3ST_2ch_modes,
14025 .input_mux = &alc662_eeepc_capture_source,
14026 .unsol_event = alc662_eeepc_unsol_event,
14027 .init_hook = alc662_eeepc_inithook,
14028 },
8c427226
KY
14029 [ALC662_ASUS_EEEPC_EP20] = {
14030 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
14031 alc662_chmode_mixer },
14032 .init_verbs = { alc662_init_verbs,
14033 alc662_eeepc_ep20_sue_init_verbs },
14034 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14035 .dac_nids = alc662_dac_nids,
8c427226
KY
14036 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14037 .channel_mode = alc662_3ST_6ch_modes,
14038 .input_mux = &alc662_lenovo_101e_capture_source,
14039 .unsol_event = alc662_eeepc_ep20_unsol_event,
14040 .init_hook = alc662_eeepc_ep20_inithook,
14041 },
6dda9f4a
KY
14042 [ALC663_ASUS_M51VA] = {
14043 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14044 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14045 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14046 .dac_nids = alc662_dac_nids,
14047 .dig_out_nid = ALC662_DIGOUT_NID,
14048 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14049 .channel_mode = alc662_3ST_2ch_modes,
14050 .input_mux = &alc663_m51va_capture_source,
14051 .unsol_event = alc663_m51va_unsol_event,
14052 .init_hook = alc663_m51va_inithook,
14053 },
14054 [ALC663_ASUS_G71V] = {
14055 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
14056 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
14057 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14058 .dac_nids = alc662_dac_nids,
14059 .dig_out_nid = ALC662_DIGOUT_NID,
14060 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14061 .channel_mode = alc662_3ST_2ch_modes,
14062 .input_mux = &alc662_eeepc_capture_source,
14063 .unsol_event = alc663_g71v_unsol_event,
14064 .init_hook = alc663_g71v_inithook,
14065 },
14066 [ALC663_ASUS_H13] = {
14067 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14068 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14069 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14070 .dac_nids = alc662_dac_nids,
14071 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14072 .channel_mode = alc662_3ST_2ch_modes,
14073 .input_mux = &alc663_m51va_capture_source,
14074 .unsol_event = alc663_m51va_unsol_event,
14075 .init_hook = alc663_m51va_inithook,
14076 },
14077 [ALC663_ASUS_G50V] = {
14078 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
14079 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
14080 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
14081 .dac_nids = alc662_dac_nids,
14082 .dig_out_nid = ALC662_DIGOUT_NID,
14083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14084 .channel_mode = alc662_3ST_6ch_modes,
14085 .input_mux = &alc663_capture_source,
14086 .unsol_event = alc663_g50v_unsol_event,
14087 .init_hook = alc663_g50v_inithook,
14088 },
bc9f98a9
KY
14089};
14090
14091
14092/*
14093 * BIOS auto configuration
14094 */
14095
14096/* add playback controls from the parsed DAC table */
14097static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
14098 const struct auto_pin_cfg *cfg)
14099{
14100 char name[32];
14101 static const char *chname[4] = {
14102 "Front", "Surround", NULL /*CLFE*/, "Side"
14103 };
14104 hda_nid_t nid;
14105 int i, err;
14106
14107 for (i = 0; i < cfg->line_outs; i++) {
14108 if (!spec->multiout.dac_nids[i])
14109 continue;
b60dd394 14110 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
14111 if (i == 2) {
14112 /* Center/LFE */
14113 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14114 "Center Playback Volume",
f12ab1e0
TI
14115 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14116 HDA_OUTPUT));
bc9f98a9
KY
14117 if (err < 0)
14118 return err;
14119 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14120 "LFE Playback Volume",
f12ab1e0
TI
14121 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14122 HDA_OUTPUT));
bc9f98a9
KY
14123 if (err < 0)
14124 return err;
14125 err = add_control(spec, ALC_CTL_BIND_MUTE,
14126 "Center Playback Switch",
f12ab1e0
TI
14127 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
14128 HDA_INPUT));
bc9f98a9
KY
14129 if (err < 0)
14130 return err;
14131 err = add_control(spec, ALC_CTL_BIND_MUTE,
14132 "LFE Playback Switch",
f12ab1e0
TI
14133 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
14134 HDA_INPUT));
bc9f98a9
KY
14135 if (err < 0)
14136 return err;
14137 } else {
14138 sprintf(name, "%s Playback Volume", chname[i]);
14139 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
14140 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14141 HDA_OUTPUT));
bc9f98a9
KY
14142 if (err < 0)
14143 return err;
14144 sprintf(name, "%s Playback Switch", chname[i]);
14145 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
14146 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
14147 HDA_INPUT));
bc9f98a9
KY
14148 if (err < 0)
14149 return err;
14150 }
14151 }
14152 return 0;
14153}
14154
14155/* add playback controls for speaker and HP outputs */
14156static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
14157 const char *pfx)
14158{
14159 hda_nid_t nid;
14160 int err;
14161 char name[32];
14162
14163 if (!pin)
14164 return 0;
14165
14166 if (alc880_is_fixed_pin(pin)) {
14167 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14168 /* printk("DAC nid=%x\n",nid); */
14169 /* specify the DAC as the extra output */
14170 if (!spec->multiout.hp_nid)
14171 spec->multiout.hp_nid = nid;
14172 else
14173 spec->multiout.extra_out_nid[0] = nid;
14174 /* control HP volume/switch on the output mixer amp */
14175 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14176 sprintf(name, "%s Playback Volume", pfx);
14177 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14178 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
14179 if (err < 0)
14180 return err;
14181 sprintf(name, "%s Playback Switch", pfx);
14182 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14183 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
14184 if (err < 0)
14185 return err;
14186 } else if (alc880_is_multi_pin(pin)) {
14187 /* set manual connection */
14188 /* we have only a switch on HP-out PIN */
14189 sprintf(name, "%s Playback Switch", pfx);
14190 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14191 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14192 if (err < 0)
14193 return err;
14194 }
14195 return 0;
14196}
14197
14198/* create playback/capture controls for input pins */
14199static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
14200 const struct auto_pin_cfg *cfg)
14201{
14202 struct hda_input_mux *imux = &spec->private_imux;
14203 int i, err, idx;
14204
14205 for (i = 0; i < AUTO_PIN_LAST; i++) {
14206 if (alc880_is_input_pin(cfg->input_pins[i])) {
14207 idx = alc880_input_pin_idx(cfg->input_pins[i]);
14208 err = new_analog_input(spec, cfg->input_pins[i],
14209 auto_pin_cfg_labels[i],
14210 idx, 0x0b);
14211 if (err < 0)
14212 return err;
14213 imux->items[imux->num_items].label =
14214 auto_pin_cfg_labels[i];
14215 imux->items[imux->num_items].index =
14216 alc880_input_pin_idx(cfg->input_pins[i]);
14217 imux->num_items++;
14218 }
14219 }
14220 return 0;
14221}
14222
14223static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
14224 hda_nid_t nid, int pin_type,
14225 int dac_idx)
14226{
f6c7e546 14227 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
14228 /* need the manual connection? */
14229 if (alc880_is_multi_pin(nid)) {
14230 struct alc_spec *spec = codec->spec;
14231 int idx = alc880_multi_pin_idx(nid);
14232 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
14233 AC_VERB_SET_CONNECT_SEL,
14234 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
14235 }
14236}
14237
14238static void alc662_auto_init_multi_out(struct hda_codec *codec)
14239{
14240 struct alc_spec *spec = codec->spec;
14241 int i;
14242
8c427226 14243 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
14244 for (i = 0; i <= HDA_SIDE; i++) {
14245 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14246 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 14247 if (nid)
baba8ee9 14248 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
14249 i);
14250 }
14251}
14252
14253static void alc662_auto_init_hp_out(struct hda_codec *codec)
14254{
14255 struct alc_spec *spec = codec->spec;
14256 hda_nid_t pin;
14257
14258 pin = spec->autocfg.hp_pins[0];
14259 if (pin) /* connect to front */
14260 /* use dac 0 */
14261 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14262 pin = spec->autocfg.speaker_pins[0];
14263 if (pin)
14264 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
14265}
14266
14267#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
14268#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
14269
14270static void alc662_auto_init_analog_input(struct hda_codec *codec)
14271{
14272 struct alc_spec *spec = codec->spec;
14273 int i;
14274
14275 for (i = 0; i < AUTO_PIN_LAST; i++) {
14276 hda_nid_t nid = spec->autocfg.input_pins[i];
14277 if (alc662_is_input_pin(nid)) {
14278 snd_hda_codec_write(codec, nid, 0,
14279 AC_VERB_SET_PIN_WIDGET_CONTROL,
14280 (i <= AUTO_PIN_FRONT_MIC ?
14281 PIN_VREF80 : PIN_IN));
14282 if (nid != ALC662_PIN_CD_NID)
14283 snd_hda_codec_write(codec, nid, 0,
14284 AC_VERB_SET_AMP_GAIN_MUTE,
14285 AMP_OUT_MUTE);
14286 }
14287 }
14288}
14289
14290static int alc662_parse_auto_config(struct hda_codec *codec)
14291{
14292 struct alc_spec *spec = codec->spec;
14293 int err;
14294 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
14295
14296 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14297 alc662_ignore);
14298 if (err < 0)
14299 return err;
14300 if (!spec->autocfg.line_outs)
14301 return 0; /* can't find valid BIOS pin config */
14302
f12ab1e0
TI
14303 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14304 if (err < 0)
14305 return err;
14306 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
14307 if (err < 0)
14308 return err;
14309 err = alc662_auto_create_extra_out(spec,
14310 spec->autocfg.speaker_pins[0],
14311 "Speaker");
14312 if (err < 0)
14313 return err;
14314 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
14315 "Headphone");
14316 if (err < 0)
14317 return err;
14318 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
14319 if (err < 0)
bc9f98a9
KY
14320 return err;
14321
14322 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14323
14324 if (spec->autocfg.dig_out_pin)
14325 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
14326
14327 if (spec->kctl_alloc)
14328 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14329
14330 spec->num_mux_defs = 1;
14331 spec->input_mux = &spec->private_imux;
14332
8c87286f 14333 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
14334 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
14335 spec->num_mixers++;
8c87286f 14336 return 1;
bc9f98a9
KY
14337}
14338
14339/* additional initialization for auto-configuration model */
14340static void alc662_auto_init(struct hda_codec *codec)
14341{
f6c7e546 14342 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
14343 alc662_auto_init_multi_out(codec);
14344 alc662_auto_init_hp_out(codec);
14345 alc662_auto_init_analog_input(codec);
f6c7e546
TI
14346 if (spec->unsol_event)
14347 alc_sku_automute(codec);
bc9f98a9
KY
14348}
14349
14350static int patch_alc662(struct hda_codec *codec)
14351{
14352 struct alc_spec *spec;
14353 int err, board_config;
14354
14355 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14356 if (!spec)
14357 return -ENOMEM;
14358
14359 codec->spec = spec;
14360
14361 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
14362 alc662_models,
14363 alc662_cfg_tbl);
14364 if (board_config < 0) {
14365 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
14366 "trying auto-probe from BIOS...\n");
14367 board_config = ALC662_AUTO;
14368 }
14369
14370 if (board_config == ALC662_AUTO) {
14371 /* automatic parse from the BIOS config */
14372 err = alc662_parse_auto_config(codec);
14373 if (err < 0) {
14374 alc_free(codec);
14375 return err;
8c87286f 14376 } else if (!err) {
bc9f98a9
KY
14377 printk(KERN_INFO
14378 "hda_codec: Cannot set up configuration "
14379 "from BIOS. Using base mode...\n");
14380 board_config = ALC662_3ST_2ch_DIG;
14381 }
14382 }
14383
14384 if (board_config != ALC662_AUTO)
14385 setup_preset(spec, &alc662_presets[board_config]);
14386
6dda9f4a
KY
14387 if (codec->vendor_id == 0x10ec0663) {
14388 spec->stream_name_analog = "ALC663 Analog";
14389 spec->stream_name_digital = "ALC663 Digital";
14390 } else {
14391 spec->stream_name_analog = "ALC662 Analog";
14392 spec->stream_name_digital = "ALC662 Digital";
14393 }
14394
bc9f98a9
KY
14395 spec->stream_analog_playback = &alc662_pcm_analog_playback;
14396 spec->stream_analog_capture = &alc662_pcm_analog_capture;
14397
bc9f98a9
KY
14398 spec->stream_digital_playback = &alc662_pcm_digital_playback;
14399 spec->stream_digital_capture = &alc662_pcm_digital_capture;
14400
e1406348
TI
14401 spec->adc_nids = alc662_adc_nids;
14402 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
14403 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 14404
2134ea4f
TI
14405 spec->vmaster_nid = 0x02;
14406
bc9f98a9
KY
14407 codec->patch_ops = alc_patch_ops;
14408 if (board_config == ALC662_AUTO)
14409 spec->init_hook = alc662_auto_init;
cb53c626
TI
14410#ifdef CONFIG_SND_HDA_POWER_SAVE
14411 if (!spec->loopback.amplist)
14412 spec->loopback.amplist = alc662_loopbacks;
14413#endif
bc9f98a9
KY
14414
14415 return 0;
14416}
14417
1da177e4
LT
14418/*
14419 * patch entries
14420 */
14421struct hda_codec_preset snd_hda_preset_realtek[] = {
14422 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 14423 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 14424 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 14425 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 14426 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 14427 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 14428 .patch = patch_alc861 },
f32610ed
JS
14429 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
14430 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
14431 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
14432 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
14433 .patch = patch_alc883 },
14434 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
14435 .patch = patch_alc662 },
6dda9f4a 14436 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 14437 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 14438 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 14439 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
cb308f97 14440 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 14441 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 14442 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 14443 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 14444 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
14445 {} /* terminator */
14446};