]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] rawmidi: let sparse know what is going on _for real_
[mirror_ubuntu-artful-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"
33
ccc656ce
KY
34#define ALC880_FRONT_EVENT 0x01
35#define ALC880_DCVOL_EVENT 0x02
36#define ALC880_HP_EVENT 0x04
37#define ALC880_MIC_EVENT 0x08
1da177e4
LT
38
39/* ALC880 board config type */
40enum {
1da177e4
LT
41 ALC880_3ST,
42 ALC880_3ST_DIG,
43 ALC880_5ST,
44 ALC880_5ST_DIG,
45 ALC880_W810,
dfc0ff62 46 ALC880_Z71V,
b6482d48 47 ALC880_6ST,
16ded525
TI
48 ALC880_6ST_DIG,
49 ALC880_F1734,
50 ALC880_ASUS,
51 ALC880_ASUS_DIG,
52 ALC880_ASUS_W1V,
df694daa 53 ALC880_ASUS_DIG2,
2cf9f0fc 54 ALC880_FUJITSU,
16ded525 55 ALC880_UNIWILL_DIG,
ccc656ce
KY
56 ALC880_UNIWILL,
57 ALC880_UNIWILL_P53,
df694daa
KY
58 ALC880_CLEVO,
59 ALC880_TCL_S700,
ae6b813a 60 ALC880_LG,
d681518a 61 ALC880_LG_LW,
e9edcee0
TI
62#ifdef CONFIG_SND_DEBUG
63 ALC880_TEST,
64#endif
df694daa 65 ALC880_AUTO,
16ded525
TI
66 ALC880_MODEL_LAST /* last tag */
67};
68
69/* ALC260 models */
70enum {
71 ALC260_BASIC,
72 ALC260_HP,
df694daa
KY
73 ALC260_HP_3013,
74 ALC260_FUJITSU_S702X,
0bfc90e9 75 ALC260_ACER,
bc9f98a9
KY
76 ALC260_WILL,
77 ALC260_REPLACER_672V,
7cf51e48
JW
78#ifdef CONFIG_SND_DEBUG
79 ALC260_TEST,
80#endif
df694daa 81 ALC260_AUTO,
16ded525 82 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
83};
84
df694daa
KY
85/* ALC262 models */
86enum {
87 ALC262_BASIC,
ccc656ce
KY
88 ALC262_HIPPO,
89 ALC262_HIPPO_1,
834be88d 90 ALC262_FUJITSU,
9c7f852e 91 ALC262_HP_BPC,
cd7509a4
KY
92 ALC262_HP_BPC_D7000_WL,
93 ALC262_HP_BPC_D7000_WF,
66d2a9d6 94 ALC262_HP_TC_T5735,
304dcaac 95 ALC262_BENQ_ED8,
272a527c 96 ALC262_SONY_ASSAMD,
83c34218 97 ALC262_BENQ_T31,
f651b50b 98 ALC262_ULTRA,
df694daa
KY
99 ALC262_AUTO,
100 ALC262_MODEL_LAST /* last tag */
101};
102
a361d84b
KY
103/* ALC268 models */
104enum {
105 ALC268_3ST,
d1a991a6 106 ALC268_TOSHIBA,
d273809e 107 ALC268_ACER,
86c53bd2
JW
108#ifdef CONFIG_SND_DEBUG
109 ALC268_TEST,
110#endif
a361d84b
KY
111 ALC268_AUTO,
112 ALC268_MODEL_LAST /* last tag */
113};
114
f6a92248
KY
115/* ALC269 models */
116enum {
117 ALC269_BASIC,
118 ALC269_AUTO,
119 ALC269_MODEL_LAST /* last tag */
120};
121
df694daa
KY
122/* ALC861 models */
123enum {
124 ALC861_3ST,
9c7f852e 125 ALC660_3ST,
df694daa
KY
126 ALC861_3ST_DIG,
127 ALC861_6ST_DIG,
22309c3e 128 ALC861_UNIWILL_M31,
a53d1aec 129 ALC861_TOSHIBA,
7cdbff94 130 ALC861_ASUS,
56bb0cab 131 ALC861_ASUS_LAPTOP,
df694daa
KY
132 ALC861_AUTO,
133 ALC861_MODEL_LAST,
134};
135
f32610ed
JS
136/* ALC861-VD models */
137enum {
138 ALC660VD_3ST,
6963f84c 139 ALC660VD_3ST_DIG,
f32610ed
JS
140 ALC861VD_3ST,
141 ALC861VD_3ST_DIG,
142 ALC861VD_6ST_DIG,
bdd148a3 143 ALC861VD_LENOVO,
272a527c 144 ALC861VD_DALLAS,
d1a991a6 145 ALC861VD_HP,
f32610ed
JS
146 ALC861VD_AUTO,
147 ALC861VD_MODEL_LAST,
148};
149
bc9f98a9
KY
150/* ALC662 models */
151enum {
152 ALC662_3ST_2ch_DIG,
153 ALC662_3ST_6ch_DIG,
154 ALC662_3ST_6ch,
155 ALC662_5ST_DIG,
156 ALC662_LENOVO_101E,
291702f0 157 ALC662_ASUS_EEEPC_P701,
bc9f98a9
KY
158 ALC662_AUTO,
159 ALC662_MODEL_LAST,
160};
161
df694daa
KY
162/* ALC882 models */
163enum {
164 ALC882_3ST_DIG,
165 ALC882_6ST_DIG,
4b146cb0 166 ALC882_ARIMA,
bdd148a3 167 ALC882_W2JC,
272a527c
KY
168 ALC882_TARGA,
169 ALC882_ASUS_A7J,
914759b7 170 ALC882_ASUS_A7M,
9102cd1c 171 ALC885_MACPRO,
87350ad0 172 ALC885_MBP3,
c54728d8 173 ALC885_IMAC24,
272a527c 174 ALC882_AUTO,
df694daa
KY
175 ALC882_MODEL_LAST,
176};
177
9c7f852e
TI
178/* ALC883 models */
179enum {
180 ALC883_3ST_2ch_DIG,
181 ALC883_3ST_6ch_DIG,
182 ALC883_3ST_6ch,
183 ALC883_6ST_DIG,
ccc656ce
KY
184 ALC883_TARGA_DIG,
185 ALC883_TARGA_2ch_DIG,
bab282b9 186 ALC883_ACER,
2880a867 187 ALC883_ACER_ASPIRE,
c07584c8 188 ALC883_MEDION,
272a527c 189 ALC883_MEDION_MD2,
b373bdeb 190 ALC883_LAPTOP_EAPD,
bc9f98a9 191 ALC883_LENOVO_101E_2ch,
272a527c 192 ALC883_LENOVO_NB0763,
189609ae
KY
193 ALC888_LENOVO_MS7195_DIG,
194 ALC883_HAIER_W66,
4723c022
CM
195 ALC888_6ST_HP,
196 ALC888_3ST_HP,
a8848bd6 197 ALC883_MITAC,
9c7f852e
TI
198 ALC883_AUTO,
199 ALC883_MODEL_LAST,
200};
201
df694daa
KY
202/* for GPIO Poll */
203#define GPIO_MASK 0x03
204
1da177e4
LT
205struct alc_spec {
206 /* codec parameterization */
df694daa 207 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
208 unsigned int num_mixers;
209
df694daa 210 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
211 * don't forget NULL
212 * termination!
e9edcee0
TI
213 */
214 unsigned int num_init_verbs;
1da177e4 215
16ded525 216 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
217 struct hda_pcm_stream *stream_analog_playback;
218 struct hda_pcm_stream *stream_analog_capture;
219
f12ab1e0 220 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
221 struct hda_pcm_stream *stream_digital_playback;
222 struct hda_pcm_stream *stream_digital_capture;
223
224 /* playback */
16ded525
TI
225 struct hda_multi_out multiout; /* playback set-up
226 * max_channels, dacs must be set
227 * dig_out_nid and hp_nid are optional
228 */
1da177e4
LT
229
230 /* capture */
231 unsigned int num_adc_nids;
232 hda_nid_t *adc_nids;
16ded525 233 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
234
235 /* capture source */
a1e8d2da 236 unsigned int num_mux_defs;
1da177e4
LT
237 const struct hda_input_mux *input_mux;
238 unsigned int cur_mux[3];
239
240 /* channel model */
d2a6d7dc 241 const struct hda_channel_mode *channel_mode;
1da177e4 242 int num_channel_mode;
4e195a7b 243 int need_dac_fix;
1da177e4
LT
244
245 /* PCM information */
4c5186ed 246 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 247
e9edcee0
TI
248 /* dynamic controls, init_verbs and input_mux */
249 struct auto_pin_cfg autocfg;
250 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 251 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 252 struct hda_input_mux private_imux;
41923e44 253 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 254
ae6b813a
TI
255 /* hooks */
256 void (*init_hook)(struct hda_codec *codec);
257 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
258
834be88d
TI
259 /* for pin sensing */
260 unsigned int sense_updated: 1;
261 unsigned int jack_present: 1;
cb53c626
TI
262
263#ifdef CONFIG_SND_HDA_POWER_SAVE
264 struct hda_loopback_check loopback;
265#endif
df694daa
KY
266};
267
268/*
269 * configuration template - to be copied to the spec instance
270 */
271struct alc_config_preset {
9c7f852e
TI
272 struct snd_kcontrol_new *mixers[5]; /* should be identical size
273 * with spec
274 */
df694daa
KY
275 const struct hda_verb *init_verbs[5];
276 unsigned int num_dacs;
277 hda_nid_t *dac_nids;
278 hda_nid_t dig_out_nid; /* optional */
279 hda_nid_t hp_nid; /* optional */
280 unsigned int num_adc_nids;
281 hda_nid_t *adc_nids;
282 hda_nid_t dig_in_nid;
283 unsigned int num_channel_mode;
284 const struct hda_channel_mode *channel_mode;
4e195a7b 285 int need_dac_fix;
a1e8d2da 286 unsigned int num_mux_defs;
df694daa 287 const struct hda_input_mux *input_mux;
ae6b813a
TI
288 void (*unsol_event)(struct hda_codec *, unsigned int);
289 void (*init_hook)(struct hda_codec *);
cb53c626
TI
290#ifdef CONFIG_SND_HDA_POWER_SAVE
291 struct hda_amp_list *loopbacks;
292#endif
1da177e4
LT
293};
294
1da177e4
LT
295
296/*
297 * input MUX handling
298 */
9c7f852e
TI
299static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
300 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
301{
302 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
303 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
304 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
305 if (mux_idx >= spec->num_mux_defs)
306 mux_idx = 0;
307 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
308}
309
9c7f852e
TI
310static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
311 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
312{
313 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
314 struct alc_spec *spec = codec->spec;
315 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
316
317 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
318 return 0;
319}
320
9c7f852e
TI
321static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
323{
324 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
325 struct alc_spec *spec = codec->spec;
326 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da
JW
327 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
328 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
9c7f852e
TI
329 spec->adc_nids[adc_idx],
330 &spec->cur_mux[adc_idx]);
1da177e4
LT
331}
332
e9edcee0 333
1da177e4
LT
334/*
335 * channel mode setting
336 */
9c7f852e
TI
337static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
338 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
339{
340 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
341 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
342 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
343 spec->num_channel_mode);
1da177e4
LT
344}
345
9c7f852e
TI
346static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
347 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
348{
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 struct alc_spec *spec = codec->spec;
d2a6d7dc 351 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
352 spec->num_channel_mode,
353 spec->multiout.max_channels);
1da177e4
LT
354}
355
9c7f852e
TI
356static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
357 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
358{
359 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
360 struct alc_spec *spec = codec->spec;
4e195a7b
TI
361 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
362 spec->num_channel_mode,
363 &spec->multiout.max_channels);
bd2033f2 364 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
365 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
366 return err;
1da177e4
LT
367}
368
a9430dd8 369/*
4c5186ed
JW
370 * Control the mode of pin widget settings via the mixer. "pc" is used
371 * instead of "%" to avoid consequences of accidently treating the % as
372 * being part of a format specifier. Maximum allowed length of a value is
373 * 63 characters plus NULL terminator.
7cf51e48
JW
374 *
375 * Note: some retasking pin complexes seem to ignore requests for input
376 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
377 * are requested. Therefore order this list so that this behaviour will not
378 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
379 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
380 * March 2006.
4c5186ed
JW
381 */
382static char *alc_pin_mode_names[] = {
7cf51e48
JW
383 "Mic 50pc bias", "Mic 80pc bias",
384 "Line in", "Line out", "Headphone out",
4c5186ed
JW
385};
386static unsigned char alc_pin_mode_values[] = {
7cf51e48 387 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
388};
389/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
390 * in the pin being assumed to be exclusively an input or an output pin. In
391 * addition, "input" pins may or may not process the mic bias option
392 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
393 * accept requests for bias as of chip versions up to March 2006) and/or
394 * wiring in the computer.
a9430dd8 395 */
a1e8d2da
JW
396#define ALC_PIN_DIR_IN 0x00
397#define ALC_PIN_DIR_OUT 0x01
398#define ALC_PIN_DIR_INOUT 0x02
399#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
400#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 401
a1e8d2da 402/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
403 * For each direction the minimum and maximum values are given.
404 */
a1e8d2da 405static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
406 { 0, 2 }, /* ALC_PIN_DIR_IN */
407 { 3, 4 }, /* ALC_PIN_DIR_OUT */
408 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
409 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
410 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
411};
412#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
413#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
414#define alc_pin_mode_n_items(_dir) \
415 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
416
9c7f852e
TI
417static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_info *uinfo)
a9430dd8 419{
4c5186ed
JW
420 unsigned int item_num = uinfo->value.enumerated.item;
421 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
422
423 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 424 uinfo->count = 1;
4c5186ed
JW
425 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
426
427 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
428 item_num = alc_pin_mode_min(dir);
429 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
430 return 0;
431}
432
9c7f852e
TI
433static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
434 struct snd_ctl_elem_value *ucontrol)
a9430dd8 435{
4c5186ed 436 unsigned int i;
a9430dd8
JW
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 439 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 440 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
441 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
442 AC_VERB_GET_PIN_WIDGET_CONTROL,
443 0x00);
a9430dd8 444
4c5186ed
JW
445 /* Find enumerated value for current pinctl setting */
446 i = alc_pin_mode_min(dir);
9c7f852e 447 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 448 i++;
9c7f852e 449 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
450 return 0;
451}
452
9c7f852e
TI
453static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
a9430dd8 455{
4c5186ed 456 signed int change;
a9430dd8
JW
457 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
458 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
459 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
460 long val = *ucontrol->value.integer.value;
9c7f852e
TI
461 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
462 AC_VERB_GET_PIN_WIDGET_CONTROL,
463 0x00);
a9430dd8 464
f12ab1e0 465 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
466 val = alc_pin_mode_min(dir);
467
468 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
469 if (change) {
470 /* Set pin mode to that requested */
82beb8fd
TI
471 snd_hda_codec_write_cache(codec, nid, 0,
472 AC_VERB_SET_PIN_WIDGET_CONTROL,
473 alc_pin_mode_values[val]);
cdcd9268
JW
474
475 /* Also enable the retasking pin's input/output as required
476 * for the requested pin mode. Enum values of 2 or less are
477 * input modes.
478 *
479 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
480 * reduces noise slightly (particularly on input) so we'll
481 * do it. However, having both input and output buffers
482 * enabled simultaneously doesn't seem to be problematic if
483 * this turns out to be necessary in the future.
cdcd9268
JW
484 */
485 if (val <= 2) {
47fd830a
TI
486 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
487 HDA_AMP_MUTE, HDA_AMP_MUTE);
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
489 HDA_AMP_MUTE, 0);
cdcd9268 490 } else {
47fd830a
TI
491 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
492 HDA_AMP_MUTE, HDA_AMP_MUTE);
493 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
494 HDA_AMP_MUTE, 0);
cdcd9268
JW
495 }
496 }
a9430dd8
JW
497 return change;
498}
499
4c5186ed 500#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 501 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
502 .info = alc_pin_mode_info, \
503 .get = alc_pin_mode_get, \
504 .put = alc_pin_mode_put, \
505 .private_value = nid | (dir<<16) }
df694daa 506
5c8f858d
JW
507/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
508 * together using a mask with more than one bit set. This control is
509 * currently used only by the ALC260 test model. At this stage they are not
510 * needed for any "production" models.
511 */
512#ifdef CONFIG_SND_DEBUG
a5ce8890 513#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 514
9c7f852e
TI
515static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
516 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
517{
518 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
519 hda_nid_t nid = kcontrol->private_value & 0xffff;
520 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
521 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
522 unsigned int val = snd_hda_codec_read(codec, nid, 0,
523 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
524
525 *valp = (val & mask) != 0;
526 return 0;
527}
9c7f852e
TI
528static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
530{
531 signed int change;
532 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
533 hda_nid_t nid = kcontrol->private_value & 0xffff;
534 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
535 long val = *ucontrol->value.integer.value;
9c7f852e
TI
536 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
537 AC_VERB_GET_GPIO_DATA,
538 0x00);
5c8f858d
JW
539
540 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
541 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
542 if (val == 0)
5c8f858d
JW
543 gpio_data &= ~mask;
544 else
545 gpio_data |= mask;
82beb8fd
TI
546 snd_hda_codec_write_cache(codec, nid, 0,
547 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
548
549 return change;
550}
551#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
552 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
553 .info = alc_gpio_data_info, \
554 .get = alc_gpio_data_get, \
555 .put = alc_gpio_data_put, \
556 .private_value = nid | (mask<<16) }
557#endif /* CONFIG_SND_DEBUG */
558
92621f13
JW
559/* A switch control to allow the enabling of the digital IO pins on the
560 * ALC260. This is incredibly simplistic; the intention of this control is
561 * to provide something in the test model allowing digital outputs to be
562 * identified if present. If models are found which can utilise these
563 * outputs a more complete mixer control can be devised for those models if
564 * necessary.
565 */
566#ifdef CONFIG_SND_DEBUG
a5ce8890 567#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 568
9c7f852e
TI
569static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
571{
572 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
573 hda_nid_t nid = kcontrol->private_value & 0xffff;
574 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
575 long *valp = ucontrol->value.integer.value;
9c7f852e 576 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 577 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
578
579 *valp = (val & mask) != 0;
580 return 0;
581}
9c7f852e
TI
582static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
584{
585 signed int change;
586 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
587 hda_nid_t nid = kcontrol->private_value & 0xffff;
588 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
589 long val = *ucontrol->value.integer.value;
9c7f852e 590 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 591 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 592 0x00);
92621f13
JW
593
594 /* Set/unset the masked control bit(s) as needed */
9c7f852e 595 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
596 if (val==0)
597 ctrl_data &= ~mask;
598 else
599 ctrl_data |= mask;
82beb8fd
TI
600 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
601 ctrl_data);
92621f13
JW
602
603 return change;
604}
605#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
606 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
607 .info = alc_spdif_ctrl_info, \
608 .get = alc_spdif_ctrl_get, \
609 .put = alc_spdif_ctrl_put, \
610 .private_value = nid | (mask<<16) }
611#endif /* CONFIG_SND_DEBUG */
612
f8225f6d
JW
613/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
614 * Again, this is only used in the ALC26x test models to help identify when
615 * the EAPD line must be asserted for features to work.
616 */
617#ifdef CONFIG_SND_DEBUG
618#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
619
620static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
621 struct snd_ctl_elem_value *ucontrol)
622{
623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
624 hda_nid_t nid = kcontrol->private_value & 0xffff;
625 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
626 long *valp = ucontrol->value.integer.value;
627 unsigned int val = snd_hda_codec_read(codec, nid, 0,
628 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
629
630 *valp = (val & mask) != 0;
631 return 0;
632}
633
634static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
636{
637 int change;
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
640 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
641 long val = *ucontrol->value.integer.value;
642 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
643 AC_VERB_GET_EAPD_BTLENABLE,
644 0x00);
645
646 /* Set/unset the masked control bit(s) as needed */
647 change = (!val ? 0 : mask) != (ctrl_data & mask);
648 if (!val)
649 ctrl_data &= ~mask;
650 else
651 ctrl_data |= mask;
652 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
653 ctrl_data);
654
655 return change;
656}
657
658#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
659 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
660 .info = alc_eapd_ctrl_info, \
661 .get = alc_eapd_ctrl_get, \
662 .put = alc_eapd_ctrl_put, \
663 .private_value = nid | (mask<<16) }
664#endif /* CONFIG_SND_DEBUG */
665
df694daa
KY
666/*
667 * set up from the preset table
668 */
9c7f852e
TI
669static void setup_preset(struct alc_spec *spec,
670 const struct alc_config_preset *preset)
df694daa
KY
671{
672 int i;
673
674 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
675 spec->mixers[spec->num_mixers++] = preset->mixers[i];
9c7f852e
TI
676 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
677 i++)
678 spec->init_verbs[spec->num_init_verbs++] =
679 preset->init_verbs[i];
df694daa
KY
680
681 spec->channel_mode = preset->channel_mode;
682 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 683 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
684
685 spec->multiout.max_channels = spec->channel_mode[0].channels;
686
687 spec->multiout.num_dacs = preset->num_dacs;
688 spec->multiout.dac_nids = preset->dac_nids;
689 spec->multiout.dig_out_nid = preset->dig_out_nid;
690 spec->multiout.hp_nid = preset->hp_nid;
691
a1e8d2da 692 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 693 if (!spec->num_mux_defs)
a1e8d2da 694 spec->num_mux_defs = 1;
df694daa
KY
695 spec->input_mux = preset->input_mux;
696
697 spec->num_adc_nids = preset->num_adc_nids;
698 spec->adc_nids = preset->adc_nids;
699 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
700
701 spec->unsol_event = preset->unsol_event;
702 spec->init_hook = preset->init_hook;
cb53c626
TI
703#ifdef CONFIG_SND_HDA_POWER_SAVE
704 spec->loopback.amplist = preset->loopbacks;
705#endif
df694daa
KY
706}
707
bc9f98a9
KY
708/* Enable GPIO mask and set output */
709static struct hda_verb alc_gpio1_init_verbs[] = {
710 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
711 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
712 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
713 { }
714};
715
716static struct hda_verb alc_gpio2_init_verbs[] = {
717 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
718 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
719 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
720 { }
721};
722
bdd148a3
KY
723static struct hda_verb alc_gpio3_init_verbs[] = {
724 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
725 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
726 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
727 { }
728};
729
c9b58006
KY
730static void alc_sku_automute(struct hda_codec *codec)
731{
732 struct alc_spec *spec = codec->spec;
733 unsigned int mute;
734 unsigned int present;
735 unsigned int hp_nid = spec->autocfg.hp_pins[0];
736 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
737
738 /* need to execute and sync at first */
739 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
740 present = snd_hda_codec_read(codec, hp_nid, 0,
741 AC_VERB_GET_PIN_SENSE, 0);
742 spec->jack_present = (present & 0x80000000) != 0;
743 if (spec->jack_present) {
744 /* mute internal speaker */
745 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
746 HDA_AMP_MUTE, HDA_AMP_MUTE);
747 } else {
748 /* unmute internal speaker if necessary */
749 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
750 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
751 HDA_AMP_MUTE, mute);
752 }
753}
754
755/* unsolicited event for HP jack sensing */
756static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
757{
758 if (codec->vendor_id == 0x10ec0880)
759 res >>= 28;
760 else
761 res >>= 26;
762 if (res != ALC880_HP_EVENT)
763 return;
764
765 alc_sku_automute(codec);
766}
767
bc9f98a9
KY
768/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
769 * 31 ~ 16 : Manufacture ID
770 * 15 ~ 8 : SKU ID
771 * 7 ~ 0 : Assembly ID
772 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
773 */
774static void alc_subsystem_id(struct hda_codec *codec,
775 unsigned int porta, unsigned int porte,
776 unsigned int portd)
777{
c9b58006
KY
778 unsigned int ass, tmp, i;
779 unsigned nid;
780 struct alc_spec *spec = codec->spec;
bc9f98a9 781
c9b58006
KY
782 ass = codec->subsystem_id & 0xffff;
783 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
784 goto do_sku;
785
786 /*
787 * 31~30 : port conetcivity
788 * 29~21 : reserve
789 * 20 : PCBEEP input
790 * 19~16 : Check sum (15:1)
791 * 15~1 : Custom
792 * 0 : override
793 */
794 nid = 0x1d;
795 if (codec->vendor_id == 0x10ec0260)
796 nid = 0x17;
797 ass = snd_hda_codec_read(codec, nid, 0,
798 AC_VERB_GET_CONFIG_DEFAULT, 0);
799 if (!(ass & 1) && !(ass & 0x100000))
800 return;
801 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
802 return;
803
c9b58006
KY
804 /* check sum */
805 tmp = 0;
806 for (i = 1; i < 16; i++) {
807 if ((ass >> i) && 1)
808 tmp++;
809 }
810 if (((ass >> 16) & 0xf) != tmp)
811 return;
812do_sku:
813 /*
814 * 0 : override
815 * 1 : Swap Jack
816 * 2 : 0 --> Desktop, 1 --> Laptop
817 * 3~5 : External Amplifier control
818 * 7~6 : Reserved
819 */
bc9f98a9
KY
820 tmp = (ass & 0x38) >> 3; /* external Amp control */
821 switch (tmp) {
822 case 1:
823 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
824 break;
825 case 3:
826 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
827 break;
bdd148a3
KY
828 case 7:
829 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
830 break;
c9b58006 831 case 5: /* set EAPD output high */
bdd148a3 832 switch (codec->vendor_id) {
c9b58006
KY
833 case 0x10ec0260:
834 snd_hda_codec_write(codec, 0x0f, 0,
835 AC_VERB_SET_EAPD_BTLENABLE, 2);
836 snd_hda_codec_write(codec, 0x10, 0,
837 AC_VERB_SET_EAPD_BTLENABLE, 2);
838 break;
839 case 0x10ec0262:
bdd148a3
KY
840 case 0x10ec0267:
841 case 0x10ec0268:
c9b58006
KY
842 case 0x10ec0269:
843 case 0x10ec0862:
844 case 0x10ec0662:
bdd148a3
KY
845 snd_hda_codec_write(codec, 0x14, 0,
846 AC_VERB_SET_EAPD_BTLENABLE, 2);
847 snd_hda_codec_write(codec, 0x15, 0,
848 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 849 break;
bdd148a3 850 }
c9b58006
KY
851 switch (codec->vendor_id) {
852 case 0x10ec0260:
853 snd_hda_codec_write(codec, 0x1a, 0,
854 AC_VERB_SET_COEF_INDEX, 7);
855 tmp = snd_hda_codec_read(codec, 0x1a, 0,
856 AC_VERB_GET_PROC_COEF, 0);
857 snd_hda_codec_write(codec, 0x1a, 0,
858 AC_VERB_SET_COEF_INDEX, 7);
859 snd_hda_codec_write(codec, 0x1a, 0,
860 AC_VERB_SET_PROC_COEF,
861 tmp | 0x2010);
862 break;
863 case 0x10ec0262:
864 case 0x10ec0880:
865 case 0x10ec0882:
866 case 0x10ec0883:
867 case 0x10ec0885:
868 case 0x10ec0888:
869 snd_hda_codec_write(codec, 0x20, 0,
870 AC_VERB_SET_COEF_INDEX, 7);
871 tmp = snd_hda_codec_read(codec, 0x20, 0,
872 AC_VERB_GET_PROC_COEF, 0);
873 snd_hda_codec_write(codec, 0x20, 0,
874 AC_VERB_SET_COEF_INDEX, 7);
875 snd_hda_codec_write(codec, 0x20, 0,
876 AC_VERB_SET_PROC_COEF,
877 tmp | 0x2010);
878 break;
879 case 0x10ec0267:
880 case 0x10ec0268:
881 snd_hda_codec_write(codec, 0x20, 0,
882 AC_VERB_SET_COEF_INDEX, 7);
883 tmp = snd_hda_codec_read(codec, 0x20, 0,
884 AC_VERB_GET_PROC_COEF, 0);
885 snd_hda_codec_write(codec, 0x20, 0,
886 AC_VERB_SET_COEF_INDEX, 7);
887 snd_hda_codec_write(codec, 0x20, 0,
888 AC_VERB_SET_PROC_COEF,
889 tmp | 0x3000);
890 break;
bc9f98a9 891 }
c9b58006 892 default:
bc9f98a9
KY
893 break;
894 }
c9b58006
KY
895
896 /* is laptop and enable the function "Mute internal speaker
897 * when the external headphone out jack is plugged"
898 */
899 if (!(ass & 0x4) || !(ass & 0x8000))
900 return;
901 /*
902 * 10~8 : Jack location
903 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
904 * 14~13: Resvered
905 * 15 : 1 --> enable the function "Mute internal speaker
906 * when the external headphone out jack is plugged"
907 */
908 if (!spec->autocfg.speaker_pins[0]) {
909 if (spec->multiout.dac_nids[0])
910 spec->autocfg.speaker_pins[0] =
911 spec->multiout.dac_nids[0];
912 else
913 return;
914 }
915
916 if (!spec->autocfg.hp_pins[0]) {
917 tmp = (ass >> 11) & 0x3; /* HP to chassis */
918 if (tmp == 0)
919 spec->autocfg.hp_pins[0] = porta;
920 else if (tmp == 1)
921 spec->autocfg.hp_pins[0] = porte;
922 else if (tmp == 2)
923 spec->autocfg.hp_pins[0] = portd;
924 else
925 return;
926 }
927
928 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
929 AC_VERB_SET_UNSOLICITED_ENABLE,
930 AC_USRSP_EN | ALC880_HP_EVENT);
931 spec->unsol_event = alc_sku_unsol_event;
932 spec->init_hook = alc_sku_automute;
bc9f98a9
KY
933}
934
f95474ec
TI
935/*
936 * Fix-up pin default configurations
937 */
938
939struct alc_pincfg {
940 hda_nid_t nid;
941 u32 val;
942};
943
944static void alc_fix_pincfg(struct hda_codec *codec,
945 const struct snd_pci_quirk *quirk,
946 const struct alc_pincfg **pinfix)
947{
948 const struct alc_pincfg *cfg;
949
950 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
951 if (!quirk)
952 return;
953
954 cfg = pinfix[quirk->value];
955 for (; cfg->nid; cfg++) {
956 int i;
957 u32 val = cfg->val;
958 for (i = 0; i < 4; i++) {
959 snd_hda_codec_write(codec, cfg->nid, 0,
960 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
961 val & 0xff);
962 val >>= 8;
963 }
964 }
965}
966
1da177e4 967/*
e9edcee0
TI
968 * ALC880 3-stack model
969 *
970 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
971 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
972 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
973 */
974
e9edcee0
TI
975static hda_nid_t alc880_dac_nids[4] = {
976 /* front, rear, clfe, rear_surr */
977 0x02, 0x05, 0x04, 0x03
978};
979
980static hda_nid_t alc880_adc_nids[3] = {
981 /* ADC0-2 */
982 0x07, 0x08, 0x09,
983};
984
985/* The datasheet says the node 0x07 is connected from inputs,
986 * but it shows zero connection in the real implementation on some devices.
df694daa 987 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 988 */
e9edcee0
TI
989static hda_nid_t alc880_adc_nids_alt[2] = {
990 /* ADC1-2 */
991 0x08, 0x09,
992};
993
994#define ALC880_DIGOUT_NID 0x06
995#define ALC880_DIGIN_NID 0x0a
996
997static struct hda_input_mux alc880_capture_source = {
998 .num_items = 4,
999 .items = {
1000 { "Mic", 0x0 },
1001 { "Front Mic", 0x3 },
1002 { "Line", 0x2 },
1003 { "CD", 0x4 },
1004 },
1005};
1006
1007/* channel source setting (2/6 channel selection for 3-stack) */
1008/* 2ch mode */
1009static struct hda_verb alc880_threestack_ch2_init[] = {
1010 /* set line-in to input, mute it */
1011 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1012 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1013 /* set mic-in to input vref 80%, mute it */
1014 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1015 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1016 { } /* end */
1017};
1018
1019/* 6ch mode */
1020static struct hda_verb alc880_threestack_ch6_init[] = {
1021 /* set line-in to output, unmute it */
1022 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1023 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1024 /* set mic-in to output, unmute it */
1025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1027 { } /* end */
1028};
1029
d2a6d7dc 1030static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1031 { 2, alc880_threestack_ch2_init },
1032 { 6, alc880_threestack_ch6_init },
1033};
1034
c8b6bf9b 1035static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1037 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1038 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1039 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1040 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1041 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1042 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1043 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1044 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1045 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1051 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1052 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1053 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1055 {
1056 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1057 .name = "Channel Mode",
df694daa
KY
1058 .info = alc_ch_mode_info,
1059 .get = alc_ch_mode_get,
1060 .put = alc_ch_mode_put,
e9edcee0
TI
1061 },
1062 { } /* end */
1063};
1064
1065/* capture mixer elements */
c8b6bf9b 1066static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1067 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1068 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1069 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1070 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1071 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1072 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1073 {
1074 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1075 /* The multiple "Capture Source" controls confuse alsamixer
1076 * So call somewhat different..
1077 * FIXME: the controls appear in the "playback" view!
1078 */
1079 /* .name = "Capture Source", */
1080 .name = "Input Source",
e9edcee0 1081 .count = 3,
1da177e4
LT
1082 .info = alc_mux_enum_info,
1083 .get = alc_mux_enum_get,
1084 .put = alc_mux_enum_put,
1085 },
1da177e4
LT
1086 { } /* end */
1087};
1088
e9edcee0 1089/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1090static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1091 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1092 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1093 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1094 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1095 {
1096 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1097 /* The multiple "Capture Source" controls confuse alsamixer
1098 * So call somewhat different..
1099 * FIXME: the controls appear in the "playback" view!
1100 */
1101 /* .name = "Capture Source", */
1102 .name = "Input Source",
1103 .count = 2,
1104 .info = alc_mux_enum_info,
1105 .get = alc_mux_enum_get,
1106 .put = alc_mux_enum_put,
1107 },
1da177e4
LT
1108 { } /* end */
1109};
1110
e9edcee0
TI
1111
1112
1113/*
1114 * ALC880 5-stack model
1115 *
9c7f852e
TI
1116 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1117 * Side = 0x02 (0xd)
e9edcee0
TI
1118 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1119 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1120 */
1121
1122/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1123static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1124 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1125 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1126 { } /* end */
1127};
1128
e9edcee0
TI
1129/* channel source setting (6/8 channel selection for 5-stack) */
1130/* 6ch mode */
1131static struct hda_verb alc880_fivestack_ch6_init[] = {
1132 /* set line-in to input, mute it */
1133 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1134 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1135 { } /* end */
1136};
1137
e9edcee0
TI
1138/* 8ch mode */
1139static struct hda_verb alc880_fivestack_ch8_init[] = {
1140 /* set line-in to output, unmute it */
1141 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1142 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1143 { } /* end */
1144};
1145
d2a6d7dc 1146static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1147 { 6, alc880_fivestack_ch6_init },
1148 { 8, alc880_fivestack_ch8_init },
1149};
1150
1151
1152/*
1153 * ALC880 6-stack model
1154 *
9c7f852e
TI
1155 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1156 * Side = 0x05 (0x0f)
e9edcee0
TI
1157 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1158 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1159 */
1160
1161static hda_nid_t alc880_6st_dac_nids[4] = {
1162 /* front, rear, clfe, rear_surr */
1163 0x02, 0x03, 0x04, 0x05
f12ab1e0 1164};
e9edcee0
TI
1165
1166static struct hda_input_mux alc880_6stack_capture_source = {
1167 .num_items = 4,
1168 .items = {
1169 { "Mic", 0x0 },
1170 { "Front Mic", 0x1 },
1171 { "Line", 0x2 },
1172 { "CD", 0x4 },
1173 },
1174};
1175
1176/* fixed 8-channels */
d2a6d7dc 1177static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1178 { 8, NULL },
1179};
1180
c8b6bf9b 1181static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1182 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1183 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1184 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1185 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1186 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1187 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1188 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1189 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1190 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1191 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1192 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1193 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1200 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1201 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1202 {
1203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1204 .name = "Channel Mode",
df694daa
KY
1205 .info = alc_ch_mode_info,
1206 .get = alc_ch_mode_get,
1207 .put = alc_ch_mode_put,
16ded525
TI
1208 },
1209 { } /* end */
1210};
1211
e9edcee0
TI
1212
1213/*
1214 * ALC880 W810 model
1215 *
1216 * W810 has rear IO for:
1217 * Front (DAC 02)
1218 * Surround (DAC 03)
1219 * Center/LFE (DAC 04)
1220 * Digital out (06)
1221 *
1222 * The system also has a pair of internal speakers, and a headphone jack.
1223 * These are both connected to Line2 on the codec, hence to DAC 02.
1224 *
1225 * There is a variable resistor to control the speaker or headphone
1226 * volume. This is a hardware-only device without a software API.
1227 *
1228 * Plugging headphones in will disable the internal speakers. This is
1229 * implemented in hardware, not via the driver using jack sense. In
1230 * a similar fashion, plugging into the rear socket marked "front" will
1231 * disable both the speakers and headphones.
1232 *
1233 * For input, there's a microphone jack, and an "audio in" jack.
1234 * These may not do anything useful with this driver yet, because I
1235 * haven't setup any initialization verbs for these yet...
1236 */
1237
1238static hda_nid_t alc880_w810_dac_nids[3] = {
1239 /* front, rear/surround, clfe */
1240 0x02, 0x03, 0x04
16ded525
TI
1241};
1242
e9edcee0 1243/* fixed 6 channels */
d2a6d7dc 1244static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1245 { 6, NULL }
1246};
1247
1248/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1249static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1250 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1251 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1252 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1253 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1254 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1255 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1256 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1257 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1259 { } /* end */
1260};
1261
1262
1263/*
1264 * Z710V model
1265 *
1266 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1267 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1268 * Line = 0x1a
e9edcee0
TI
1269 */
1270
1271static hda_nid_t alc880_z71v_dac_nids[1] = {
1272 0x02
1273};
1274#define ALC880_Z71V_HP_DAC 0x03
1275
1276/* fixed 2 channels */
d2a6d7dc 1277static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1278 { 2, NULL }
1279};
1280
c8b6bf9b 1281static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1282 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1283 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1284 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1285 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1286 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1287 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1290 { } /* end */
1291};
1292
e9edcee0
TI
1293
1294/* FIXME! */
1295/*
1296 * ALC880 F1734 model
1297 *
1298 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1299 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1300 */
1301
1302static hda_nid_t alc880_f1734_dac_nids[1] = {
1303 0x03
1304};
1305#define ALC880_F1734_HP_DAC 0x02
1306
c8b6bf9b 1307static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1308 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1309 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1310 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1311 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1312 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1313 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1316 { } /* end */
1317};
1318
1319
1320/* FIXME! */
1321/*
1322 * ALC880 ASUS model
1323 *
1324 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1325 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1326 * Mic = 0x18, Line = 0x1a
1327 */
1328
1329#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1330#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1331
c8b6bf9b 1332static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1333 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1334 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1335 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1336 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1337 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1338 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1339 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1340 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1341 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1342 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1344 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1347 {
1348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1349 .name = "Channel Mode",
df694daa
KY
1350 .info = alc_ch_mode_info,
1351 .get = alc_ch_mode_get,
1352 .put = alc_ch_mode_put,
16ded525
TI
1353 },
1354 { } /* end */
1355};
e9edcee0
TI
1356
1357/* FIXME! */
1358/*
1359 * ALC880 ASUS W1V model
1360 *
1361 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1362 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1363 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1364 */
1365
1366/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1367static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1368 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1369 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1370 { } /* end */
1371};
1372
3c10a9d9 1373/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1374static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1375 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1376 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1377 { } /* end */
1378};
e9edcee0 1379
df694daa
KY
1380/* TCL S700 */
1381static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1382 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1383 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1386 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1389 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1390 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1391 {
1392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1393 /* The multiple "Capture Source" controls confuse alsamixer
1394 * So call somewhat different..
1395 * FIXME: the controls appear in the "playback" view!
1396 */
1397 /* .name = "Capture Source", */
1398 .name = "Input Source",
1399 .count = 1,
1400 .info = alc_mux_enum_info,
1401 .get = alc_mux_enum_get,
1402 .put = alc_mux_enum_put,
1403 },
1404 { } /* end */
1405};
1406
ccc656ce
KY
1407/* Uniwill */
1408static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1409 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1410 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1411 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1412 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1414 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1416 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1417 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1418 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1419 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1420 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1421 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1422 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1423 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1425 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1426 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1427 {
1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429 .name = "Channel Mode",
1430 .info = alc_ch_mode_info,
1431 .get = alc_ch_mode_get,
1432 .put = alc_ch_mode_put,
1433 },
1434 { } /* end */
1435};
1436
2cf9f0fc
TD
1437static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1440 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1441 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1444 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1445 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1446 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1447 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1448 { } /* end */
1449};
1450
ccc656ce
KY
1451static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1452 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1453 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1454 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1455 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1458 { } /* end */
1459};
1460
1da177e4 1461/*
e9edcee0 1462 * build control elements
1da177e4
LT
1463 */
1464static int alc_build_controls(struct hda_codec *codec)
1465{
1466 struct alc_spec *spec = codec->spec;
1467 int err;
1468 int i;
1469
1470 for (i = 0; i < spec->num_mixers; i++) {
1471 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1472 if (err < 0)
1473 return err;
1474 }
1475
1476 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1477 err = snd_hda_create_spdif_out_ctls(codec,
1478 spec->multiout.dig_out_nid);
1da177e4
LT
1479 if (err < 0)
1480 return err;
1481 }
1482 if (spec->dig_in_nid) {
1483 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1484 if (err < 0)
1485 return err;
1486 }
1487 return 0;
1488}
1489
e9edcee0 1490
1da177e4
LT
1491/*
1492 * initialize the codec volumes, etc
1493 */
1494
e9edcee0
TI
1495/*
1496 * generic initialization of ADC, input mixers and output mixers
1497 */
1498static struct hda_verb alc880_volume_init_verbs[] = {
1499 /*
1500 * Unmute ADC0-2 and set the default input to mic-in
1501 */
71fe7b82 1502 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1504 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1506 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1507 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1508
e9edcee0
TI
1509 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1510 * mixer widget
9c7f852e
TI
1511 * Note: PASD motherboards uses the Line In 2 as the input for front
1512 * panel mic (mic 2)
1da177e4 1513 */
e9edcee0 1514 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1522
e9edcee0
TI
1523 /*
1524 * Set up output mixers (0x0c - 0x0f)
1da177e4 1525 */
e9edcee0
TI
1526 /* set vol=0 to output mixers */
1527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1528 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1529 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1530 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1531 /* set up input amps for analog loopback */
1532 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1540 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1541
1542 { }
1543};
1544
e9edcee0
TI
1545/*
1546 * 3-stack pin configuration:
1547 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1548 */
1549static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1550 /*
1551 * preset connection lists of input pins
1552 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1553 */
1554 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1555 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1556 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1557
1558 /*
1559 * Set pin mode and muting
1560 */
1561 /* set front pin widgets 0x14 for output */
05acb863 1562 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1563 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1564 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1567 /* Mic2 (as headphone out) for HP output */
1568 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1570 /* Line In pin widget for input */
05acb863 1571 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1573 /* Line2 (as front mic) pin widget for input and vref at 80% */
1574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1575 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1576 /* CD pin widget for input */
05acb863 1577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1578
e9edcee0
TI
1579 { }
1580};
1da177e4 1581
e9edcee0
TI
1582/*
1583 * 5-stack pin configuration:
1584 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1585 * line-in/side = 0x1a, f-mic = 0x1b
1586 */
1587static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1588 /*
1589 * preset connection lists of input pins
1590 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1591 */
e9edcee0
TI
1592 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1593 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1594
e9edcee0
TI
1595 /*
1596 * Set pin mode and muting
1da177e4 1597 */
e9edcee0
TI
1598 /* set pin widgets 0x14-0x17 for output */
1599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1601 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1602 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1603 /* unmute pins for output (no gain on this amp) */
1604 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1605 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1607 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1608
1609 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1610 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1612 /* Mic2 (as headphone out) for HP output */
1613 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1614 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1615 /* Line In pin widget for input */
1616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1617 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1618 /* Line2 (as front mic) pin widget for input and vref at 80% */
1619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1620 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1621 /* CD pin widget for input */
1622 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1623
1624 { }
1625};
1626
e9edcee0
TI
1627/*
1628 * W810 pin configuration:
1629 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1630 */
1631static struct hda_verb alc880_pin_w810_init_verbs[] = {
1632 /* hphone/speaker input selector: front DAC */
1633 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1634
05acb863 1635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1639 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1640 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1641
e9edcee0 1642 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1643 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1644
1da177e4
LT
1645 { }
1646};
1647
e9edcee0
TI
1648/*
1649 * Z71V pin configuration:
1650 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1651 */
1652static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1654 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1655 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1657
16ded525 1658 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1660 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1661 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1662
1663 { }
1664};
1665
e9edcee0
TI
1666/*
1667 * 6-stack pin configuration:
9c7f852e
TI
1668 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1669 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1670 */
1671static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1672 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1673
16ded525 1674 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1675 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1678 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1679 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1680 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1681 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1682
16ded525 1683 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1684 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1685 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1686 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1687 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1689 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1690 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1691 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1692
e9edcee0
TI
1693 { }
1694};
1695
ccc656ce
KY
1696/*
1697 * Uniwill pin configuration:
1698 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1699 * line = 0x1a
1700 */
1701static struct hda_verb alc880_uniwill_init_verbs[] = {
1702 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1703
1704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1709 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1711 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1713 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1714 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1715 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1718
1719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1721 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1722 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1725 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1726 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1727 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1728
1729 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1730 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1731
1732 { }
1733};
1734
1735/*
1736* Uniwill P53
1737* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1738 */
1739static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1740 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1741
1742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1747 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1750 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1751 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1753 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1754
1755 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1761
1762 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1763 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1764
1765 { }
1766};
1767
2cf9f0fc
TD
1768static struct hda_verb alc880_beep_init_verbs[] = {
1769 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1770 { }
1771};
1772
ccc656ce 1773/* toggle speaker-output according to the hp-jack state */
458a4fab 1774static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1775{
1776 unsigned int present;
f12ab1e0 1777 unsigned char bits;
ccc656ce
KY
1778
1779 present = snd_hda_codec_read(codec, 0x14, 0,
1780 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1781 bits = present ? HDA_AMP_MUTE : 0;
1782 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1783 HDA_AMP_MUTE, bits);
1784 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1785 HDA_AMP_MUTE, bits);
458a4fab
TI
1786}
1787
1788/* auto-toggle front mic */
1789static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1790{
1791 unsigned int present;
1792 unsigned char bits;
ccc656ce
KY
1793
1794 present = snd_hda_codec_read(codec, 0x18, 0,
1795 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1796 bits = present ? HDA_AMP_MUTE : 0;
1797 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1798}
1799
1800static void alc880_uniwill_automute(struct hda_codec *codec)
1801{
1802 alc880_uniwill_hp_automute(codec);
1803 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1804}
1805
1806static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1807 unsigned int res)
1808{
1809 /* Looks like the unsol event is incompatible with the standard
1810 * definition. 4bit tag is placed at 28 bit!
1811 */
458a4fab
TI
1812 switch (res >> 28) {
1813 case ALC880_HP_EVENT:
1814 alc880_uniwill_hp_automute(codec);
1815 break;
1816 case ALC880_MIC_EVENT:
1817 alc880_uniwill_mic_automute(codec);
1818 break;
1819 }
ccc656ce
KY
1820}
1821
1822static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1823{
1824 unsigned int present;
f12ab1e0 1825 unsigned char bits;
ccc656ce
KY
1826
1827 present = snd_hda_codec_read(codec, 0x14, 0,
1828 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1829 bits = present ? HDA_AMP_MUTE : 0;
1830 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1831}
1832
1833static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1834{
1835 unsigned int present;
1836
1837 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1838 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1839 present &= HDA_AMP_VOLMASK;
1840 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1841 HDA_AMP_VOLMASK, present);
1842 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1843 HDA_AMP_VOLMASK, present);
ccc656ce 1844}
47fd830a 1845
ccc656ce
KY
1846static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1847 unsigned int res)
1848{
1849 /* Looks like the unsol event is incompatible with the standard
1850 * definition. 4bit tag is placed at 28 bit!
1851 */
1852 if ((res >> 28) == ALC880_HP_EVENT)
1853 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1854 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1855 alc880_uniwill_p53_dcvol_automute(codec);
1856}
1857
e9edcee0
TI
1858/* FIXME! */
1859/*
1860 * F1734 pin configuration:
1861 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1862 */
1863static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1864 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1865 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1866 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1867 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1868
e9edcee0 1869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1873
e9edcee0
TI
1874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1882 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62
TI
1883
1884 { }
1885};
1886
e9edcee0
TI
1887/* FIXME! */
1888/*
1889 * ASUS pin configuration:
1890 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1891 */
1892static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1893 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1894 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1895 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1896 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1897
1898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1900 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1902 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1904 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1905 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1906
1907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1909 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1910 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1914 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1915 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1916
e9edcee0
TI
1917 { }
1918};
16ded525 1919
e9edcee0 1920/* Enable GPIO mask and set output */
bc9f98a9
KY
1921#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1922#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1923
1924/* Clevo m520g init */
1925static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1926 /* headphone output */
1927 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1928 /* line-out */
1929 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1930 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1931 /* Line-in */
1932 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1933 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1934 /* CD */
1935 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1936 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 /* Mic1 (rear panel) */
1938 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1940 /* Mic2 (front panel) */
1941 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1942 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1943 /* headphone */
1944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1946 /* change to EAPD mode */
1947 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1948 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1949
1950 { }
16ded525
TI
1951};
1952
df694daa 1953static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
1954 /* change to EAPD mode */
1955 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1956 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1957
df694daa
KY
1958 /* Headphone output */
1959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960 /* Front output*/
1961 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1963
1964 /* Line In pin widget for input */
1965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1966 /* CD pin widget for input */
1967 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1968 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1970
1971 /* change to EAPD mode */
1972 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1973 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1974
1975 { }
1976};
16ded525 1977
e9edcee0 1978/*
ae6b813a
TI
1979 * LG m1 express dual
1980 *
1981 * Pin assignment:
1982 * Rear Line-In/Out (blue): 0x14
1983 * Build-in Mic-In: 0x15
1984 * Speaker-out: 0x17
1985 * HP-Out (green): 0x1b
1986 * Mic-In/Out (red): 0x19
1987 * SPDIF-Out: 0x1e
1988 */
1989
1990/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1991static hda_nid_t alc880_lg_dac_nids[3] = {
1992 0x05, 0x02, 0x03
1993};
1994
1995/* seems analog CD is not working */
1996static struct hda_input_mux alc880_lg_capture_source = {
1997 .num_items = 3,
1998 .items = {
1999 { "Mic", 0x1 },
2000 { "Line", 0x5 },
2001 { "Internal Mic", 0x6 },
2002 },
2003};
2004
2005/* 2,4,6 channel modes */
2006static struct hda_verb alc880_lg_ch2_init[] = {
2007 /* set line-in and mic-in to input */
2008 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2009 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2010 { }
2011};
2012
2013static struct hda_verb alc880_lg_ch4_init[] = {
2014 /* set line-in to out and mic-in to input */
2015 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2016 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2017 { }
2018};
2019
2020static struct hda_verb alc880_lg_ch6_init[] = {
2021 /* set line-in and mic-in to output */
2022 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2023 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2024 { }
2025};
2026
2027static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2028 { 2, alc880_lg_ch2_init },
2029 { 4, alc880_lg_ch4_init },
2030 { 6, alc880_lg_ch6_init },
2031};
2032
2033static struct snd_kcontrol_new alc880_lg_mixer[] = {
2034 /* FIXME: it's not really "master" but front channels */
2035 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2036 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
2037 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2038 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2039 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2040 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2041 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2042 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2048 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2049 {
2050 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2051 .name = "Channel Mode",
2052 .info = alc_ch_mode_info,
2053 .get = alc_ch_mode_get,
2054 .put = alc_ch_mode_put,
2055 },
2056 { } /* end */
2057};
2058
2059static struct hda_verb alc880_lg_init_verbs[] = {
2060 /* set capture source to mic-in */
2061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2064 /* mute all amp mixer inputs */
2065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2068 /* line-in to input */
2069 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2070 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2071 /* built-in mic */
2072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2073 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2074 /* speaker-out */
2075 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2076 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077 /* mic-in to input */
2078 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2079 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2080 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2081 /* HP-out */
2082 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2085 /* jack sense */
2086 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2087 { }
2088};
2089
2090/* toggle speaker-output according to the hp-jack state */
2091static void alc880_lg_automute(struct hda_codec *codec)
2092{
2093 unsigned int present;
f12ab1e0 2094 unsigned char bits;
ae6b813a
TI
2095
2096 present = snd_hda_codec_read(codec, 0x1b, 0,
2097 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2098 bits = present ? HDA_AMP_MUTE : 0;
2099 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2100 HDA_AMP_MUTE, bits);
ae6b813a
TI
2101}
2102
2103static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2104{
2105 /* Looks like the unsol event is incompatible with the standard
2106 * definition. 4bit tag is placed at 28 bit!
2107 */
2108 if ((res >> 28) == 0x01)
2109 alc880_lg_automute(codec);
2110}
2111
d681518a
TI
2112/*
2113 * LG LW20
2114 *
2115 * Pin assignment:
2116 * Speaker-out: 0x14
2117 * Mic-In: 0x18
e4f41da9
CM
2118 * Built-in Mic-In: 0x19
2119 * Line-In: 0x1b
2120 * HP-Out: 0x1a
d681518a
TI
2121 * SPDIF-Out: 0x1e
2122 */
2123
d681518a 2124static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2125 .num_items = 3,
d681518a
TI
2126 .items = {
2127 { "Mic", 0x0 },
2128 { "Internal Mic", 0x1 },
e4f41da9 2129 { "Line In", 0x2 },
d681518a
TI
2130 },
2131};
2132
0a8c5da3
CM
2133#define alc880_lg_lw_modes alc880_threestack_modes
2134
d681518a 2135static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2139 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2140 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2141 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2142 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2143 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2148 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2149 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2150 {
2151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2152 .name = "Channel Mode",
2153 .info = alc_ch_mode_info,
2154 .get = alc_ch_mode_get,
2155 .put = alc_ch_mode_put,
2156 },
d681518a
TI
2157 { } /* end */
2158};
2159
2160static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2161 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2162 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2163 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2164
d681518a
TI
2165 /* set capture source to mic-in */
2166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2167 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2168 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2170 /* speaker-out */
2171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2173 /* HP-out */
d681518a
TI
2174 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2175 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2176 /* mic-in to input */
2177 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2178 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2179 /* built-in mic */
2180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2182 /* jack sense */
2183 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2184 { }
2185};
2186
2187/* toggle speaker-output according to the hp-jack state */
2188static void alc880_lg_lw_automute(struct hda_codec *codec)
2189{
2190 unsigned int present;
f12ab1e0 2191 unsigned char bits;
d681518a
TI
2192
2193 present = snd_hda_codec_read(codec, 0x1b, 0,
2194 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2195 bits = present ? HDA_AMP_MUTE : 0;
2196 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2197 HDA_AMP_MUTE, bits);
d681518a
TI
2198}
2199
2200static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2201{
2202 /* Looks like the unsol event is incompatible with the standard
2203 * definition. 4bit tag is placed at 28 bit!
2204 */
2205 if ((res >> 28) == 0x01)
2206 alc880_lg_lw_automute(codec);
2207}
2208
cb53c626
TI
2209#ifdef CONFIG_SND_HDA_POWER_SAVE
2210static struct hda_amp_list alc880_loopbacks[] = {
2211 { 0x0b, HDA_INPUT, 0 },
2212 { 0x0b, HDA_INPUT, 1 },
2213 { 0x0b, HDA_INPUT, 2 },
2214 { 0x0b, HDA_INPUT, 3 },
2215 { 0x0b, HDA_INPUT, 4 },
2216 { } /* end */
2217};
2218
2219static struct hda_amp_list alc880_lg_loopbacks[] = {
2220 { 0x0b, HDA_INPUT, 1 },
2221 { 0x0b, HDA_INPUT, 6 },
2222 { 0x0b, HDA_INPUT, 7 },
2223 { } /* end */
2224};
2225#endif
2226
ae6b813a
TI
2227/*
2228 * Common callbacks
e9edcee0
TI
2229 */
2230
1da177e4
LT
2231static int alc_init(struct hda_codec *codec)
2232{
2233 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2234 unsigned int i;
2235
2236 for (i = 0; i < spec->num_init_verbs; i++)
2237 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2238
2239 if (spec->init_hook)
2240 spec->init_hook(codec);
2241
1da177e4
LT
2242 return 0;
2243}
2244
ae6b813a
TI
2245static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2246{
2247 struct alc_spec *spec = codec->spec;
2248
2249 if (spec->unsol_event)
2250 spec->unsol_event(codec, res);
2251}
2252
cb53c626
TI
2253#ifdef CONFIG_SND_HDA_POWER_SAVE
2254static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2255{
2256 struct alc_spec *spec = codec->spec;
2257 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2258}
2259#endif
2260
1da177e4
LT
2261/*
2262 * Analog playback callbacks
2263 */
2264static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2265 struct hda_codec *codec,
c8b6bf9b 2266 struct snd_pcm_substream *substream)
1da177e4
LT
2267{
2268 struct alc_spec *spec = codec->spec;
2269 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2270}
2271
2272static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2273 struct hda_codec *codec,
2274 unsigned int stream_tag,
2275 unsigned int format,
c8b6bf9b 2276 struct snd_pcm_substream *substream)
1da177e4
LT
2277{
2278 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2279 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2280 stream_tag, format, substream);
1da177e4
LT
2281}
2282
2283static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2284 struct hda_codec *codec,
c8b6bf9b 2285 struct snd_pcm_substream *substream)
1da177e4
LT
2286{
2287 struct alc_spec *spec = codec->spec;
2288 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2289}
2290
2291/*
2292 * Digital out
2293 */
2294static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2295 struct hda_codec *codec,
c8b6bf9b 2296 struct snd_pcm_substream *substream)
1da177e4
LT
2297{
2298 struct alc_spec *spec = codec->spec;
2299 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2300}
2301
6b97eb45
TI
2302static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2303 struct hda_codec *codec,
2304 unsigned int stream_tag,
2305 unsigned int format,
2306 struct snd_pcm_substream *substream)
2307{
2308 struct alc_spec *spec = codec->spec;
2309 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2310 stream_tag, format, substream);
2311}
2312
1da177e4
LT
2313static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2314 struct hda_codec *codec,
c8b6bf9b 2315 struct snd_pcm_substream *substream)
1da177e4
LT
2316{
2317 struct alc_spec *spec = codec->spec;
2318 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2319}
2320
2321/*
2322 * Analog capture
2323 */
2324static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2325 struct hda_codec *codec,
2326 unsigned int stream_tag,
2327 unsigned int format,
c8b6bf9b 2328 struct snd_pcm_substream *substream)
1da177e4
LT
2329{
2330 struct alc_spec *spec = codec->spec;
2331
2332 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2333 stream_tag, 0, format);
2334 return 0;
2335}
2336
2337static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2338 struct hda_codec *codec,
c8b6bf9b 2339 struct snd_pcm_substream *substream)
1da177e4
LT
2340{
2341 struct alc_spec *spec = codec->spec;
2342
9c7f852e
TI
2343 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2344 0, 0, 0);
1da177e4
LT
2345 return 0;
2346}
2347
2348
2349/*
2350 */
2351static struct hda_pcm_stream alc880_pcm_analog_playback = {
2352 .substreams = 1,
2353 .channels_min = 2,
2354 .channels_max = 8,
e9edcee0 2355 /* NID is set in alc_build_pcms */
1da177e4
LT
2356 .ops = {
2357 .open = alc880_playback_pcm_open,
2358 .prepare = alc880_playback_pcm_prepare,
2359 .cleanup = alc880_playback_pcm_cleanup
2360 },
2361};
2362
2363static struct hda_pcm_stream alc880_pcm_analog_capture = {
2364 .substreams = 2,
2365 .channels_min = 2,
2366 .channels_max = 2,
e9edcee0 2367 /* NID is set in alc_build_pcms */
1da177e4
LT
2368 .ops = {
2369 .prepare = alc880_capture_pcm_prepare,
2370 .cleanup = alc880_capture_pcm_cleanup
2371 },
2372};
2373
2374static struct hda_pcm_stream alc880_pcm_digital_playback = {
2375 .substreams = 1,
2376 .channels_min = 2,
2377 .channels_max = 2,
2378 /* NID is set in alc_build_pcms */
2379 .ops = {
2380 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2381 .close = alc880_dig_playback_pcm_close,
2382 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2383 },
2384};
2385
2386static struct hda_pcm_stream alc880_pcm_digital_capture = {
2387 .substreams = 1,
2388 .channels_min = 2,
2389 .channels_max = 2,
2390 /* NID is set in alc_build_pcms */
2391};
2392
4c5186ed
JW
2393/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2394static struct hda_pcm_stream alc_pcm_null_playback = {
2395 .substreams = 0,
2396 .channels_min = 0,
2397 .channels_max = 0,
2398};
2399
1da177e4
LT
2400static int alc_build_pcms(struct hda_codec *codec)
2401{
2402 struct alc_spec *spec = codec->spec;
2403 struct hda_pcm *info = spec->pcm_rec;
2404 int i;
2405
2406 codec->num_pcms = 1;
2407 codec->pcm_info = info;
2408
2409 info->name = spec->stream_name_analog;
4a471b7d
TI
2410 if (spec->stream_analog_playback) {
2411 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2412 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2413 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2414 }
2415 if (spec->stream_analog_capture) {
2416 snd_assert(spec->adc_nids, return -EINVAL);
2417 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2418 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2419 }
2420
2421 if (spec->channel_mode) {
2422 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2423 for (i = 0; i < spec->num_channel_mode; i++) {
2424 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2425 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2426 }
1da177e4
LT
2427 }
2428 }
2429
e08a007d 2430 /* SPDIF for stream index #1 */
1da177e4 2431 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2432 codec->num_pcms = 2;
c06134d7 2433 info = spec->pcm_rec + 1;
1da177e4 2434 info->name = spec->stream_name_digital;
4a471b7d
TI
2435 if (spec->multiout.dig_out_nid &&
2436 spec->stream_digital_playback) {
1da177e4
LT
2437 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2438 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2439 }
4a471b7d
TI
2440 if (spec->dig_in_nid &&
2441 spec->stream_digital_capture) {
1da177e4
LT
2442 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2443 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2444 }
2445 }
2446
e08a007d
TI
2447 /* If the use of more than one ADC is requested for the current
2448 * model, configure a second analog capture-only PCM.
2449 */
2450 /* Additional Analaog capture for index #2 */
2451 if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2452 spec->adc_nids) {
2453 codec->num_pcms = 3;
c06134d7 2454 info = spec->pcm_rec + 2;
e08a007d
TI
2455 info->name = spec->stream_name_analog;
2456 /* No playback stream for second PCM */
2457 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2458 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2459 if (spec->stream_analog_capture) {
2460 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2461 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2462 }
2463 }
2464
1da177e4
LT
2465 return 0;
2466}
2467
2468static void alc_free(struct hda_codec *codec)
2469{
e9edcee0
TI
2470 struct alc_spec *spec = codec->spec;
2471 unsigned int i;
2472
f12ab1e0 2473 if (!spec)
e9edcee0
TI
2474 return;
2475
2476 if (spec->kctl_alloc) {
2477 for (i = 0; i < spec->num_kctl_used; i++)
2478 kfree(spec->kctl_alloc[i].name);
2479 kfree(spec->kctl_alloc);
2480 }
2481 kfree(spec);
1da177e4
LT
2482}
2483
2484/*
2485 */
2486static struct hda_codec_ops alc_patch_ops = {
2487 .build_controls = alc_build_controls,
2488 .build_pcms = alc_build_pcms,
2489 .init = alc_init,
2490 .free = alc_free,
ae6b813a 2491 .unsol_event = alc_unsol_event,
cb53c626
TI
2492#ifdef CONFIG_SND_HDA_POWER_SAVE
2493 .check_power_status = alc_check_power_status,
2494#endif
1da177e4
LT
2495};
2496
2fa522be
TI
2497
2498/*
2499 * Test configuration for debugging
2500 *
2501 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2502 * enum controls.
2503 */
2504#ifdef CONFIG_SND_DEBUG
2505static hda_nid_t alc880_test_dac_nids[4] = {
2506 0x02, 0x03, 0x04, 0x05
2507};
2508
2509static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2510 .num_items = 7,
2fa522be
TI
2511 .items = {
2512 { "In-1", 0x0 },
2513 { "In-2", 0x1 },
2514 { "In-3", 0x2 },
2515 { "In-4", 0x3 },
2516 { "CD", 0x4 },
ae6b813a
TI
2517 { "Front", 0x5 },
2518 { "Surround", 0x6 },
2fa522be
TI
2519 },
2520};
2521
d2a6d7dc 2522static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2523 { 2, NULL },
fd2c326d 2524 { 4, NULL },
2fa522be 2525 { 6, NULL },
fd2c326d 2526 { 8, NULL },
2fa522be
TI
2527};
2528
9c7f852e
TI
2529static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2530 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2531{
2532 static char *texts[] = {
2533 "N/A", "Line Out", "HP Out",
2534 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2535 };
2536 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2537 uinfo->count = 1;
2538 uinfo->value.enumerated.items = 8;
2539 if (uinfo->value.enumerated.item >= 8)
2540 uinfo->value.enumerated.item = 7;
2541 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2542 return 0;
2543}
2544
9c7f852e
TI
2545static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2546 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2547{
2548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2549 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2550 unsigned int pin_ctl, item = 0;
2551
2552 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2553 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2554 if (pin_ctl & AC_PINCTL_OUT_EN) {
2555 if (pin_ctl & AC_PINCTL_HP_EN)
2556 item = 2;
2557 else
2558 item = 1;
2559 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2560 switch (pin_ctl & AC_PINCTL_VREFEN) {
2561 case AC_PINCTL_VREF_HIZ: item = 3; break;
2562 case AC_PINCTL_VREF_50: item = 4; break;
2563 case AC_PINCTL_VREF_GRD: item = 5; break;
2564 case AC_PINCTL_VREF_80: item = 6; break;
2565 case AC_PINCTL_VREF_100: item = 7; break;
2566 }
2567 }
2568 ucontrol->value.enumerated.item[0] = item;
2569 return 0;
2570}
2571
9c7f852e
TI
2572static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2573 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2574{
2575 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2576 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2577 static unsigned int ctls[] = {
2578 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2579 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2580 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2581 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2582 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2583 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2584 };
2585 unsigned int old_ctl, new_ctl;
2586
2587 old_ctl = snd_hda_codec_read(codec, nid, 0,
2588 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2589 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2590 if (old_ctl != new_ctl) {
82beb8fd
TI
2591 int val;
2592 snd_hda_codec_write_cache(codec, nid, 0,
2593 AC_VERB_SET_PIN_WIDGET_CONTROL,
2594 new_ctl);
47fd830a
TI
2595 val = ucontrol->value.enumerated.item[0] >= 3 ?
2596 HDA_AMP_MUTE : 0;
2597 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2598 HDA_AMP_MUTE, val);
2fa522be
TI
2599 return 1;
2600 }
2601 return 0;
2602}
2603
9c7f852e
TI
2604static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2605 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2606{
2607 static char *texts[] = {
2608 "Front", "Surround", "CLFE", "Side"
2609 };
2610 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2611 uinfo->count = 1;
2612 uinfo->value.enumerated.items = 4;
2613 if (uinfo->value.enumerated.item >= 4)
2614 uinfo->value.enumerated.item = 3;
2615 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2616 return 0;
2617}
2618
9c7f852e
TI
2619static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2620 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2621{
2622 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2623 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2624 unsigned int sel;
2625
2626 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2627 ucontrol->value.enumerated.item[0] = sel & 3;
2628 return 0;
2629}
2630
9c7f852e
TI
2631static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2632 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2633{
2634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2635 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2636 unsigned int sel;
2637
2638 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2639 if (ucontrol->value.enumerated.item[0] != sel) {
2640 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2641 snd_hda_codec_write_cache(codec, nid, 0,
2642 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2643 return 1;
2644 }
2645 return 0;
2646}
2647
2648#define PIN_CTL_TEST(xname,nid) { \
2649 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2650 .name = xname, \
2651 .info = alc_test_pin_ctl_info, \
2652 .get = alc_test_pin_ctl_get, \
2653 .put = alc_test_pin_ctl_put, \
2654 .private_value = nid \
2655 }
2656
2657#define PIN_SRC_TEST(xname,nid) { \
2658 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2659 .name = xname, \
2660 .info = alc_test_pin_src_info, \
2661 .get = alc_test_pin_src_get, \
2662 .put = alc_test_pin_src_put, \
2663 .private_value = nid \
2664 }
2665
c8b6bf9b 2666static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2667 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2668 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2669 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2670 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2671 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2672 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2673 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2674 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2675 PIN_CTL_TEST("Front Pin Mode", 0x14),
2676 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2677 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2678 PIN_CTL_TEST("Side Pin Mode", 0x17),
2679 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2680 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2681 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2682 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2683 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2684 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2685 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2686 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2687 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2688 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2689 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2690 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2691 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2692 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2693 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2694 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2695 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2696 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2697 {
2698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2699 .name = "Channel Mode",
df694daa
KY
2700 .info = alc_ch_mode_info,
2701 .get = alc_ch_mode_get,
2702 .put = alc_ch_mode_put,
2fa522be
TI
2703 },
2704 { } /* end */
2705};
2706
2707static struct hda_verb alc880_test_init_verbs[] = {
2708 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2710 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2715 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2717 /* Vol output for 0x0c-0x0f */
05acb863
TI
2718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2719 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2720 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2722 /* Set output pins 0x14-0x17 */
05acb863
TI
2723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2725 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2727 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2730 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2731 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2732 /* Set input pins 0x18-0x1c */
16ded525
TI
2733 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2734 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2735 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2736 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2737 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2738 /* Mute input pins 0x18-0x1b */
05acb863
TI
2739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2741 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2742 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2743 /* ADC set up */
05acb863 2744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2745 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2747 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2748 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2749 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2750 /* Analog input/passthru */
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2753 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2754 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2755 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2756 { }
2757};
2758#endif
2759
1da177e4
LT
2760/*
2761 */
2762
f5fcc13c
TI
2763static const char *alc880_models[ALC880_MODEL_LAST] = {
2764 [ALC880_3ST] = "3stack",
2765 [ALC880_TCL_S700] = "tcl",
2766 [ALC880_3ST_DIG] = "3stack-digout",
2767 [ALC880_CLEVO] = "clevo",
2768 [ALC880_5ST] = "5stack",
2769 [ALC880_5ST_DIG] = "5stack-digout",
2770 [ALC880_W810] = "w810",
2771 [ALC880_Z71V] = "z71v",
2772 [ALC880_6ST] = "6stack",
2773 [ALC880_6ST_DIG] = "6stack-digout",
2774 [ALC880_ASUS] = "asus",
2775 [ALC880_ASUS_W1V] = "asus-w1v",
2776 [ALC880_ASUS_DIG] = "asus-dig",
2777 [ALC880_ASUS_DIG2] = "asus-dig2",
2778 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2779 [ALC880_UNIWILL_P53] = "uniwill-p53",
2780 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2781 [ALC880_F1734] = "F1734",
2782 [ALC880_LG] = "lg",
2783 [ALC880_LG_LW] = "lg-lw",
2fa522be 2784#ifdef CONFIG_SND_DEBUG
f5fcc13c 2785 [ALC880_TEST] = "test",
2fa522be 2786#endif
f5fcc13c
TI
2787 [ALC880_AUTO] = "auto",
2788};
2789
2790static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2791 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2792 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2793 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2794 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2795 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2796 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2797 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2798 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2799 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2800 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2801 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2802 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2803 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2804 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2805 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2806 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2807 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2808 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2809 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2810 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2811 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
0e4ceb75 2812 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
f5fcc13c
TI
2813 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2814 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2815 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2816 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2817 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2818 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2819 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2820 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2821 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2822 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2823 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2824 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2825 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
2826 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2827 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 2828 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 2829 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 2830 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 2831 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
2832 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2833 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741
TI
2834 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2835 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 2836 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 2837 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 2838 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 2839 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 2840 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
2841 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2842 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 2843 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
2844 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2845 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2846 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2847 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
2848 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2849 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 2850 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 2851 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2852 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2853 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
2854 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2855 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2856 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2857 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2858 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2859 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
2860 {}
2861};
2862
16ded525 2863/*
df694daa 2864 * ALC880 codec presets
16ded525 2865 */
16ded525
TI
2866static struct alc_config_preset alc880_presets[] = {
2867 [ALC880_3ST] = {
e9edcee0 2868 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2869 .init_verbs = { alc880_volume_init_verbs,
2870 alc880_pin_3stack_init_verbs },
16ded525 2871 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 2872 .dac_nids = alc880_dac_nids,
16ded525
TI
2873 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2874 .channel_mode = alc880_threestack_modes,
4e195a7b 2875 .need_dac_fix = 1,
16ded525
TI
2876 .input_mux = &alc880_capture_source,
2877 },
2878 [ALC880_3ST_DIG] = {
e9edcee0 2879 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2880 .init_verbs = { alc880_volume_init_verbs,
2881 alc880_pin_3stack_init_verbs },
16ded525 2882 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
2883 .dac_nids = alc880_dac_nids,
2884 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2885 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2886 .channel_mode = alc880_threestack_modes,
4e195a7b 2887 .need_dac_fix = 1,
16ded525
TI
2888 .input_mux = &alc880_capture_source,
2889 },
df694daa
KY
2890 [ALC880_TCL_S700] = {
2891 .mixers = { alc880_tcl_s700_mixer },
2892 .init_verbs = { alc880_volume_init_verbs,
2893 alc880_pin_tcl_S700_init_verbs,
2894 alc880_gpio2_init_verbs },
2895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2896 .dac_nids = alc880_dac_nids,
2897 .hp_nid = 0x03,
2898 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2899 .channel_mode = alc880_2_jack_modes,
2900 .input_mux = &alc880_capture_source,
2901 },
16ded525 2902 [ALC880_5ST] = {
f12ab1e0
TI
2903 .mixers = { alc880_three_stack_mixer,
2904 alc880_five_stack_mixer},
2905 .init_verbs = { alc880_volume_init_verbs,
2906 alc880_pin_5stack_init_verbs },
16ded525
TI
2907 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2908 .dac_nids = alc880_dac_nids,
16ded525
TI
2909 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2910 .channel_mode = alc880_fivestack_modes,
2911 .input_mux = &alc880_capture_source,
2912 },
2913 [ALC880_5ST_DIG] = {
f12ab1e0
TI
2914 .mixers = { alc880_three_stack_mixer,
2915 alc880_five_stack_mixer },
2916 .init_verbs = { alc880_volume_init_verbs,
2917 alc880_pin_5stack_init_verbs },
16ded525
TI
2918 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2919 .dac_nids = alc880_dac_nids,
2920 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2921 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2922 .channel_mode = alc880_fivestack_modes,
2923 .input_mux = &alc880_capture_source,
2924 },
b6482d48
TI
2925 [ALC880_6ST] = {
2926 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
2927 .init_verbs = { alc880_volume_init_verbs,
2928 alc880_pin_6stack_init_verbs },
b6482d48
TI
2929 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2930 .dac_nids = alc880_6st_dac_nids,
2931 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2932 .channel_mode = alc880_sixstack_modes,
2933 .input_mux = &alc880_6stack_capture_source,
2934 },
16ded525 2935 [ALC880_6ST_DIG] = {
e9edcee0 2936 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
2937 .init_verbs = { alc880_volume_init_verbs,
2938 alc880_pin_6stack_init_verbs },
16ded525
TI
2939 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2940 .dac_nids = alc880_6st_dac_nids,
2941 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2942 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2943 .channel_mode = alc880_sixstack_modes,
2944 .input_mux = &alc880_6stack_capture_source,
2945 },
2946 [ALC880_W810] = {
e9edcee0 2947 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
2948 .init_verbs = { alc880_volume_init_verbs,
2949 alc880_pin_w810_init_verbs,
b0af0de5 2950 alc880_gpio2_init_verbs },
16ded525
TI
2951 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2952 .dac_nids = alc880_w810_dac_nids,
2953 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2954 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2955 .channel_mode = alc880_w810_modes,
2956 .input_mux = &alc880_capture_source,
2957 },
2958 [ALC880_Z71V] = {
e9edcee0 2959 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
2960 .init_verbs = { alc880_volume_init_verbs,
2961 alc880_pin_z71v_init_verbs },
16ded525
TI
2962 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2963 .dac_nids = alc880_z71v_dac_nids,
2964 .dig_out_nid = ALC880_DIGOUT_NID,
2965 .hp_nid = 0x03,
e9edcee0
TI
2966 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2967 .channel_mode = alc880_2_jack_modes,
16ded525
TI
2968 .input_mux = &alc880_capture_source,
2969 },
2970 [ALC880_F1734] = {
e9edcee0 2971 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
2972 .init_verbs = { alc880_volume_init_verbs,
2973 alc880_pin_f1734_init_verbs },
e9edcee0
TI
2974 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2975 .dac_nids = alc880_f1734_dac_nids,
2976 .hp_nid = 0x02,
2977 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2978 .channel_mode = alc880_2_jack_modes,
16ded525
TI
2979 .input_mux = &alc880_capture_source,
2980 },
2981 [ALC880_ASUS] = {
e9edcee0 2982 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
2983 .init_verbs = { alc880_volume_init_verbs,
2984 alc880_pin_asus_init_verbs,
e9edcee0
TI
2985 alc880_gpio1_init_verbs },
2986 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2987 .dac_nids = alc880_asus_dac_nids,
2988 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2989 .channel_mode = alc880_asus_modes,
4e195a7b 2990 .need_dac_fix = 1,
16ded525
TI
2991 .input_mux = &alc880_capture_source,
2992 },
2993 [ALC880_ASUS_DIG] = {
e9edcee0 2994 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
2995 .init_verbs = { alc880_volume_init_verbs,
2996 alc880_pin_asus_init_verbs,
e9edcee0
TI
2997 alc880_gpio1_init_verbs },
2998 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2999 .dac_nids = alc880_asus_dac_nids,
16ded525 3000 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3001 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3002 .channel_mode = alc880_asus_modes,
4e195a7b 3003 .need_dac_fix = 1,
16ded525
TI
3004 .input_mux = &alc880_capture_source,
3005 },
df694daa
KY
3006 [ALC880_ASUS_DIG2] = {
3007 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3008 .init_verbs = { alc880_volume_init_verbs,
3009 alc880_pin_asus_init_verbs,
df694daa
KY
3010 alc880_gpio2_init_verbs }, /* use GPIO2 */
3011 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3012 .dac_nids = alc880_asus_dac_nids,
3013 .dig_out_nid = ALC880_DIGOUT_NID,
3014 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3015 .channel_mode = alc880_asus_modes,
4e195a7b 3016 .need_dac_fix = 1,
df694daa
KY
3017 .input_mux = &alc880_capture_source,
3018 },
16ded525 3019 [ALC880_ASUS_W1V] = {
e9edcee0 3020 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3021 .init_verbs = { alc880_volume_init_verbs,
3022 alc880_pin_asus_init_verbs,
e9edcee0
TI
3023 alc880_gpio1_init_verbs },
3024 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3025 .dac_nids = alc880_asus_dac_nids,
16ded525 3026 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3027 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3028 .channel_mode = alc880_asus_modes,
4e195a7b 3029 .need_dac_fix = 1,
16ded525
TI
3030 .input_mux = &alc880_capture_source,
3031 },
3032 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3033 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3034 .init_verbs = { alc880_volume_init_verbs,
3035 alc880_pin_asus_init_verbs },
e9edcee0
TI
3036 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3037 .dac_nids = alc880_asus_dac_nids,
16ded525 3038 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3039 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3040 .channel_mode = alc880_asus_modes,
4e195a7b 3041 .need_dac_fix = 1,
16ded525
TI
3042 .input_mux = &alc880_capture_source,
3043 },
ccc656ce
KY
3044 [ALC880_UNIWILL] = {
3045 .mixers = { alc880_uniwill_mixer },
3046 .init_verbs = { alc880_volume_init_verbs,
3047 alc880_uniwill_init_verbs },
3048 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3049 .dac_nids = alc880_asus_dac_nids,
3050 .dig_out_nid = ALC880_DIGOUT_NID,
3051 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3052 .channel_mode = alc880_threestack_modes,
3053 .need_dac_fix = 1,
3054 .input_mux = &alc880_capture_source,
3055 .unsol_event = alc880_uniwill_unsol_event,
3056 .init_hook = alc880_uniwill_automute,
3057 },
3058 [ALC880_UNIWILL_P53] = {
3059 .mixers = { alc880_uniwill_p53_mixer },
3060 .init_verbs = { alc880_volume_init_verbs,
3061 alc880_uniwill_p53_init_verbs },
3062 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3063 .dac_nids = alc880_asus_dac_nids,
3064 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3065 .channel_mode = alc880_threestack_modes,
3066 .input_mux = &alc880_capture_source,
3067 .unsol_event = alc880_uniwill_p53_unsol_event,
3068 .init_hook = alc880_uniwill_p53_hp_automute,
3069 },
3070 [ALC880_FUJITSU] = {
f12ab1e0 3071 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3072 alc880_pcbeep_mixer, },
3073 .init_verbs = { alc880_volume_init_verbs,
3074 alc880_uniwill_p53_init_verbs,
3075 alc880_beep_init_verbs },
3076 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3077 .dac_nids = alc880_dac_nids,
d53d7d9e 3078 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3079 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3080 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3081 .input_mux = &alc880_capture_source,
3082 .unsol_event = alc880_uniwill_p53_unsol_event,
3083 .init_hook = alc880_uniwill_p53_hp_automute,
3084 },
df694daa
KY
3085 [ALC880_CLEVO] = {
3086 .mixers = { alc880_three_stack_mixer },
3087 .init_verbs = { alc880_volume_init_verbs,
3088 alc880_pin_clevo_init_verbs },
3089 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3090 .dac_nids = alc880_dac_nids,
3091 .hp_nid = 0x03,
3092 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3093 .channel_mode = alc880_threestack_modes,
4e195a7b 3094 .need_dac_fix = 1,
df694daa
KY
3095 .input_mux = &alc880_capture_source,
3096 },
ae6b813a
TI
3097 [ALC880_LG] = {
3098 .mixers = { alc880_lg_mixer },
3099 .init_verbs = { alc880_volume_init_verbs,
3100 alc880_lg_init_verbs },
3101 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3102 .dac_nids = alc880_lg_dac_nids,
3103 .dig_out_nid = ALC880_DIGOUT_NID,
3104 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3105 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3106 .need_dac_fix = 1,
ae6b813a
TI
3107 .input_mux = &alc880_lg_capture_source,
3108 .unsol_event = alc880_lg_unsol_event,
3109 .init_hook = alc880_lg_automute,
cb53c626
TI
3110#ifdef CONFIG_SND_HDA_POWER_SAVE
3111 .loopbacks = alc880_lg_loopbacks,
3112#endif
ae6b813a 3113 },
d681518a
TI
3114 [ALC880_LG_LW] = {
3115 .mixers = { alc880_lg_lw_mixer },
3116 .init_verbs = { alc880_volume_init_verbs,
3117 alc880_lg_lw_init_verbs },
0a8c5da3 3118 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3119 .dac_nids = alc880_dac_nids,
3120 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3121 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3122 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3123 .input_mux = &alc880_lg_lw_capture_source,
3124 .unsol_event = alc880_lg_lw_unsol_event,
3125 .init_hook = alc880_lg_lw_automute,
3126 },
16ded525
TI
3127#ifdef CONFIG_SND_DEBUG
3128 [ALC880_TEST] = {
e9edcee0
TI
3129 .mixers = { alc880_test_mixer },
3130 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3131 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3132 .dac_nids = alc880_test_dac_nids,
3133 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3134 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3135 .channel_mode = alc880_test_modes,
3136 .input_mux = &alc880_test_capture_source,
3137 },
3138#endif
3139};
3140
e9edcee0
TI
3141/*
3142 * Automatic parse of I/O pins from the BIOS configuration
3143 */
3144
3145#define NUM_CONTROL_ALLOC 32
3146#define NUM_VERB_ALLOC 32
3147
3148enum {
3149 ALC_CTL_WIDGET_VOL,
3150 ALC_CTL_WIDGET_MUTE,
3151 ALC_CTL_BIND_MUTE,
3152};
c8b6bf9b 3153static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3154 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3155 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3156 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3157};
3158
3159/* add dynamic controls */
f12ab1e0
TI
3160static int add_control(struct alc_spec *spec, int type, const char *name,
3161 unsigned long val)
e9edcee0 3162{
c8b6bf9b 3163 struct snd_kcontrol_new *knew;
e9edcee0
TI
3164
3165 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3166 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3167
f12ab1e0
TI
3168 /* array + terminator */
3169 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3170 if (!knew)
e9edcee0
TI
3171 return -ENOMEM;
3172 if (spec->kctl_alloc) {
f12ab1e0
TI
3173 memcpy(knew, spec->kctl_alloc,
3174 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3175 kfree(spec->kctl_alloc);
3176 }
3177 spec->kctl_alloc = knew;
3178 spec->num_kctl_alloc = num;
3179 }
3180
3181 knew = &spec->kctl_alloc[spec->num_kctl_used];
3182 *knew = alc880_control_templates[type];
543537bd 3183 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3184 if (!knew->name)
e9edcee0
TI
3185 return -ENOMEM;
3186 knew->private_value = val;
3187 spec->num_kctl_used++;
3188 return 0;
3189}
3190
3191#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3192#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3193#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3194#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3195#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3196#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3197#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3198#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3199#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3200#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3201#define ALC880_PIN_CD_NID 0x1c
3202
3203/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3204static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3205 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3206{
3207 hda_nid_t nid;
3208 int assigned[4];
3209 int i, j;
3210
3211 memset(assigned, 0, sizeof(assigned));
b0af0de5 3212 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3213
3214 /* check the pins hardwired to audio widget */
3215 for (i = 0; i < cfg->line_outs; i++) {
3216 nid = cfg->line_out_pins[i];
3217 if (alc880_is_fixed_pin(nid)) {
3218 int idx = alc880_fixed_pin_idx(nid);
5014f193 3219 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3220 assigned[idx] = 1;
3221 }
3222 }
3223 /* left pins can be connect to any audio widget */
3224 for (i = 0; i < cfg->line_outs; i++) {
3225 nid = cfg->line_out_pins[i];
3226 if (alc880_is_fixed_pin(nid))
3227 continue;
3228 /* search for an empty channel */
3229 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3230 if (!assigned[j]) {
3231 spec->multiout.dac_nids[i] =
3232 alc880_idx_to_dac(j);
e9edcee0
TI
3233 assigned[j] = 1;
3234 break;
3235 }
3236 }
3237 }
3238 spec->multiout.num_dacs = cfg->line_outs;
3239 return 0;
3240}
3241
3242/* add playback controls from the parsed DAC table */
df694daa
KY
3243static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3244 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3245{
3246 char name[32];
f12ab1e0
TI
3247 static const char *chname[4] = {
3248 "Front", "Surround", NULL /*CLFE*/, "Side"
3249 };
e9edcee0
TI
3250 hda_nid_t nid;
3251 int i, err;
3252
3253 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3254 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3255 continue;
3256 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3257 if (i == 2) {
3258 /* Center/LFE */
f12ab1e0
TI
3259 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3260 "Center Playback Volume",
3261 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3262 HDA_OUTPUT));
3263 if (err < 0)
e9edcee0 3264 return err;
f12ab1e0
TI
3265 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3266 "LFE Playback Volume",
3267 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3268 HDA_OUTPUT));
3269 if (err < 0)
e9edcee0 3270 return err;
f12ab1e0
TI
3271 err = add_control(spec, ALC_CTL_BIND_MUTE,
3272 "Center Playback Switch",
3273 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3274 HDA_INPUT));
3275 if (err < 0)
e9edcee0 3276 return err;
f12ab1e0
TI
3277 err = add_control(spec, ALC_CTL_BIND_MUTE,
3278 "LFE Playback Switch",
3279 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3280 HDA_INPUT));
3281 if (err < 0)
e9edcee0
TI
3282 return err;
3283 } else {
3284 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3285 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3286 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3287 HDA_OUTPUT));
3288 if (err < 0)
e9edcee0
TI
3289 return err;
3290 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3291 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3292 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3293 HDA_INPUT));
3294 if (err < 0)
e9edcee0
TI
3295 return err;
3296 }
3297 }
e9edcee0
TI
3298 return 0;
3299}
3300
8d88bc3d
TI
3301/* add playback controls for speaker and HP outputs */
3302static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3303 const char *pfx)
e9edcee0
TI
3304{
3305 hda_nid_t nid;
3306 int err;
8d88bc3d 3307 char name[32];
e9edcee0 3308
f12ab1e0 3309 if (!pin)
e9edcee0
TI
3310 return 0;
3311
3312 if (alc880_is_fixed_pin(pin)) {
3313 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3314 /* specify the DAC as the extra output */
f12ab1e0 3315 if (!spec->multiout.hp_nid)
e9edcee0 3316 spec->multiout.hp_nid = nid;
82bc955f
TI
3317 else
3318 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3319 /* control HP volume/switch on the output mixer amp */
3320 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3321 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3322 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3323 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3324 if (err < 0)
e9edcee0 3325 return err;
8d88bc3d 3326 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3327 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3328 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3329 if (err < 0)
e9edcee0
TI
3330 return err;
3331 } else if (alc880_is_multi_pin(pin)) {
3332 /* set manual connection */
e9edcee0 3333 /* we have only a switch on HP-out PIN */
8d88bc3d 3334 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3335 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3336 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3337 if (err < 0)
e9edcee0
TI
3338 return err;
3339 }
3340 return 0;
3341}
3342
3343/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3344static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3345 const char *ctlname,
df694daa 3346 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3347{
3348 char name[32];
df694daa 3349 int err;
e9edcee0
TI
3350
3351 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3352 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3353 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3354 if (err < 0)
e9edcee0
TI
3355 return err;
3356 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3357 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3358 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3359 if (err < 0)
e9edcee0
TI
3360 return err;
3361 return 0;
3362}
3363
3364/* create playback/capture controls for input pins */
df694daa
KY
3365static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3366 const struct auto_pin_cfg *cfg)
e9edcee0 3367{
e9edcee0 3368 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3369 int i, err, idx;
e9edcee0
TI
3370
3371 for (i = 0; i < AUTO_PIN_LAST; i++) {
3372 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3373 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3374 err = new_analog_input(spec, cfg->input_pins[i],
3375 auto_pin_cfg_labels[i],
df694daa 3376 idx, 0x0b);
e9edcee0
TI
3377 if (err < 0)
3378 return err;
f12ab1e0
TI
3379 imux->items[imux->num_items].label =
3380 auto_pin_cfg_labels[i];
3381 imux->items[imux->num_items].index =
3382 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3383 imux->num_items++;
3384 }
3385 }
3386 return 0;
3387}
3388
df694daa
KY
3389static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3390 hda_nid_t nid, int pin_type,
e9edcee0
TI
3391 int dac_idx)
3392{
3393 /* set as output */
f12ab1e0
TI
3394 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3395 pin_type);
3396 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3397 AMP_OUT_UNMUTE);
e9edcee0
TI
3398 /* need the manual connection? */
3399 if (alc880_is_multi_pin(nid)) {
3400 struct alc_spec *spec = codec->spec;
3401 int idx = alc880_multi_pin_idx(nid);
3402 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3403 AC_VERB_SET_CONNECT_SEL,
3404 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3405 }
3406}
3407
baba8ee9
TI
3408static int get_pin_type(int line_out_type)
3409{
3410 if (line_out_type == AUTO_PIN_HP_OUT)
3411 return PIN_HP;
3412 else
3413 return PIN_OUT;
3414}
3415
e9edcee0
TI
3416static void alc880_auto_init_multi_out(struct hda_codec *codec)
3417{
3418 struct alc_spec *spec = codec->spec;
3419 int i;
bc9f98a9
KY
3420
3421 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3422 for (i = 0; i < spec->autocfg.line_outs; i++) {
3423 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3424 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3425 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3426 }
3427}
3428
8d88bc3d 3429static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3430{
3431 struct alc_spec *spec = codec->spec;
3432 hda_nid_t pin;
3433
82bc955f 3434 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3435 if (pin) /* connect to front */
3436 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3437 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3438 if (pin) /* connect to front */
3439 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3440}
3441
3442static void alc880_auto_init_analog_input(struct hda_codec *codec)
3443{
3444 struct alc_spec *spec = codec->spec;
3445 int i;
3446
3447 for (i = 0; i < AUTO_PIN_LAST; i++) {
3448 hda_nid_t nid = spec->autocfg.input_pins[i];
3449 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3450 snd_hda_codec_write(codec, nid, 0,
3451 AC_VERB_SET_PIN_WIDGET_CONTROL,
3452 i <= AUTO_PIN_FRONT_MIC ?
3453 PIN_VREF80 : PIN_IN);
e9edcee0 3454 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3455 snd_hda_codec_write(codec, nid, 0,
3456 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3457 AMP_OUT_MUTE);
3458 }
3459 }
3460}
3461
3462/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3463/* return 1 if successful, 0 if the proper config is not found,
3464 * or a negative error code
3465 */
e9edcee0
TI
3466static int alc880_parse_auto_config(struct hda_codec *codec)
3467{
3468 struct alc_spec *spec = codec->spec;
3469 int err;
df694daa 3470 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3471
f12ab1e0
TI
3472 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3473 alc880_ignore);
3474 if (err < 0)
e9edcee0 3475 return err;
f12ab1e0 3476 if (!spec->autocfg.line_outs)
e9edcee0 3477 return 0; /* can't find valid BIOS pin config */
df694daa 3478
f12ab1e0
TI
3479 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3480 if (err < 0)
3481 return err;
3482 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3483 if (err < 0)
3484 return err;
3485 err = alc880_auto_create_extra_out(spec,
3486 spec->autocfg.speaker_pins[0],
3487 "Speaker");
3488 if (err < 0)
3489 return err;
3490 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3491 "Headphone");
3492 if (err < 0)
3493 return err;
3494 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3495 if (err < 0)
e9edcee0
TI
3496 return err;
3497
3498 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3499
3500 if (spec->autocfg.dig_out_pin)
3501 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3502 if (spec->autocfg.dig_in_pin)
3503 spec->dig_in_nid = ALC880_DIGIN_NID;
3504
3505 if (spec->kctl_alloc)
3506 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3507
3508 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3509
a1e8d2da 3510 spec->num_mux_defs = 1;
e9edcee0
TI
3511 spec->input_mux = &spec->private_imux;
3512
3513 return 1;
3514}
3515
ae6b813a
TI
3516/* additional initialization for auto-configuration model */
3517static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3518{
e9edcee0 3519 alc880_auto_init_multi_out(codec);
8d88bc3d 3520 alc880_auto_init_extra_out(codec);
e9edcee0 3521 alc880_auto_init_analog_input(codec);
e9edcee0
TI
3522}
3523
3524/*
3525 * OK, here we have finally the patch for ALC880
3526 */
3527
1da177e4
LT
3528static int patch_alc880(struct hda_codec *codec)
3529{
3530 struct alc_spec *spec;
3531 int board_config;
df694daa 3532 int err;
1da177e4 3533
e560d8d8 3534 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3535 if (spec == NULL)
3536 return -ENOMEM;
3537
3538 codec->spec = spec;
3539
f5fcc13c
TI
3540 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3541 alc880_models,
3542 alc880_cfg_tbl);
3543 if (board_config < 0) {
9c7f852e
TI
3544 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3545 "trying auto-probe from BIOS...\n");
e9edcee0 3546 board_config = ALC880_AUTO;
1da177e4 3547 }
1da177e4 3548
e9edcee0
TI
3549 if (board_config == ALC880_AUTO) {
3550 /* automatic parse from the BIOS config */
3551 err = alc880_parse_auto_config(codec);
3552 if (err < 0) {
3553 alc_free(codec);
3554 return err;
f12ab1e0 3555 } else if (!err) {
9c7f852e
TI
3556 printk(KERN_INFO
3557 "hda_codec: Cannot set up configuration "
3558 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3559 board_config = ALC880_3ST;
3560 }
1da177e4
LT
3561 }
3562
df694daa
KY
3563 if (board_config != ALC880_AUTO)
3564 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3565
3566 spec->stream_name_analog = "ALC880 Analog";
3567 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3568 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3569
3570 spec->stream_name_digital = "ALC880 Digital";
3571 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3572 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3573
f12ab1e0 3574 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3575 /* check whether NID 0x07 is valid */
54d17403 3576 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3577 /* get type */
3578 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3579 if (wcap != AC_WID_AUD_IN) {
3580 spec->adc_nids = alc880_adc_nids_alt;
3581 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3582 spec->mixers[spec->num_mixers] =
3583 alc880_capture_alt_mixer;
e9edcee0
TI
3584 spec->num_mixers++;
3585 } else {
3586 spec->adc_nids = alc880_adc_nids;
3587 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3588 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3589 spec->num_mixers++;
3590 }
3591 }
1da177e4
LT
3592
3593 codec->patch_ops = alc_patch_ops;
e9edcee0 3594 if (board_config == ALC880_AUTO)
ae6b813a 3595 spec->init_hook = alc880_auto_init;
cb53c626
TI
3596#ifdef CONFIG_SND_HDA_POWER_SAVE
3597 if (!spec->loopback.amplist)
3598 spec->loopback.amplist = alc880_loopbacks;
3599#endif
1da177e4
LT
3600
3601 return 0;
3602}
3603
e9edcee0 3604
1da177e4
LT
3605/*
3606 * ALC260 support
3607 */
3608
e9edcee0
TI
3609static hda_nid_t alc260_dac_nids[1] = {
3610 /* front */
3611 0x02,
3612};
3613
3614static hda_nid_t alc260_adc_nids[1] = {
3615 /* ADC0 */
3616 0x04,
3617};
3618
df694daa 3619static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3620 /* ADC1 */
3621 0x05,
3622};
3623
df694daa
KY
3624static hda_nid_t alc260_hp_adc_nids[2] = {
3625 /* ADC1, 0 */
3626 0x05, 0x04
3627};
3628
d57fdac0
JW
3629/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3630 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3631 */
3632static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3633 /* ADC0, ADC1 */
3634 0x04, 0x05
3635};
3636
e9edcee0
TI
3637#define ALC260_DIGOUT_NID 0x03
3638#define ALC260_DIGIN_NID 0x06
3639
3640static struct hda_input_mux alc260_capture_source = {
3641 .num_items = 4,
3642 .items = {
3643 { "Mic", 0x0 },
3644 { "Front Mic", 0x1 },
3645 { "Line", 0x2 },
3646 { "CD", 0x4 },
3647 },
3648};
3649
17e7aec6 3650/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3651 * headphone jack and the internal CD lines since these are the only pins at
3652 * which audio can appear. For flexibility, also allow the option of
3653 * recording the mixer output on the second ADC (ADC0 doesn't have a
3654 * connection to the mixer output).
a9430dd8 3655 */
a1e8d2da
JW
3656static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3657 {
3658 .num_items = 3,
3659 .items = {
3660 { "Mic/Line", 0x0 },
3661 { "CD", 0x4 },
3662 { "Headphone", 0x2 },
3663 },
a9430dd8 3664 },
a1e8d2da
JW
3665 {
3666 .num_items = 4,
3667 .items = {
3668 { "Mic/Line", 0x0 },
3669 { "CD", 0x4 },
3670 { "Headphone", 0x2 },
3671 { "Mixer", 0x5 },
3672 },
3673 },
3674
a9430dd8
JW
3675};
3676
a1e8d2da
JW
3677/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3678 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3679 */
a1e8d2da
JW
3680static struct hda_input_mux alc260_acer_capture_sources[2] = {
3681 {
3682 .num_items = 4,
3683 .items = {
3684 { "Mic", 0x0 },
3685 { "Line", 0x2 },
3686 { "CD", 0x4 },
3687 { "Headphone", 0x5 },
3688 },
3689 },
3690 {
3691 .num_items = 5,
3692 .items = {
3693 { "Mic", 0x0 },
3694 { "Line", 0x2 },
3695 { "CD", 0x4 },
3696 { "Headphone", 0x6 },
3697 { "Mixer", 0x5 },
3698 },
0bfc90e9
JW
3699 },
3700};
1da177e4
LT
3701/*
3702 * This is just place-holder, so there's something for alc_build_pcms to look
3703 * at when it calculates the maximum number of channels. ALC260 has no mixer
3704 * element which allows changing the channel mode, so the verb list is
3705 * never used.
3706 */
d2a6d7dc 3707static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3708 { 2, NULL },
3709};
3710
df694daa
KY
3711
3712/* Mixer combinations
3713 *
3714 * basic: base_output + input + pc_beep + capture
3715 * HP: base_output + input + capture_alt
3716 * HP_3013: hp_3013 + input + capture
3717 * fujitsu: fujitsu + capture
0bfc90e9 3718 * acer: acer + capture
df694daa
KY
3719 */
3720
3721static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3722 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3723 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3725 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3726 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3727 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3728 { } /* end */
f12ab1e0 3729};
1da177e4 3730
df694daa 3731static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
3732 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3733 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3734 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3735 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3737 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3738 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3739 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3740 { } /* end */
3741};
3742
3743static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3744 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3745 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3746 { } /* end */
3747};
3748
3749static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3750 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3751 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3752 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3753 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3754 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3756 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3757 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
3758 { } /* end */
3759};
3760
a1e8d2da
JW
3761/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3762 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3763 */
c8b6bf9b 3764static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 3765 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3766 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 3767 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
3768 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3769 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3770 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3771 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 3772 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
3773 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3774 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3775 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3776 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
3777 { } /* end */
3778};
3779
a1e8d2da
JW
3780/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3781 * versions of the ALC260 don't act on requests to enable mic bias from NID
3782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3783 * datasheet doesn't mention this restriction. At this stage it's not clear
3784 * whether this behaviour is intentional or is a hardware bug in chip
3785 * revisions available in early 2006. Therefore for now allow the
3786 * "Headphone Jack Mode" control to span all choices, but if it turns out
3787 * that the lack of mic bias for this NID is intentional we could change the
3788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3789 *
3790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3791 * don't appear to make the mic bias available from the "line" jack, even
3792 * though the NID used for this jack (0x14) can supply it. The theory is
3793 * that perhaps Acer have included blocking capacitors between the ALC260
3794 * and the output jack. If this turns out to be the case for all such
3795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3796 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
3797 *
3798 * The C20x Tablet series have a mono internal speaker which is controlled
3799 * via the chip's Mono sum widget and pin complex, so include the necessary
3800 * controls for such models. On models without a "mono speaker" the control
3801 * won't do anything.
a1e8d2da 3802 */
0bfc90e9
JW
3803static struct snd_kcontrol_new alc260_acer_mixer[] = {
3804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 3806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
bd869485
JW
3807 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3808 HDA_OUTPUT),
3809 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3810 HDA_INPUT),
0bfc90e9
JW
3811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3819 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3820 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3821 { } /* end */
3822};
3823
bc9f98a9
KY
3824/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3825 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
3826 */
3827static struct snd_kcontrol_new alc260_will_mixer[] = {
3828 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3829 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3831 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3832 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3833 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3834 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3835 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3836 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3837 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3838 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3839 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3840 { } /* end */
3841};
3842
3843/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3844 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3845 */
3846static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3847 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3848 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3850 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3851 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3852 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3853 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3854 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3855 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3856 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3857 { } /* end */
3858};
3859
df694daa
KY
3860/* capture mixer elements */
3861static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
3862 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3863 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
3864 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3865 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
3866 {
3867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
3868 /* The multiple "Capture Source" controls confuse alsamixer
3869 * So call somewhat different..
3870 * FIXME: the controls appear in the "playback" view!
3871 */
3872 /* .name = "Capture Source", */
3873 .name = "Input Source",
3874 .count = 2,
3875 .info = alc_mux_enum_info,
3876 .get = alc_mux_enum_get,
3877 .put = alc_mux_enum_put,
3878 },
3879 { } /* end */
3880};
3881
3882static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3883 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3884 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3885 {
3886 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3887 /* The multiple "Capture Source" controls confuse alsamixer
3888 * So call somewhat different..
3889 * FIXME: the controls appear in the "playback" view!
3890 */
3891 /* .name = "Capture Source", */
3892 .name = "Input Source",
3893 .count = 1,
a9430dd8
JW
3894 .info = alc_mux_enum_info,
3895 .get = alc_mux_enum_get,
3896 .put = alc_mux_enum_put,
3897 },
3898 { } /* end */
3899};
3900
df694daa
KY
3901/*
3902 * initialization verbs
3903 */
1da177e4
LT
3904static struct hda_verb alc260_init_verbs[] = {
3905 /* Line In pin widget for input */
05acb863 3906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3907 /* CD pin widget for input */
05acb863 3908 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3909 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 3910 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 3911 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 3912 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 3913 /* LINE-2 is used for line-out in rear */
05acb863 3914 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 3915 /* select line-out */
fd56f2db 3916 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 3917 /* LINE-OUT pin */
05acb863 3918 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 3919 /* enable HP */
05acb863 3920 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 3921 /* enable Mono */
05acb863
TI
3922 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3923 /* mute capture amp left and right */
16ded525 3924 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
3925 /* set connection select to line in (default select for this ADC) */
3926 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
3927 /* mute capture amp left and right */
3928 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3929 /* set connection select to line in (default select for this ADC) */
3930 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
3931 /* set vol=0 Line-Out mixer amp left and right */
3932 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3933 /* unmute pin widget amp left and right (no gain on this amp) */
3934 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3935 /* set vol=0 HP mixer amp left and right */
3936 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3937 /* unmute pin widget amp left and right (no gain on this amp) */
3938 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3939 /* set vol=0 Mono mixer amp left and right */
3940 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3941 /* unmute pin widget amp left and right (no gain on this amp) */
3942 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3943 /* unmute LINE-2 out pin */
3944 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
3945 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3946 * Line In 2 = 0x03
3947 */
cb53c626
TI
3948 /* mute analog inputs */
3949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3950 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3952 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 3954 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
3955 /* mute Front out path */
3956 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3957 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3958 /* mute Headphone out path */
3959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3960 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3961 /* mute Mono out path */
3962 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3963 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3964 { }
3965};
3966
474167d6 3967#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
3968static struct hda_verb alc260_hp_init_verbs[] = {
3969 /* Headphone and output */
3970 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3971 /* mono output */
3972 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3973 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3974 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3975 /* Mic2 (front panel) pin widget for input and vref at 80% */
3976 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3977 /* Line In pin widget for input */
3978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3979 /* Line-2 pin widget for output */
3980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3981 /* CD pin widget for input */
3982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3983 /* unmute amp left and right */
3984 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3985 /* set connection select to line in (default select for this ADC) */
3986 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3987 /* unmute Line-Out mixer amp left and right (volume = 0) */
3988 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3989 /* mute pin widget amp left and right (no gain on this amp) */
3990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3991 /* unmute HP mixer amp left and right (volume = 0) */
3992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3993 /* mute pin widget amp left and right (no gain on this amp) */
3994 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
3995 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3996 * Line In 2 = 0x03
3997 */
cb53c626
TI
3998 /* mute analog inputs */
3999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4003 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4004 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4005 /* Unmute Front out path */
4006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4008 /* Unmute Headphone out path */
4009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4011 /* Unmute Mono out path */
4012 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4013 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4014 { }
4015};
474167d6 4016#endif
df694daa
KY
4017
4018static struct hda_verb alc260_hp_3013_init_verbs[] = {
4019 /* Line out and output */
4020 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4021 /* mono output */
4022 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4023 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4024 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4025 /* Mic2 (front panel) pin widget for input and vref at 80% */
4026 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4027 /* Line In pin widget for input */
4028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4029 /* Headphone pin widget for output */
4030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4031 /* CD pin widget for input */
4032 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4033 /* unmute amp left and right */
4034 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4035 /* set connection select to line in (default select for this ADC) */
4036 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4037 /* unmute Line-Out mixer amp left and right (volume = 0) */
4038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4039 /* mute pin widget amp left and right (no gain on this amp) */
4040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4041 /* unmute HP mixer amp left and right (volume = 0) */
4042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4043 /* mute pin widget amp left and right (no gain on this amp) */
4044 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4045 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4046 * Line In 2 = 0x03
4047 */
cb53c626
TI
4048 /* mute analog inputs */
4049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4054 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4055 /* Unmute Front out path */
4056 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4057 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4058 /* Unmute Headphone out path */
4059 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4060 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4061 /* Unmute Mono out path */
4062 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4063 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4064 { }
4065};
4066
a9430dd8 4067/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4068 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4069 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4070 */
4071static struct hda_verb alc260_fujitsu_init_verbs[] = {
4072 /* Disable all GPIOs */
4073 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4074 /* Internal speaker is connected to headphone pin */
4075 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4076 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4077 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4078 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4079 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4080 /* Ensure all other unused pins are disabled and muted. */
4081 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4083 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4084 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4085 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4086 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4089
4090 /* Disable digital (SPDIF) pins */
4091 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4092 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4093
f7ace40d
JW
4094 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4095 * when acting as an output.
4096 */
4097 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4098
f7ace40d 4099 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4101 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4102 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4104 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4105 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4106 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4107 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4108 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4109
f7ace40d
JW
4110 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4111 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4112 /* Unmute Line1 pin widget output buffer since it starts as an output.
4113 * If the pin mode is changed by the user the pin mode control will
4114 * take care of enabling the pin's input/output buffers as needed.
4115 * Therefore there's no need to enable the input buffer at this
4116 * stage.
cdcd9268 4117 */
f7ace40d 4118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4119 /* Unmute input buffer of pin widget used for Line-in (no equiv
4120 * mixer ctrl)
4121 */
f7ace40d
JW
4122 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4123
4124 /* Mute capture amp left and right */
4125 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4126 /* Set ADC connection select to match default mixer setting - line
4127 * in (on mic1 pin)
4128 */
4129 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4130
4131 /* Do the same for the second ADC: mute capture input amp and
4132 * set ADC connection to line in (on mic1 pin)
4133 */
4134 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4135 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4136
4137 /* Mute all inputs to mixer widget (even unconnected ones) */
4138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4146
4147 { }
a9430dd8
JW
4148};
4149
0bfc90e9
JW
4150/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4151 * similar laptops (adapted from Fujitsu init verbs).
4152 */
4153static struct hda_verb alc260_acer_init_verbs[] = {
4154 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4155 * the headphone jack. Turn this on and rely on the standard mute
4156 * methods whenever the user wants to turn these outputs off.
4157 */
4158 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4159 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4160 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4161 /* Internal speaker/Headphone jack is connected to Line-out pin */
4162 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4163 /* Internal microphone/Mic jack is connected to Mic1 pin */
4164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4165 /* Line In jack is connected to Line1 pin */
4166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4167 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4168 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4169 /* Ensure all other unused pins are disabled and muted. */
4170 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4171 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4172 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4173 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4176 /* Disable digital (SPDIF) pins */
4177 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4178 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4179
4180 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4181 * bus when acting as outputs.
4182 */
4183 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4184 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4185
4186 /* Start with output sum widgets muted and their output gains at min */
4187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4191 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4193 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4194 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4195 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4196
f12ab1e0
TI
4197 /* Unmute Line-out pin widget amp left and right
4198 * (no equiv mixer ctrl)
4199 */
0bfc90e9 4200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4201 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4202 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4203 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4204 * inputs. If the pin mode is changed by the user the pin mode control
4205 * will take care of enabling the pin's input/output buffers as needed.
4206 * Therefore there's no need to enable the input buffer at this
4207 * stage.
4208 */
4209 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4210 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4211
4212 /* Mute capture amp left and right */
4213 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4214 /* Set ADC connection select to match default mixer setting - mic
4215 * (on mic1 pin)
4216 */
4217 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4218
4219 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4220 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4221 */
4222 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4223 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4224
4225 /* Mute all inputs to mixer widget (even unconnected ones) */
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4234
4235 { }
4236};
4237
bc9f98a9
KY
4238static struct hda_verb alc260_will_verbs[] = {
4239 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4240 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4241 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4242 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4243 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4244 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4245 {}
4246};
4247
4248static struct hda_verb alc260_replacer_672v_verbs[] = {
4249 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4250 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4251 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4252
4253 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4254 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4255 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4256
4257 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4258 {}
4259};
4260
4261/* toggle speaker-output according to the hp-jack state */
4262static void alc260_replacer_672v_automute(struct hda_codec *codec)
4263{
4264 unsigned int present;
4265
4266 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4267 present = snd_hda_codec_read(codec, 0x0f, 0,
4268 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4269 if (present) {
82beb8fd
TI
4270 snd_hda_codec_write_cache(codec, 0x01, 0,
4271 AC_VERB_SET_GPIO_DATA, 1);
4272 snd_hda_codec_write_cache(codec, 0x0f, 0,
4273 AC_VERB_SET_PIN_WIDGET_CONTROL,
4274 PIN_HP);
bc9f98a9 4275 } else {
82beb8fd
TI
4276 snd_hda_codec_write_cache(codec, 0x01, 0,
4277 AC_VERB_SET_GPIO_DATA, 0);
4278 snd_hda_codec_write_cache(codec, 0x0f, 0,
4279 AC_VERB_SET_PIN_WIDGET_CONTROL,
4280 PIN_OUT);
bc9f98a9
KY
4281 }
4282}
4283
4284static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4285 unsigned int res)
4286{
4287 if ((res >> 26) == ALC880_HP_EVENT)
4288 alc260_replacer_672v_automute(codec);
4289}
4290
7cf51e48
JW
4291/* Test configuration for debugging, modelled after the ALC880 test
4292 * configuration.
4293 */
4294#ifdef CONFIG_SND_DEBUG
4295static hda_nid_t alc260_test_dac_nids[1] = {
4296 0x02,
4297};
4298static hda_nid_t alc260_test_adc_nids[2] = {
4299 0x04, 0x05,
4300};
a1e8d2da
JW
4301/* For testing the ALC260, each input MUX needs its own definition since
4302 * the signal assignments are different. This assumes that the first ADC
4303 * is NID 0x04.
17e7aec6 4304 */
a1e8d2da
JW
4305static struct hda_input_mux alc260_test_capture_sources[2] = {
4306 {
4307 .num_items = 7,
4308 .items = {
4309 { "MIC1 pin", 0x0 },
4310 { "MIC2 pin", 0x1 },
4311 { "LINE1 pin", 0x2 },
4312 { "LINE2 pin", 0x3 },
4313 { "CD pin", 0x4 },
4314 { "LINE-OUT pin", 0x5 },
4315 { "HP-OUT pin", 0x6 },
4316 },
4317 },
4318 {
4319 .num_items = 8,
4320 .items = {
4321 { "MIC1 pin", 0x0 },
4322 { "MIC2 pin", 0x1 },
4323 { "LINE1 pin", 0x2 },
4324 { "LINE2 pin", 0x3 },
4325 { "CD pin", 0x4 },
4326 { "Mixer", 0x5 },
4327 { "LINE-OUT pin", 0x6 },
4328 { "HP-OUT pin", 0x7 },
4329 },
7cf51e48
JW
4330 },
4331};
4332static struct snd_kcontrol_new alc260_test_mixer[] = {
4333 /* Output driver widgets */
4334 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4335 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4336 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4337 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4338 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4339 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4340
a1e8d2da
JW
4341 /* Modes for retasking pin widgets
4342 * Note: the ALC260 doesn't seem to act on requests to enable mic
4343 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4344 * mention this restriction. At this stage it's not clear whether
4345 * this behaviour is intentional or is a hardware bug in chip
4346 * revisions available at least up until early 2006. Therefore for
4347 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4348 * choices, but if it turns out that the lack of mic bias for these
4349 * NIDs is intentional we could change their modes from
4350 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4351 */
7cf51e48
JW
4352 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4353 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4354 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4355 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4356 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4357 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4358
4359 /* Loopback mixer controls */
4360 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4361 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4362 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4363 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4364 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4365 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4366 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4367 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4368 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4369 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4370 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4371 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4372 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4373 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4374 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4375 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4376
4377 /* Controls for GPIO pins, assuming they are configured as outputs */
4378 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4379 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4380 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4381 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4382
92621f13
JW
4383 /* Switches to allow the digital IO pins to be enabled. The datasheet
4384 * is ambigious as to which NID is which; testing on laptops which
4385 * make this output available should provide clarification.
4386 */
4387 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4388 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4389
f8225f6d
JW
4390 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4391 * this output to turn on an external amplifier.
4392 */
4393 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4394 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4395
7cf51e48
JW
4396 { } /* end */
4397};
4398static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4399 /* Enable all GPIOs as outputs with an initial value of 0 */
4400 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4401 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4402 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4403
7cf51e48
JW
4404 /* Enable retasking pins as output, initially without power amp */
4405 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4406 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4409 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4410 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4411
92621f13
JW
4412 /* Disable digital (SPDIF) pins initially, but users can enable
4413 * them via a mixer switch. In the case of SPDIF-out, this initverb
4414 * payload also sets the generation to 0, output to be in "consumer"
4415 * PCM format, copyright asserted, no pre-emphasis and no validity
4416 * control.
4417 */
7cf51e48
JW
4418 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4419 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4420
f7ace40d 4421 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4422 * OUT1 sum bus when acting as an output.
4423 */
4424 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4425 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4426 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4427 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4428
4429 /* Start with output sum widgets muted and their output gains at min */
4430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4432 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4435 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4436 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4437 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4438 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4439
cdcd9268
JW
4440 /* Unmute retasking pin widget output buffers since the default
4441 * state appears to be output. As the pin mode is changed by the
4442 * user the pin mode control will take care of enabling the pin's
4443 * input/output buffers as needed.
4444 */
7cf51e48
JW
4445 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4449 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4450 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4451 /* Also unmute the mono-out pin widget */
4452 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4453
7cf51e48
JW
4454 /* Mute capture amp left and right */
4455 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4456 /* Set ADC connection select to match default mixer setting (mic1
4457 * pin)
7cf51e48
JW
4458 */
4459 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4460
4461 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4462 * set ADC connection to mic1 pin
7cf51e48
JW
4463 */
4464 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4465 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4466
4467 /* Mute all inputs to mixer widget (even unconnected ones) */
4468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4470 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4476
4477 { }
4478};
4479#endif
4480
1da177e4
LT
4481static struct hda_pcm_stream alc260_pcm_analog_playback = {
4482 .substreams = 1,
4483 .channels_min = 2,
4484 .channels_max = 2,
1da177e4
LT
4485};
4486
4487static struct hda_pcm_stream alc260_pcm_analog_capture = {
4488 .substreams = 1,
4489 .channels_min = 2,
4490 .channels_max = 2,
1da177e4
LT
4491};
4492
a3bcba38
TI
4493#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4494#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4495
df694daa
KY
4496/*
4497 * for BIOS auto-configuration
4498 */
16ded525 4499
df694daa
KY
4500static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4501 const char *pfx)
4502{
4503 hda_nid_t nid_vol;
4504 unsigned long vol_val, sw_val;
4505 char name[32];
4506 int err;
4507
4508 if (nid >= 0x0f && nid < 0x11) {
4509 nid_vol = nid - 0x7;
4510 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4511 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4512 } else if (nid == 0x11) {
4513 nid_vol = nid - 0x7;
4514 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4515 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4516 } else if (nid >= 0x12 && nid <= 0x15) {
4517 nid_vol = 0x08;
4518 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4519 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4520 } else
4521 return 0; /* N/A */
4522
4523 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4524 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4525 if (err < 0)
df694daa
KY
4526 return err;
4527 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4528 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4529 if (err < 0)
df694daa
KY
4530 return err;
4531 return 1;
4532}
4533
4534/* add playback controls from the parsed DAC table */
4535static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4536 const struct auto_pin_cfg *cfg)
4537{
4538 hda_nid_t nid;
4539 int err;
4540
4541 spec->multiout.num_dacs = 1;
4542 spec->multiout.dac_nids = spec->private_dac_nids;
4543 spec->multiout.dac_nids[0] = 0x02;
4544
4545 nid = cfg->line_out_pins[0];
4546 if (nid) {
4547 err = alc260_add_playback_controls(spec, nid, "Front");
4548 if (err < 0)
4549 return err;
4550 }
4551
82bc955f 4552 nid = cfg->speaker_pins[0];
df694daa
KY
4553 if (nid) {
4554 err = alc260_add_playback_controls(spec, nid, "Speaker");
4555 if (err < 0)
4556 return err;
4557 }
4558
eb06ed8f 4559 nid = cfg->hp_pins[0];
df694daa
KY
4560 if (nid) {
4561 err = alc260_add_playback_controls(spec, nid, "Headphone");
4562 if (err < 0)
4563 return err;
4564 }
f12ab1e0 4565 return 0;
df694daa
KY
4566}
4567
4568/* create playback/capture controls for input pins */
4569static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4570 const struct auto_pin_cfg *cfg)
4571{
df694daa
KY
4572 struct hda_input_mux *imux = &spec->private_imux;
4573 int i, err, idx;
4574
4575 for (i = 0; i < AUTO_PIN_LAST; i++) {
4576 if (cfg->input_pins[i] >= 0x12) {
4577 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4578 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4579 auto_pin_cfg_labels[i], idx,
4580 0x07);
df694daa
KY
4581 if (err < 0)
4582 return err;
f12ab1e0
TI
4583 imux->items[imux->num_items].label =
4584 auto_pin_cfg_labels[i];
df694daa
KY
4585 imux->items[imux->num_items].index = idx;
4586 imux->num_items++;
4587 }
f12ab1e0 4588 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4589 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4590 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4591 auto_pin_cfg_labels[i], idx,
4592 0x07);
df694daa
KY
4593 if (err < 0)
4594 return err;
f12ab1e0
TI
4595 imux->items[imux->num_items].label =
4596 auto_pin_cfg_labels[i];
df694daa
KY
4597 imux->items[imux->num_items].index = idx;
4598 imux->num_items++;
4599 }
4600 }
4601 return 0;
4602}
4603
4604static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4605 hda_nid_t nid, int pin_type,
4606 int sel_idx)
4607{
4608 /* set as output */
f12ab1e0
TI
4609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4610 pin_type);
4611 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4612 AMP_OUT_UNMUTE);
df694daa
KY
4613 /* need the manual connection? */
4614 if (nid >= 0x12) {
4615 int idx = nid - 0x12;
4616 snd_hda_codec_write(codec, idx + 0x0b, 0,
4617 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4618 }
4619}
4620
4621static void alc260_auto_init_multi_out(struct hda_codec *codec)
4622{
4623 struct alc_spec *spec = codec->spec;
4624 hda_nid_t nid;
4625
bc9f98a9 4626 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4627 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4628 if (nid) {
4629 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4630 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4631 }
df694daa 4632
82bc955f 4633 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4634 if (nid)
4635 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4636
eb06ed8f 4637 nid = spec->autocfg.hp_pins[0];
df694daa 4638 if (nid)
baba8ee9 4639 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4640}
df694daa
KY
4641
4642#define ALC260_PIN_CD_NID 0x16
4643static void alc260_auto_init_analog_input(struct hda_codec *codec)
4644{
4645 struct alc_spec *spec = codec->spec;
4646 int i;
4647
4648 for (i = 0; i < AUTO_PIN_LAST; i++) {
4649 hda_nid_t nid = spec->autocfg.input_pins[i];
4650 if (nid >= 0x12) {
f12ab1e0
TI
4651 snd_hda_codec_write(codec, nid, 0,
4652 AC_VERB_SET_PIN_WIDGET_CONTROL,
4653 i <= AUTO_PIN_FRONT_MIC ?
4654 PIN_VREF80 : PIN_IN);
df694daa 4655 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4656 snd_hda_codec_write(codec, nid, 0,
4657 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4658 AMP_OUT_MUTE);
4659 }
4660 }
4661}
4662
4663/*
4664 * generic initialization of ADC, input mixers and output mixers
4665 */
4666static struct hda_verb alc260_volume_init_verbs[] = {
4667 /*
4668 * Unmute ADC0-1 and set the default input to mic-in
4669 */
4670 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4671 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4672 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4673 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4674
4675 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4676 * mixer widget
f12ab1e0
TI
4677 * Note: PASD motherboards uses the Line In 2 as the input for
4678 * front panel mic (mic 2)
df694daa
KY
4679 */
4680 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4681 /* mute analog inputs */
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4686 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4687
4688 /*
4689 * Set up output mixers (0x08 - 0x0a)
4690 */
4691 /* set vol=0 to output mixers */
4692 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4693 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4694 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4695 /* set up input amps for analog loopback */
4696 /* Amp Indices: DAC = 0, mixer = 1 */
4697 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4699 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4700 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4701 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4702 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4703
4704 { }
4705};
4706
4707static int alc260_parse_auto_config(struct hda_codec *codec)
4708{
4709 struct alc_spec *spec = codec->spec;
4710 unsigned int wcap;
4711 int err;
4712 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4713
f12ab1e0
TI
4714 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4715 alc260_ignore);
4716 if (err < 0)
df694daa 4717 return err;
f12ab1e0
TI
4718 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4719 if (err < 0)
4a471b7d 4720 return err;
f12ab1e0 4721 if (!spec->kctl_alloc)
df694daa 4722 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
4723 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4724 if (err < 0)
df694daa
KY
4725 return err;
4726
4727 spec->multiout.max_channels = 2;
4728
4729 if (spec->autocfg.dig_out_pin)
4730 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4731 if (spec->kctl_alloc)
4732 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4733
4734 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4735
a1e8d2da 4736 spec->num_mux_defs = 1;
df694daa
KY
4737 spec->input_mux = &spec->private_imux;
4738
4739 /* check whether NID 0x04 is valid */
4a471b7d 4740 wcap = get_wcaps(codec, 0x04);
df694daa
KY
4741 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4742 if (wcap != AC_WID_AUD_IN) {
4743 spec->adc_nids = alc260_adc_nids_alt;
4744 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4745 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
4746 } else {
4747 spec->adc_nids = alc260_adc_nids;
4748 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4749 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 4750 }
4a471b7d 4751 spec->num_mixers++;
df694daa
KY
4752
4753 return 1;
4754}
4755
ae6b813a
TI
4756/* additional initialization for auto-configuration model */
4757static void alc260_auto_init(struct hda_codec *codec)
df694daa 4758{
df694daa
KY
4759 alc260_auto_init_multi_out(codec);
4760 alc260_auto_init_analog_input(codec);
df694daa
KY
4761}
4762
cb53c626
TI
4763#ifdef CONFIG_SND_HDA_POWER_SAVE
4764static struct hda_amp_list alc260_loopbacks[] = {
4765 { 0x07, HDA_INPUT, 0 },
4766 { 0x07, HDA_INPUT, 1 },
4767 { 0x07, HDA_INPUT, 2 },
4768 { 0x07, HDA_INPUT, 3 },
4769 { 0x07, HDA_INPUT, 4 },
4770 { } /* end */
4771};
4772#endif
4773
df694daa
KY
4774/*
4775 * ALC260 configurations
4776 */
f5fcc13c
TI
4777static const char *alc260_models[ALC260_MODEL_LAST] = {
4778 [ALC260_BASIC] = "basic",
4779 [ALC260_HP] = "hp",
4780 [ALC260_HP_3013] = "hp-3013",
4781 [ALC260_FUJITSU_S702X] = "fujitsu",
4782 [ALC260_ACER] = "acer",
bc9f98a9
KY
4783 [ALC260_WILL] = "will",
4784 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 4785#ifdef CONFIG_SND_DEBUG
f5fcc13c 4786 [ALC260_TEST] = "test",
7cf51e48 4787#endif
f5fcc13c
TI
4788 [ALC260_AUTO] = "auto",
4789};
4790
4791static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 4792 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 4793 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 4794 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 4795 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
4796 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4797 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4798 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4799 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4800 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4801 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4802 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4803 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4804 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4805 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4806 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4807 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 4808 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 4809 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
4810 {}
4811};
4812
4813static struct alc_config_preset alc260_presets[] = {
4814 [ALC260_BASIC] = {
4815 .mixers = { alc260_base_output_mixer,
4816 alc260_input_mixer,
4817 alc260_pc_beep_mixer,
4818 alc260_capture_mixer },
4819 .init_verbs = { alc260_init_verbs },
4820 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4821 .dac_nids = alc260_dac_nids,
4822 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4823 .adc_nids = alc260_adc_nids,
4824 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4825 .channel_mode = alc260_modes,
4826 .input_mux = &alc260_capture_source,
4827 },
4828 [ALC260_HP] = {
4829 .mixers = { alc260_base_output_mixer,
4830 alc260_input_mixer,
4831 alc260_capture_alt_mixer },
474167d6 4832 .init_verbs = { alc260_init_verbs },
df694daa
KY
4833 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4834 .dac_nids = alc260_dac_nids,
4835 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4836 .adc_nids = alc260_hp_adc_nids,
4837 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4838 .channel_mode = alc260_modes,
4839 .input_mux = &alc260_capture_source,
4840 },
4841 [ALC260_HP_3013] = {
4842 .mixers = { alc260_hp_3013_mixer,
4843 alc260_input_mixer,
4844 alc260_capture_alt_mixer },
4845 .init_verbs = { alc260_hp_3013_init_verbs },
4846 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4847 .dac_nids = alc260_dac_nids,
4848 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4849 .adc_nids = alc260_hp_adc_nids,
4850 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4851 .channel_mode = alc260_modes,
4852 .input_mux = &alc260_capture_source,
4853 },
4854 [ALC260_FUJITSU_S702X] = {
4855 .mixers = { alc260_fujitsu_mixer,
4856 alc260_capture_mixer },
4857 .init_verbs = { alc260_fujitsu_init_verbs },
4858 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4859 .dac_nids = alc260_dac_nids,
d57fdac0
JW
4860 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4861 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
4862 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4863 .channel_mode = alc260_modes,
a1e8d2da
JW
4864 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4865 .input_mux = alc260_fujitsu_capture_sources,
df694daa 4866 },
0bfc90e9
JW
4867 [ALC260_ACER] = {
4868 .mixers = { alc260_acer_mixer,
4869 alc260_capture_mixer },
4870 .init_verbs = { alc260_acer_init_verbs },
4871 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4872 .dac_nids = alc260_dac_nids,
4873 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4874 .adc_nids = alc260_dual_adc_nids,
4875 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4876 .channel_mode = alc260_modes,
a1e8d2da
JW
4877 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4878 .input_mux = alc260_acer_capture_sources,
0bfc90e9 4879 },
bc9f98a9
KY
4880 [ALC260_WILL] = {
4881 .mixers = { alc260_will_mixer,
4882 alc260_capture_mixer },
4883 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4884 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4885 .dac_nids = alc260_dac_nids,
4886 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4887 .adc_nids = alc260_adc_nids,
4888 .dig_out_nid = ALC260_DIGOUT_NID,
4889 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4890 .channel_mode = alc260_modes,
4891 .input_mux = &alc260_capture_source,
4892 },
4893 [ALC260_REPLACER_672V] = {
4894 .mixers = { alc260_replacer_672v_mixer,
4895 alc260_capture_mixer },
4896 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4897 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4898 .dac_nids = alc260_dac_nids,
4899 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4900 .adc_nids = alc260_adc_nids,
4901 .dig_out_nid = ALC260_DIGOUT_NID,
4902 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4903 .channel_mode = alc260_modes,
4904 .input_mux = &alc260_capture_source,
4905 .unsol_event = alc260_replacer_672v_unsol_event,
4906 .init_hook = alc260_replacer_672v_automute,
4907 },
7cf51e48
JW
4908#ifdef CONFIG_SND_DEBUG
4909 [ALC260_TEST] = {
4910 .mixers = { alc260_test_mixer,
4911 alc260_capture_mixer },
4912 .init_verbs = { alc260_test_init_verbs },
4913 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4914 .dac_nids = alc260_test_dac_nids,
4915 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4916 .adc_nids = alc260_test_adc_nids,
4917 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4918 .channel_mode = alc260_modes,
a1e8d2da
JW
4919 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4920 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
4921 },
4922#endif
df694daa
KY
4923};
4924
4925static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
4926{
4927 struct alc_spec *spec;
df694daa 4928 int err, board_config;
1da177e4 4929
e560d8d8 4930 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4931 if (spec == NULL)
4932 return -ENOMEM;
4933
4934 codec->spec = spec;
4935
f5fcc13c
TI
4936 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4937 alc260_models,
4938 alc260_cfg_tbl);
4939 if (board_config < 0) {
9c7f852e
TI
4940 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4941 "trying auto-probe from BIOS...\n");
df694daa 4942 board_config = ALC260_AUTO;
16ded525 4943 }
1da177e4 4944
df694daa
KY
4945 if (board_config == ALC260_AUTO) {
4946 /* automatic parse from the BIOS config */
4947 err = alc260_parse_auto_config(codec);
4948 if (err < 0) {
4949 alc_free(codec);
4950 return err;
f12ab1e0 4951 } else if (!err) {
9c7f852e
TI
4952 printk(KERN_INFO
4953 "hda_codec: Cannot set up configuration "
4954 "from BIOS. Using base mode...\n");
df694daa
KY
4955 board_config = ALC260_BASIC;
4956 }
a9430dd8 4957 }
e9edcee0 4958
df694daa
KY
4959 if (board_config != ALC260_AUTO)
4960 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
4961
4962 spec->stream_name_analog = "ALC260 Analog";
4963 spec->stream_analog_playback = &alc260_pcm_analog_playback;
4964 spec->stream_analog_capture = &alc260_pcm_analog_capture;
4965
a3bcba38
TI
4966 spec->stream_name_digital = "ALC260 Digital";
4967 spec->stream_digital_playback = &alc260_pcm_digital_playback;
4968 spec->stream_digital_capture = &alc260_pcm_digital_capture;
4969
1da177e4 4970 codec->patch_ops = alc_patch_ops;
df694daa 4971 if (board_config == ALC260_AUTO)
ae6b813a 4972 spec->init_hook = alc260_auto_init;
cb53c626
TI
4973#ifdef CONFIG_SND_HDA_POWER_SAVE
4974 if (!spec->loopback.amplist)
4975 spec->loopback.amplist = alc260_loopbacks;
4976#endif
1da177e4
LT
4977
4978 return 0;
4979}
4980
e9edcee0 4981
1da177e4
LT
4982/*
4983 * ALC882 support
4984 *
4985 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4986 * configuration. Each pin widget can choose any input DACs and a mixer.
4987 * Each ADC is connected from a mixer of all inputs. This makes possible
4988 * 6-channel independent captures.
4989 *
4990 * In addition, an independent DAC for the multi-playback (not used in this
4991 * driver yet).
4992 */
df694daa
KY
4993#define ALC882_DIGOUT_NID 0x06
4994#define ALC882_DIGIN_NID 0x0a
1da177e4 4995
d2a6d7dc 4996static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
4997 { 8, NULL }
4998};
4999
5000static hda_nid_t alc882_dac_nids[4] = {
5001 /* front, rear, clfe, rear_surr */
5002 0x02, 0x03, 0x04, 0x05
5003};
5004
df694daa
KY
5005/* identical with ALC880 */
5006#define alc882_adc_nids alc880_adc_nids
5007#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4
LT
5008
5009/* input MUX */
5010/* FIXME: should be a matrix-type input source selection */
5011
5012static struct hda_input_mux alc882_capture_source = {
5013 .num_items = 4,
5014 .items = {
5015 { "Mic", 0x0 },
5016 { "Front Mic", 0x1 },
5017 { "Line", 0x2 },
5018 { "CD", 0x4 },
5019 },
5020};
1da177e4
LT
5021#define alc882_mux_enum_info alc_mux_enum_info
5022#define alc882_mux_enum_get alc_mux_enum_get
5023
f12ab1e0
TI
5024static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5025 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5026{
5027 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5028 struct alc_spec *spec = codec->spec;
5029 const struct hda_input_mux *imux = spec->input_mux;
5030 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5031 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5032 hda_nid_t nid = capture_mixers[adc_idx];
5033 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5034 unsigned int i, idx;
5035
5036 idx = ucontrol->value.enumerated.item[0];
5037 if (idx >= imux->num_items)
5038 idx = imux->num_items - 1;
82beb8fd 5039 if (*cur_val == idx)
1da177e4
LT
5040 return 0;
5041 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5042 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5043 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5044 imux->items[i].index,
47fd830a 5045 HDA_AMP_MUTE, v);
1da177e4
LT
5046 }
5047 *cur_val = idx;
5048 return 1;
5049}
5050
272a527c
KY
5051/*
5052 * 2ch mode
5053 */
5054static struct hda_verb alc882_3ST_ch2_init[] = {
5055 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5056 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5057 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5058 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5059 { } /* end */
5060};
5061
5062/*
5063 * 6ch mode
5064 */
5065static struct hda_verb alc882_3ST_ch6_init[] = {
5066 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5067 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5068 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5069 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5070 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5071 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5072 { } /* end */
5073};
5074
5075static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5076 { 2, alc882_3ST_ch2_init },
5077 { 6, alc882_3ST_ch6_init },
5078};
5079
df694daa
KY
5080/*
5081 * 6ch mode
5082 */
5083static struct hda_verb alc882_sixstack_ch6_init[] = {
5084 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5085 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5086 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5087 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5088 { } /* end */
5089};
5090
5091/*
5092 * 8ch mode
5093 */
5094static struct hda_verb alc882_sixstack_ch8_init[] = {
5095 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5096 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5097 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5098 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5099 { } /* end */
5100};
5101
5102static struct hda_channel_mode alc882_sixstack_modes[2] = {
5103 { 6, alc882_sixstack_ch6_init },
5104 { 8, alc882_sixstack_ch8_init },
5105};
5106
87350ad0
TI
5107/*
5108 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5109 */
5110
5111/*
5112 * 2ch mode
5113 */
5114static struct hda_verb alc885_mbp_ch2_init[] = {
5115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5116 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5118 { } /* end */
5119};
5120
5121/*
5122 * 6ch mode
5123 */
5124static struct hda_verb alc885_mbp_ch6_init[] = {
5125 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5126 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5127 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5128 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5129 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5130 { } /* end */
5131};
5132
5133static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5134 { 2, alc885_mbp_ch2_init },
5135 { 6, alc885_mbp_ch6_init },
5136};
5137
5138
1da177e4
LT
5139/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5140 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5141 */
c8b6bf9b 5142static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5145 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5146 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5147 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5148 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5149 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5150 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5151 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5152 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5154 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5155 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5156 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5157 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5159 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5161 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5162 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5163 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5164 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5165 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5166 { } /* end */
5167};
5168
87350ad0
TI
5169static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5170 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5171 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5172 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5173 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5174 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5175 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5177 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5178 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5179 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5180 { } /* end */
5181};
bdd148a3
KY
5182static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5183 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5184 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5185 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5186 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5187 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5188 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5192 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5193 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5194 { } /* end */
5195};
5196
272a527c
KY
5197static struct snd_kcontrol_new alc882_targa_mixer[] = {
5198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5200 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5201 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5202 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5203 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5204 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5207 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5208 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5209 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5210 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5211 { } /* end */
5212};
5213
5214/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5215 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5216 */
5217static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5219 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5221 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5222 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5223 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5225 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5226 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5227 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5230 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5231 { } /* end */
5232};
5233
914759b7
TI
5234static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5235 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5236 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5238 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5239 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5240 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5241 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5245 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5246 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5247 { } /* end */
5248};
5249
df694daa
KY
5250static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5251 {
5252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5253 .name = "Channel Mode",
5254 .info = alc_ch_mode_info,
5255 .get = alc_ch_mode_get,
5256 .put = alc_ch_mode_put,
5257 },
5258 { } /* end */
5259};
5260
1da177e4
LT
5261static struct hda_verb alc882_init_verbs[] = {
5262 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5266 /* Rear mixer */
05acb863
TI
5267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5268 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5270 /* CLFE mixer */
05acb863
TI
5271 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5272 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5274 /* Side mixer */
05acb863
TI
5275 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5276 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5277 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5278
e9edcee0 5279 /* Front Pin: output 0 (0x0c) */
05acb863 5280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5283 /* Rear Pin: output 1 (0x0d) */
05acb863 5284 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5285 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5286 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5287 /* CLFE Pin: output 2 (0x0e) */
05acb863 5288 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5289 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5290 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5291 /* Side Pin: output 3 (0x0f) */
05acb863 5292 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5293 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5294 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5295 /* Mic (rear) pin: input vref at 80% */
16ded525 5296 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5297 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5298 /* Front Mic pin: input vref at 80% */
16ded525 5299 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5301 /* Line In pin: input */
05acb863 5302 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5303 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5304 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5305 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5306 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5308 /* CD pin widget for input */
05acb863 5309 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5310
5311 /* FIXME: use matrix-type input source selection */
5312 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5313 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5318 /* Input mixer2 */
05acb863
TI
5319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5323 /* Input mixer3 */
05acb863
TI
5324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5328 /* ADC1: mute amp left and right */
5329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5330 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5331 /* ADC2: mute amp left and right */
5332 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5333 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5334 /* ADC3: mute amp left and right */
5335 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5336 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5337
5338 { }
5339};
5340
4b146cb0
TI
5341static struct hda_verb alc882_eapd_verbs[] = {
5342 /* change to EAPD mode */
5343 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5344 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5345 { }
4b146cb0
TI
5346};
5347
9102cd1c
TD
5348/* Mac Pro test */
5349static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5351 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5353 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5354 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5355 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5356 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5357 { } /* end */
5358};
5359
5360static struct hda_verb alc882_macpro_init_verbs[] = {
5361 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365 /* Front Pin: output 0 (0x0c) */
5366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5369 /* Front Mic pin: input vref at 80% */
5370 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5371 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5372 /* Speaker: output */
5373 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5374 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5375 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5376 /* Headphone output (output 0 - 0x0c) */
5377 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5378 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5379 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5380
5381 /* FIXME: use matrix-type input source selection */
5382 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5383 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5388 /* Input mixer2 */
5389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5393 /* Input mixer3 */
5394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5398 /* ADC1: mute amp left and right */
5399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5400 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5401 /* ADC2: mute amp left and right */
5402 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5403 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5404 /* ADC3: mute amp left and right */
5405 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5406 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5407
5408 { }
5409};
f12ab1e0 5410
87350ad0
TI
5411/* Macbook Pro rev3 */
5412static struct hda_verb alc885_mbp3_init_verbs[] = {
5413 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5417 /* Rear mixer */
5418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5421 /* Front Pin: output 0 (0x0c) */
5422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5423 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5424 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5425 /* HP Pin: output 0 (0x0d) */
5426 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5428 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5429 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5430 /* Mic (rear) pin: input vref at 80% */
5431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5433 /* Front Mic pin: input vref at 80% */
5434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5435 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5436 /* Line In pin: use output 1 when in LineOut mode */
5437 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5438 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5439 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5440
5441 /* FIXME: use matrix-type input source selection */
5442 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5443 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5448 /* Input mixer2 */
5449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5453 /* Input mixer3 */
5454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5458 /* ADC1: mute amp left and right */
5459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5460 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5461 /* ADC2: mute amp left and right */
5462 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5463 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5464 /* ADC3: mute amp left and right */
5465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5466 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5467
5468 { }
5469};
5470
c54728d8
NF
5471/* iMac 24 mixer. */
5472static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5473 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5474 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5475 { } /* end */
5476};
5477
5478/* iMac 24 init verbs. */
5479static struct hda_verb alc885_imac24_init_verbs[] = {
5480 /* Internal speakers: output 0 (0x0c) */
5481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5482 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5483 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5484 /* Internal speakers: output 0 (0x0c) */
5485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5487 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5488 /* Headphone: output 0 (0x0c) */
5489 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5491 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5493 /* Front Mic: input vref at 80% */
5494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5496 { }
5497};
5498
5499/* Toggle speaker-output according to the hp-jack state */
5500static void alc885_imac24_automute(struct hda_codec *codec)
5501{
5502 unsigned int present;
5503
5504 present = snd_hda_codec_read(codec, 0x14, 0,
5505 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5506 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5507 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5508 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5509 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5510}
5511
5512/* Processes unsolicited events. */
5513static void alc885_imac24_unsol_event(struct hda_codec *codec,
5514 unsigned int res)
5515{
5516 /* Headphone insertion or removal. */
5517 if ((res >> 26) == ALC880_HP_EVENT)
5518 alc885_imac24_automute(codec);
5519}
5520
87350ad0
TI
5521static void alc885_mbp3_automute(struct hda_codec *codec)
5522{
5523 unsigned int present;
5524
5525 present = snd_hda_codec_read(codec, 0x15, 0,
5526 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5527 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5528 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5529 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5530 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5531
5532}
5533static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5534 unsigned int res)
5535{
5536 /* Headphone insertion or removal. */
5537 if ((res >> 26) == ALC880_HP_EVENT)
5538 alc885_mbp3_automute(codec);
5539}
5540
5541
272a527c
KY
5542static struct hda_verb alc882_targa_verbs[] = {
5543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5545
5546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5547 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5548
5549 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5550 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5551 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5552
5553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5554 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5555 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5556 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5557 { } /* end */
5558};
5559
5560/* toggle speaker-output according to the hp-jack state */
5561static void alc882_targa_automute(struct hda_codec *codec)
5562{
5563 unsigned int present;
5564
5565 present = snd_hda_codec_read(codec, 0x14, 0,
5566 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5567 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5568 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5569 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5570 present ? 1 : 3);
272a527c
KY
5571}
5572
5573static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5574{
5575 /* Looks like the unsol event is incompatible with the standard
5576 * definition. 4bit tag is placed at 26 bit!
5577 */
5578 if (((res >> 26) == ALC880_HP_EVENT)) {
5579 alc882_targa_automute(codec);
5580 }
5581}
5582
5583static struct hda_verb alc882_asus_a7j_verbs[] = {
5584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5586
5587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5589 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5590
5591 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5592 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5593 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5594
5595 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5596 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5597 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5598 { } /* end */
5599};
5600
914759b7
TI
5601static struct hda_verb alc882_asus_a7m_verbs[] = {
5602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5604
5605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5608
5609 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5610 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5611 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5612
5613 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5614 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5615 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5616 { } /* end */
5617};
5618
9102cd1c
TD
5619static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5620{
5621 unsigned int gpiostate, gpiomask, gpiodir;
5622
5623 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5624 AC_VERB_GET_GPIO_DATA, 0);
5625
5626 if (!muted)
5627 gpiostate |= (1 << pin);
5628 else
5629 gpiostate &= ~(1 << pin);
5630
5631 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5632 AC_VERB_GET_GPIO_MASK, 0);
5633 gpiomask |= (1 << pin);
5634
5635 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5636 AC_VERB_GET_GPIO_DIRECTION, 0);
5637 gpiodir |= (1 << pin);
5638
5639
5640 snd_hda_codec_write(codec, codec->afg, 0,
5641 AC_VERB_SET_GPIO_MASK, gpiomask);
5642 snd_hda_codec_write(codec, codec->afg, 0,
5643 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5644
5645 msleep(1);
5646
5647 snd_hda_codec_write(codec, codec->afg, 0,
5648 AC_VERB_SET_GPIO_DATA, gpiostate);
5649}
5650
7debbe51
TI
5651/* set up GPIO at initialization */
5652static void alc885_macpro_init_hook(struct hda_codec *codec)
5653{
5654 alc882_gpio_mute(codec, 0, 0);
5655 alc882_gpio_mute(codec, 1, 0);
5656}
5657
5658/* set up GPIO and update auto-muting at initialization */
5659static void alc885_imac24_init_hook(struct hda_codec *codec)
5660{
5661 alc885_macpro_init_hook(codec);
5662 alc885_imac24_automute(codec);
5663}
5664
df694daa
KY
5665/*
5666 * generic initialization of ADC, input mixers and output mixers
5667 */
5668static struct hda_verb alc882_auto_init_verbs[] = {
5669 /*
5670 * Unmute ADC0-2 and set the default input to mic-in
5671 */
5672 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5674 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5676 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 5678
cb53c626 5679 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 5680 * mixer widget
f12ab1e0
TI
5681 * Note: PASD motherboards uses the Line In 2 as the input for
5682 * front panel mic (mic 2)
df694daa
KY
5683 */
5684 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 5690
df694daa
KY
5691 /*
5692 * Set up output mixers (0x0c - 0x0f)
5693 */
5694 /* set vol=0 to output mixers */
5695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5696 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5697 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5698 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5699 /* set up input amps for analog loopback */
5700 /* Amp Indices: DAC = 0, mixer = 1 */
5701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5704 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5705 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5707 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5708 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5709 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5710 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5711
5712 /* FIXME: use matrix-type input source selection */
5713 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5714 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5715 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5716 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5717 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5718 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5719 /* Input mixer2 */
5720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5722 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5723 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5724 /* Input mixer3 */
5725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5729
5730 { }
5731};
5732
5733/* capture mixer elements */
5734static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5735 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5736 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5737 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5738 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5739 {
5740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5741 /* The multiple "Capture Source" controls confuse alsamixer
5742 * So call somewhat different..
5743 * FIXME: the controls appear in the "playback" view!
5744 */
5745 /* .name = "Capture Source", */
5746 .name = "Input Source",
5747 .count = 2,
5748 .info = alc882_mux_enum_info,
5749 .get = alc882_mux_enum_get,
5750 .put = alc882_mux_enum_put,
5751 },
5752 { } /* end */
5753};
5754
5755static struct snd_kcontrol_new alc882_capture_mixer[] = {
5756 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5757 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5758 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5759 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5760 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5761 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5762 {
5763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5764 /* The multiple "Capture Source" controls confuse alsamixer
5765 * So call somewhat different..
5766 * FIXME: the controls appear in the "playback" view!
5767 */
5768 /* .name = "Capture Source", */
5769 .name = "Input Source",
5770 .count = 3,
5771 .info = alc882_mux_enum_info,
5772 .get = alc882_mux_enum_get,
5773 .put = alc882_mux_enum_put,
5774 },
5775 { } /* end */
5776};
5777
cb53c626
TI
5778#ifdef CONFIG_SND_HDA_POWER_SAVE
5779#define alc882_loopbacks alc880_loopbacks
5780#endif
5781
df694daa
KY
5782/* pcm configuration: identiacal with ALC880 */
5783#define alc882_pcm_analog_playback alc880_pcm_analog_playback
5784#define alc882_pcm_analog_capture alc880_pcm_analog_capture
5785#define alc882_pcm_digital_playback alc880_pcm_digital_playback
5786#define alc882_pcm_digital_capture alc880_pcm_digital_capture
5787
5788/*
5789 * configuration and preset
5790 */
f5fcc13c
TI
5791static const char *alc882_models[ALC882_MODEL_LAST] = {
5792 [ALC882_3ST_DIG] = "3stack-dig",
5793 [ALC882_6ST_DIG] = "6stack-dig",
5794 [ALC882_ARIMA] = "arima",
bdd148a3 5795 [ALC882_W2JC] = "w2jc",
0438a00e
TI
5796 [ALC882_TARGA] = "targa",
5797 [ALC882_ASUS_A7J] = "asus-a7j",
5798 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 5799 [ALC885_MACPRO] = "macpro",
87350ad0 5800 [ALC885_MBP3] = "mbp3",
c54728d8 5801 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
5802 [ALC882_AUTO] = "auto",
5803};
5804
5805static struct snd_pci_quirk alc882_cfg_tbl[] = {
5806 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 5807 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 5808 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 5809 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 5810 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 5811 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 5812 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741
TI
5813 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5814 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
5815 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5816 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
5817 {}
5818};
5819
5820static struct alc_config_preset alc882_presets[] = {
5821 [ALC882_3ST_DIG] = {
5822 .mixers = { alc882_base_mixer },
5823 .init_verbs = { alc882_init_verbs },
5824 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5825 .dac_nids = alc882_dac_nids,
5826 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
5827 .dig_in_nid = ALC882_DIGIN_NID,
5828 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5829 .channel_mode = alc882_ch_modes,
4e195a7b 5830 .need_dac_fix = 1,
df694daa
KY
5831 .input_mux = &alc882_capture_source,
5832 },
5833 [ALC882_6ST_DIG] = {
5834 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5835 .init_verbs = { alc882_init_verbs },
5836 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5837 .dac_nids = alc882_dac_nids,
5838 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
5839 .dig_in_nid = ALC882_DIGIN_NID,
5840 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5841 .channel_mode = alc882_sixstack_modes,
5842 .input_mux = &alc882_capture_source,
5843 },
4b146cb0
TI
5844 [ALC882_ARIMA] = {
5845 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5846 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5847 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5848 .dac_nids = alc882_dac_nids,
5849 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5850 .channel_mode = alc882_sixstack_modes,
5851 .input_mux = &alc882_capture_source,
5852 },
bdd148a3
KY
5853 [ALC882_W2JC] = {
5854 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5855 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5856 alc880_gpio1_init_verbs },
5857 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5858 .dac_nids = alc882_dac_nids,
5859 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5860 .channel_mode = alc880_threestack_modes,
5861 .need_dac_fix = 1,
5862 .input_mux = &alc882_capture_source,
5863 .dig_out_nid = ALC882_DIGOUT_NID,
5864 },
87350ad0
TI
5865 [ALC885_MBP3] = {
5866 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5867 .init_verbs = { alc885_mbp3_init_verbs,
5868 alc880_gpio1_init_verbs },
5869 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5870 .dac_nids = alc882_dac_nids,
5871 .channel_mode = alc885_mbp_6ch_modes,
5872 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5873 .input_mux = &alc882_capture_source,
5874 .dig_out_nid = ALC882_DIGOUT_NID,
5875 .dig_in_nid = ALC882_DIGIN_NID,
5876 .unsol_event = alc885_mbp3_unsol_event,
5877 .init_hook = alc885_mbp3_automute,
5878 },
9102cd1c
TD
5879 [ALC885_MACPRO] = {
5880 .mixers = { alc882_macpro_mixer },
5881 .init_verbs = { alc882_macpro_init_verbs },
5882 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5883 .dac_nids = alc882_dac_nids,
5884 .dig_out_nid = ALC882_DIGOUT_NID,
5885 .dig_in_nid = ALC882_DIGIN_NID,
5886 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5887 .channel_mode = alc882_ch_modes,
5888 .input_mux = &alc882_capture_source,
7debbe51 5889 .init_hook = alc885_macpro_init_hook,
9102cd1c 5890 },
c54728d8
NF
5891 [ALC885_IMAC24] = {
5892 .mixers = { alc885_imac24_mixer },
5893 .init_verbs = { alc885_imac24_init_verbs },
5894 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5895 .dac_nids = alc882_dac_nids,
5896 .dig_out_nid = ALC882_DIGOUT_NID,
5897 .dig_in_nid = ALC882_DIGIN_NID,
5898 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5899 .channel_mode = alc882_ch_modes,
5900 .input_mux = &alc882_capture_source,
5901 .unsol_event = alc885_imac24_unsol_event,
7debbe51 5902 .init_hook = alc885_imac24_init_hook,
c54728d8 5903 },
272a527c
KY
5904 [ALC882_TARGA] = {
5905 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5906 alc882_capture_mixer },
5907 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5908 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5909 .dac_nids = alc882_dac_nids,
5910 .dig_out_nid = ALC882_DIGOUT_NID,
5911 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5912 .adc_nids = alc882_adc_nids,
5913 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5914 .channel_mode = alc882_3ST_6ch_modes,
5915 .need_dac_fix = 1,
5916 .input_mux = &alc882_capture_source,
5917 .unsol_event = alc882_targa_unsol_event,
5918 .init_hook = alc882_targa_automute,
5919 },
5920 [ALC882_ASUS_A7J] = {
5921 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5922 alc882_capture_mixer },
5923 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5924 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5925 .dac_nids = alc882_dac_nids,
5926 .dig_out_nid = ALC882_DIGOUT_NID,
5927 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5928 .adc_nids = alc882_adc_nids,
5929 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5930 .channel_mode = alc882_3ST_6ch_modes,
5931 .need_dac_fix = 1,
5932 .input_mux = &alc882_capture_source,
5933 },
914759b7
TI
5934 [ALC882_ASUS_A7M] = {
5935 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5936 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5937 alc880_gpio1_init_verbs,
5938 alc882_asus_a7m_verbs },
5939 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5940 .dac_nids = alc882_dac_nids,
5941 .dig_out_nid = ALC882_DIGOUT_NID,
5942 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5943 .channel_mode = alc880_threestack_modes,
5944 .need_dac_fix = 1,
5945 .input_mux = &alc882_capture_source,
5946 },
df694daa
KY
5947};
5948
5949
f95474ec
TI
5950/*
5951 * Pin config fixes
5952 */
5953enum {
5954 PINFIX_ABIT_AW9D_MAX
5955};
5956
5957static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5958 { 0x15, 0x01080104 }, /* side */
5959 { 0x16, 0x01011012 }, /* rear */
5960 { 0x17, 0x01016011 }, /* clfe */
5961 { }
5962};
5963
5964static const struct alc_pincfg *alc882_pin_fixes[] = {
5965 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5966};
5967
5968static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5969 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5970 {}
5971};
5972
df694daa
KY
5973/*
5974 * BIOS auto configuration
5975 */
5976static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5977 hda_nid_t nid, int pin_type,
5978 int dac_idx)
5979{
5980 /* set as output */
5981 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
5982 int idx;
5983
df694daa
KY
5984 if (spec->multiout.dac_nids[dac_idx] == 0x25)
5985 idx = 4;
5986 else
5987 idx = spec->multiout.dac_nids[dac_idx] - 2;
5988
f12ab1e0
TI
5989 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5990 pin_type);
5991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5992 AMP_OUT_UNMUTE);
df694daa
KY
5993 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5994
5995}
5996
5997static void alc882_auto_init_multi_out(struct hda_codec *codec)
5998{
5999 struct alc_spec *spec = codec->spec;
6000 int i;
6001
bc9f98a9 6002 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6003 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6004 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6005 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6006 if (nid)
baba8ee9 6007 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6008 i);
df694daa
KY
6009 }
6010}
6011
6012static void alc882_auto_init_hp_out(struct hda_codec *codec)
6013{
6014 struct alc_spec *spec = codec->spec;
6015 hda_nid_t pin;
6016
eb06ed8f 6017 pin = spec->autocfg.hp_pins[0];
df694daa 6018 if (pin) /* connect to front */
f12ab1e0
TI
6019 /* use dac 0 */
6020 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
df694daa
KY
6021}
6022
6023#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6024#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6025
6026static void alc882_auto_init_analog_input(struct hda_codec *codec)
6027{
6028 struct alc_spec *spec = codec->spec;
6029 int i;
6030
6031 for (i = 0; i < AUTO_PIN_LAST; i++) {
6032 hda_nid_t nid = spec->autocfg.input_pins[i];
6033 if (alc882_is_input_pin(nid)) {
f12ab1e0
TI
6034 snd_hda_codec_write(codec, nid, 0,
6035 AC_VERB_SET_PIN_WIDGET_CONTROL,
6036 i <= AUTO_PIN_FRONT_MIC ?
6037 PIN_VREF80 : PIN_IN);
df694daa 6038 if (nid != ALC882_PIN_CD_NID)
f12ab1e0
TI
6039 snd_hda_codec_write(codec, nid, 0,
6040 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6041 AMP_OUT_MUTE);
6042 }
6043 }
6044}
6045
776e184e
TI
6046/* add mic boosts if needed */
6047static int alc_auto_add_mic_boost(struct hda_codec *codec)
6048{
6049 struct alc_spec *spec = codec->spec;
6050 int err;
6051 hda_nid_t nid;
6052
6053 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6054 if (nid) {
6055 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6056 "Mic Boost",
6057 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6058 if (err < 0)
6059 return err;
6060 }
6061 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6062 if (nid) {
6063 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6064 "Front Mic Boost",
6065 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6066 if (err < 0)
6067 return err;
6068 }
6069 return 0;
6070}
6071
df694daa
KY
6072/* almost identical with ALC880 parser... */
6073static int alc882_parse_auto_config(struct hda_codec *codec)
6074{
6075 struct alc_spec *spec = codec->spec;
6076 int err = alc880_parse_auto_config(codec);
6077
6078 if (err < 0)
6079 return err;
776e184e
TI
6080 else if (!err)
6081 return 0; /* no config found */
6082
6083 err = alc_auto_add_mic_boost(codec);
6084 if (err < 0)
6085 return err;
6086
6087 /* hack - override the init verbs */
6088 spec->init_verbs[0] = alc882_auto_init_verbs;
6089
6090 return 1; /* config found */
df694daa
KY
6091}
6092
ae6b813a
TI
6093/* additional initialization for auto-configuration model */
6094static void alc882_auto_init(struct hda_codec *codec)
df694daa 6095{
df694daa
KY
6096 alc882_auto_init_multi_out(codec);
6097 alc882_auto_init_hp_out(codec);
6098 alc882_auto_init_analog_input(codec);
df694daa
KY
6099}
6100
df694daa
KY
6101static int patch_alc882(struct hda_codec *codec)
6102{
6103 struct alc_spec *spec;
6104 int err, board_config;
6105
6106 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6107 if (spec == NULL)
6108 return -ENOMEM;
6109
6110 codec->spec = spec;
6111
f5fcc13c
TI
6112 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6113 alc882_models,
6114 alc882_cfg_tbl);
df694daa
KY
6115
6116 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6117 /* Pick up systems that don't supply PCI SSID */
6118 switch (codec->subsystem_id) {
6119 case 0x106b0c00: /* Mac Pro */
6120 board_config = ALC885_MACPRO;
6121 break;
c54728d8
NF
6122 case 0x106b1000: /* iMac 24 */
6123 board_config = ALC885_IMAC24;
6124 break;
87350ad0
TI
6125 case 0x106b2c00: /* Macbook Pro rev3 */
6126 board_config = ALC885_MBP3;
6127 break;
081d17c4
TD
6128 default:
6129 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6130 "trying auto-probe from BIOS...\n");
6131 board_config = ALC882_AUTO;
6132 }
df694daa
KY
6133 }
6134
f95474ec
TI
6135 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6136
df694daa
KY
6137 if (board_config == ALC882_AUTO) {
6138 /* automatic parse from the BIOS config */
6139 err = alc882_parse_auto_config(codec);
6140 if (err < 0) {
6141 alc_free(codec);
6142 return err;
f12ab1e0 6143 } else if (!err) {
9c7f852e
TI
6144 printk(KERN_INFO
6145 "hda_codec: Cannot set up configuration "
6146 "from BIOS. Using base mode...\n");
df694daa
KY
6147 board_config = ALC882_3ST_DIG;
6148 }
6149 }
6150
6151 if (board_config != ALC882_AUTO)
6152 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6153
6154 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6155 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6156 spec->stream_analog_capture = &alc882_pcm_analog_capture;
1da177e4
LT
6157
6158 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6159 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6160 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6161
f12ab1e0 6162 if (!spec->adc_nids && spec->input_mux) {
df694daa 6163 /* check whether NID 0x07 is valid */
4a471b7d 6164 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6165 /* get type */
6166 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6167 if (wcap != AC_WID_AUD_IN) {
6168 spec->adc_nids = alc882_adc_nids_alt;
6169 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
f12ab1e0
TI
6170 spec->mixers[spec->num_mixers] =
6171 alc882_capture_alt_mixer;
df694daa
KY
6172 spec->num_mixers++;
6173 } else {
6174 spec->adc_nids = alc882_adc_nids;
6175 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6176 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6177 spec->num_mixers++;
6178 }
6179 }
1da177e4
LT
6180
6181 codec->patch_ops = alc_patch_ops;
df694daa 6182 if (board_config == ALC882_AUTO)
ae6b813a 6183 spec->init_hook = alc882_auto_init;
cb53c626
TI
6184#ifdef CONFIG_SND_HDA_POWER_SAVE
6185 if (!spec->loopback.amplist)
6186 spec->loopback.amplist = alc882_loopbacks;
6187#endif
df694daa
KY
6188
6189 return 0;
6190}
6191
6192/*
9c7f852e
TI
6193 * ALC883 support
6194 *
6195 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6196 * configuration. Each pin widget can choose any input DACs and a mixer.
6197 * Each ADC is connected from a mixer of all inputs. This makes possible
6198 * 6-channel independent captures.
6199 *
6200 * In addition, an independent DAC for the multi-playback (not used in this
6201 * driver yet).
df694daa 6202 */
9c7f852e
TI
6203#define ALC883_DIGOUT_NID 0x06
6204#define ALC883_DIGIN_NID 0x0a
df694daa 6205
9c7f852e
TI
6206static hda_nid_t alc883_dac_nids[4] = {
6207 /* front, rear, clfe, rear_surr */
6208 0x02, 0x04, 0x03, 0x05
6209};
df694daa 6210
9c7f852e
TI
6211static hda_nid_t alc883_adc_nids[2] = {
6212 /* ADC1-2 */
6213 0x08, 0x09,
6214};
f12ab1e0 6215
9c7f852e
TI
6216/* input MUX */
6217/* FIXME: should be a matrix-type input source selection */
df694daa 6218
9c7f852e
TI
6219static struct hda_input_mux alc883_capture_source = {
6220 .num_items = 4,
6221 .items = {
6222 { "Mic", 0x0 },
6223 { "Front Mic", 0x1 },
6224 { "Line", 0x2 },
6225 { "CD", 0x4 },
6226 },
6227};
bc9f98a9
KY
6228
6229static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6230 .num_items = 2,
6231 .items = {
6232 { "Mic", 0x1 },
6233 { "Line", 0x2 },
6234 },
6235};
6236
272a527c
KY
6237static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6238 .num_items = 4,
6239 .items = {
6240 { "Mic", 0x0 },
6241 { "iMic", 0x1 },
6242 { "Line", 0x2 },
6243 { "CD", 0x4 },
6244 },
6245};
6246
9c7f852e
TI
6247#define alc883_mux_enum_info alc_mux_enum_info
6248#define alc883_mux_enum_get alc_mux_enum_get
df694daa 6249
9c7f852e
TI
6250static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6251 struct snd_ctl_elem_value *ucontrol)
6252{
6253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6254 struct alc_spec *spec = codec->spec;
6255 const struct hda_input_mux *imux = spec->input_mux;
6256 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6257 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6258 hda_nid_t nid = capture_mixers[adc_idx];
6259 unsigned int *cur_val = &spec->cur_mux[adc_idx];
6260 unsigned int i, idx;
6261
6262 idx = ucontrol->value.enumerated.item[0];
6263 if (idx >= imux->num_items)
6264 idx = imux->num_items - 1;
82beb8fd 6265 if (*cur_val == idx)
9c7f852e
TI
6266 return 0;
6267 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
6268 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6269 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 6270 imux->items[i].index,
47fd830a 6271 HDA_AMP_MUTE, v);
9c7f852e
TI
6272 }
6273 *cur_val = idx;
6274 return 1;
6275}
f12ab1e0 6276
9c7f852e
TI
6277/*
6278 * 2ch mode
6279 */
6280static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6281 { 2, NULL }
6282};
6283
6284/*
6285 * 2ch mode
6286 */
6287static struct hda_verb alc883_3ST_ch2_init[] = {
6288 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6289 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6290 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6291 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6292 { } /* end */
6293};
6294
b201131c
TD
6295/*
6296 * 4ch mode
6297 */
6298static struct hda_verb alc883_3ST_ch4_init[] = {
6299 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6300 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6301 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6302 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6303 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6304 { } /* end */
6305};
6306
9c7f852e
TI
6307/*
6308 * 6ch mode
6309 */
6310static struct hda_verb alc883_3ST_ch6_init[] = {
6311 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6312 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6313 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6314 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6315 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6316 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6317 { } /* end */
6318};
6319
b201131c 6320static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6321 { 2, alc883_3ST_ch2_init },
b201131c 6322 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6323 { 6, alc883_3ST_ch6_init },
6324};
6325
6326/*
6327 * 6ch mode
6328 */
6329static struct hda_verb alc883_sixstack_ch6_init[] = {
6330 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6331 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6332 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6333 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6334 { } /* end */
6335};
6336
6337/*
6338 * 8ch mode
6339 */
6340static struct hda_verb alc883_sixstack_ch8_init[] = {
6341 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6342 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6343 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6344 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6345 { } /* end */
6346};
6347
6348static struct hda_channel_mode alc883_sixstack_modes[2] = {
6349 { 6, alc883_sixstack_ch6_init },
6350 { 8, alc883_sixstack_ch8_init },
6351};
6352
b373bdeb
AN
6353static struct hda_verb alc883_medion_eapd_verbs[] = {
6354 /* eanable EAPD on medion laptop */
6355 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6356 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6357 { }
6358};
6359
9c7f852e
TI
6360/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6361 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6362 */
6363
6364static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6371 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6372 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6374 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6376 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6377 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6378 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6379 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6381 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6383 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6384 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6385 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6386 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6387 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6388 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6389 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6390 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6391 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6392 {
6393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6394 /* .name = "Capture Source", */
6395 .name = "Input Source",
6396 .count = 2,
6397 .info = alc883_mux_enum_info,
6398 .get = alc883_mux_enum_get,
6399 .put = alc883_mux_enum_put,
6400 },
df694daa 6401 { } /* end */
834be88d
TI
6402};
6403
a8848bd6
AS
6404static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6405 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6406 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6413 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6414 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6416 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6417 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6420 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6421 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6422 {
6423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6424 /* .name = "Capture Source", */
6425 .name = "Input Source",
6426 .count = 2,
6427 .info = alc883_mux_enum_info,
6428 .get = alc883_mux_enum_get,
6429 .put = alc883_mux_enum_put,
6430 },
6431 { } /* end */
6432};
6433
9c7f852e
TI
6434static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6436 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6438 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6439 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6440 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6441 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6443 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6444 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6446 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6447 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6448 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6449 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6450 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6451 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6452 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6453 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6454 {
6455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6456 /* .name = "Capture Source", */
6457 .name = "Input Source",
6458 .count = 2,
6459 .info = alc883_mux_enum_info,
6460 .get = alc883_mux_enum_get,
6461 .put = alc883_mux_enum_put,
6462 },
6463 { } /* end */
6464};
df694daa 6465
9c7f852e
TI
6466static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6467 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6468 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6469 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6470 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6471 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6472 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6473 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6474 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6476 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6477 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6478 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6479 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6481 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6483 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6484 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6486 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6487 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6488 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6489 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6490 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6491 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6492 {
6493 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6494 /* .name = "Capture Source", */
6495 .name = "Input Source",
6496 .count = 2,
6497 .info = alc883_mux_enum_info,
6498 .get = alc883_mux_enum_get,
6499 .put = alc883_mux_enum_put,
6500 },
6501 { } /* end */
6502};
6503
d1d985f0 6504static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6505 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6506 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6507 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6508 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6509 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6510 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6511 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6512 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6514 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6515 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6516 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6517 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6518 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6519 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6520 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6522 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6523 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6524 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6525 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6526 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6527 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6528
6529 {
6530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6531 /* .name = "Capture Source", */
6532 .name = "Input Source",
6533 .count = 1,
6534 .info = alc883_mux_enum_info,
6535 .get = alc883_mux_enum_get,
6536 .put = alc883_mux_enum_put,
6537 },
6538 { } /* end */
6539};
6540
ccc656ce
KY
6541static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6542 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6544 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6545 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6546 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6547 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6548 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6549 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6550 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6551 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6552 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6553 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6554 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6555 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6556 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6558 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6559 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6560 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6561 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6562 {
6563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6564 /* .name = "Capture Source", */
6565 .name = "Input Source",
6566 .count = 2,
6567 .info = alc883_mux_enum_info,
6568 .get = alc883_mux_enum_get,
6569 .put = alc883_mux_enum_put,
6570 },
6571 { } /* end */
f12ab1e0 6572};
ccc656ce
KY
6573
6574static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6575 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6577 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6581 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6583 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6584 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6585 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6586 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6587 {
6588 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6589 /* .name = "Capture Source", */
6590 .name = "Input Source",
6591 .count = 2,
6592 .info = alc883_mux_enum_info,
6593 .get = alc883_mux_enum_get,
6594 .put = alc883_mux_enum_put,
6595 },
6596 { } /* end */
f12ab1e0 6597};
ccc656ce 6598
bc9f98a9
KY
6599static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6600 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6601 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6602 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6603 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6604 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6605 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6606 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6607 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6608 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6609 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6610 {
6611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6612 /* .name = "Capture Source", */
6613 .name = "Input Source",
6614 .count = 1,
6615 .info = alc883_mux_enum_info,
6616 .get = alc883_mux_enum_get,
6617 .put = alc883_mux_enum_put,
6618 },
6619 { } /* end */
f12ab1e0 6620};
bc9f98a9 6621
272a527c
KY
6622static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6623 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6624 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6630 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6631 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6632 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6633 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6634 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6635 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6636 {
6637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6638 /* .name = "Capture Source", */
6639 .name = "Input Source",
6640 .count = 2,
6641 .info = alc883_mux_enum_info,
6642 .get = alc883_mux_enum_get,
6643 .put = alc883_mux_enum_put,
6644 },
6645 { } /* end */
6646};
6647
6648static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6649 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6651 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6652 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6653 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6656 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6657 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6658 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6659 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6660 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6661 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6662 {
6663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6664 /* .name = "Capture Source", */
6665 .name = "Input Source",
6666 .count = 2,
6667 .info = alc883_mux_enum_info,
6668 .get = alc883_mux_enum_get,
6669 .put = alc883_mux_enum_put,
6670 },
6671 { } /* end */
6672};
6673
4723c022 6674static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
cd1e3b40
CM
6675 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6676 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6677 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6678 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6679 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6680 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6681 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6682 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6683 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6684 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6686 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6687 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6688 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6689 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6695 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6696 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6697 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6698 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6699 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6700 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6701 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6702 {
6703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6704 /* .name = "Capture Source", */
6705 .name = "Input Source",
6706 .count = 2,
6707 .info = alc883_mux_enum_info,
6708 .get = alc883_mux_enum_get,
6709 .put = alc883_mux_enum_put,
6710 },
6711 { } /* end */
6712};
6713
4723c022 6714static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
8341de60
CM
6715 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6716 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6717 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6718 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6719 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6721 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6722 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6726 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6727 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6729 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6731 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6732 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6733 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6734 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6735 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6736 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6737 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6738 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6739 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6740 {
6741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6742 /* .name = "Capture Source", */
6743 .name = "Input Source",
6744 .count = 2,
6745 .info = alc883_mux_enum_info,
6746 .get = alc883_mux_enum_get,
6747 .put = alc883_mux_enum_put,
6748 },
6749 { } /* end */
6750};
6751
2880a867 6752static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
6753 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6754 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 6755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
6756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6757 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
6758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6759 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
6761 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6762 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6763 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6764 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6765 {
6766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6767 /* .name = "Capture Source", */
6768 .name = "Input Source",
6769 .count = 2,
6770 .info = alc883_mux_enum_info,
6771 .get = alc883_mux_enum_get,
6772 .put = alc883_mux_enum_put,
6773 },
6774 { } /* end */
d1a991a6 6775};
2880a867 6776
9c7f852e
TI
6777static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6778 {
6779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6780 .name = "Channel Mode",
6781 .info = alc_ch_mode_info,
6782 .get = alc_ch_mode_get,
6783 .put = alc_ch_mode_put,
6784 },
6785 { } /* end */
6786};
6787
6788static struct hda_verb alc883_init_verbs[] = {
6789 /* ADC1: mute amp left and right */
6790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 6791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
6792 /* ADC2: mute amp left and right */
6793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 6794 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
6795 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6798 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6799 /* Rear mixer */
6800 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6802 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6803 /* CLFE mixer */
6804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6805 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6807 /* Side mixer */
6808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6809 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 6811
cb53c626
TI
6812 /* mute analog input loopbacks */
6813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6816 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6817 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 6818
9c7f852e
TI
6819 /* Front Pin: output 0 (0x0c) */
6820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6822 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6823 /* Rear Pin: output 1 (0x0d) */
6824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6827 /* CLFE Pin: output 2 (0x0e) */
6828 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6830 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6831 /* Side Pin: output 3 (0x0f) */
6832 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6834 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6835 /* Mic (rear) pin: input vref at 80% */
6836 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6837 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6838 /* Front Mic pin: input vref at 80% */
6839 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6840 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6841 /* Line In pin: input */
6842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6843 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6844 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6846 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6847 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6848 /* CD pin widget for input */
6849 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6850
6851 /* FIXME: use matrix-type input source selection */
6852 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6853 /* Input mixer2 */
6854 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6855 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6856 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6857 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6858 /* Input mixer3 */
6859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6863 { }
6864};
6865
a8848bd6
AS
6866/* toggle speaker-output according to the hp-jack state */
6867static void alc883_mitac_hp_automute(struct hda_codec *codec)
6868{
6869 unsigned int present;
6870
6871 present = snd_hda_codec_read(codec, 0x15, 0,
6872 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6873 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6874 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6875 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
6876 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6877}
6878
6879/* auto-toggle front mic */
6880/*
6881static void alc883_mitac_mic_automute(struct hda_codec *codec)
6882{
6883 unsigned int present;
6884 unsigned char bits;
6885
6886 present = snd_hda_codec_read(codec, 0x18, 0,
6887 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6888 bits = present ? HDA_AMP_MUTE : 0;
6889 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
6890}
6891*/
6892
6893static void alc883_mitac_automute(struct hda_codec *codec)
6894{
6895 alc883_mitac_hp_automute(codec);
6896 /* alc883_mitac_mic_automute(codec); */
6897}
6898
6899static void alc883_mitac_unsol_event(struct hda_codec *codec,
6900 unsigned int res)
6901{
6902 switch (res >> 26) {
6903 case ALC880_HP_EVENT:
6904 alc883_mitac_hp_automute(codec);
6905 break;
6906 case ALC880_MIC_EVENT:
6907 /* alc883_mitac_mic_automute(codec); */
6908 break;
6909 }
6910}
6911
6912static struct hda_verb alc883_mitac_verbs[] = {
6913 /* HP */
6914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6916 /* Subwoofer */
6917 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
6918 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6919
6920 /* enable unsolicited event */
6921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6922 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
6923
6924 { } /* end */
6925};
6926
ccc656ce
KY
6927static struct hda_verb alc883_tagra_verbs[] = {
6928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6930
6931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6932 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6933
6934 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6935 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6936 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6937
6938 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
6939 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6940 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6941 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
6942
6943 { } /* end */
6944};
6945
bc9f98a9
KY
6946static struct hda_verb alc883_lenovo_101e_verbs[] = {
6947 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6949 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6950 { } /* end */
6951};
6952
272a527c
KY
6953static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6956 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6958 { } /* end */
6959};
6960
6961static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6964 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6965 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6966 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6967 { } /* end */
6968};
6969
189609ae
KY
6970static struct hda_verb alc883_haier_w66_verbs[] = {
6971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6973
6974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6975
6976 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6977 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6978 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6980 { } /* end */
6981};
6982
4723c022 6983static struct hda_verb alc888_6st_hp_verbs[] = {
cd1e3b40
CM
6984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
6986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
6987 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
6988 { }
6989};
6990
4723c022 6991static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60
CM
6992 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6993 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
6994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
6995 { }
6996};
6997
4723c022 6998static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
6999 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7000 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7001 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7002 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7003 { }
7004};
7005
4723c022 7006static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7007 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7008 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7009 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7010 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7011 { }
7012};
7013
4723c022
CM
7014static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7015 { 2, alc888_3st_hp_2ch_init },
7016 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7017};
7018
272a527c
KY
7019/* toggle front-jack and RCA according to the hp-jack state */
7020static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7021{
7022 unsigned int present;
7023
7024 present = snd_hda_codec_read(codec, 0x1b, 0,
7025 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7026 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7027 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7028 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7029 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7030}
7031
7032/* toggle RCA according to the front-jack state */
7033static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7034{
7035 unsigned int present;
7036
7037 present = snd_hda_codec_read(codec, 0x14, 0,
7038 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7039 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7040 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7041}
47fd830a 7042
272a527c
KY
7043static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7044 unsigned int res)
7045{
7046 if ((res >> 26) == ALC880_HP_EVENT)
7047 alc888_lenovo_ms7195_front_automute(codec);
7048 if ((res >> 26) == ALC880_FRONT_EVENT)
7049 alc888_lenovo_ms7195_rca_automute(codec);
7050}
7051
7052static struct hda_verb alc883_medion_md2_verbs[] = {
7053 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7054 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7055
7056 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7057
7058 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7059 { } /* end */
7060};
7061
7062/* toggle speaker-output according to the hp-jack state */
7063static void alc883_medion_md2_automute(struct hda_codec *codec)
7064{
7065 unsigned int present;
7066
7067 present = snd_hda_codec_read(codec, 0x14, 0,
7068 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7069 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7070 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7071}
7072
7073static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7074 unsigned int res)
7075{
7076 if ((res >> 26) == ALC880_HP_EVENT)
7077 alc883_medion_md2_automute(codec);
7078}
7079
ccc656ce
KY
7080/* toggle speaker-output according to the hp-jack state */
7081static void alc883_tagra_automute(struct hda_codec *codec)
7082{
7083 unsigned int present;
f12ab1e0 7084 unsigned char bits;
ccc656ce
KY
7085
7086 present = snd_hda_codec_read(codec, 0x14, 0,
7087 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7088 bits = present ? HDA_AMP_MUTE : 0;
7089 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7090 HDA_AMP_MUTE, bits);
82beb8fd
TI
7091 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7092 present ? 1 : 3);
ccc656ce
KY
7093}
7094
7095static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7096{
7097 if ((res >> 26) == ALC880_HP_EVENT)
7098 alc883_tagra_automute(codec);
7099}
7100
189609ae
KY
7101static void alc883_haier_w66_automute(struct hda_codec *codec)
7102{
7103 unsigned int present;
7104 unsigned char bits;
7105
7106 present = snd_hda_codec_read(codec, 0x1b, 0,
7107 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7108 bits = present ? 0x80 : 0;
7109 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7110 0x80, bits);
7111}
7112
7113static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7114 unsigned int res)
7115{
7116 if ((res >> 26) == ALC880_HP_EVENT)
7117 alc883_haier_w66_automute(codec);
7118}
7119
bc9f98a9
KY
7120static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7121{
7122 unsigned int present;
f12ab1e0 7123 unsigned char bits;
bc9f98a9
KY
7124
7125 present = snd_hda_codec_read(codec, 0x14, 0,
7126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7127 bits = present ? HDA_AMP_MUTE : 0;
7128 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7129 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7130}
7131
7132static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7133{
7134 unsigned int present;
f12ab1e0 7135 unsigned char bits;
bc9f98a9
KY
7136
7137 present = snd_hda_codec_read(codec, 0x1b, 0,
7138 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7139 bits = present ? HDA_AMP_MUTE : 0;
7140 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7141 HDA_AMP_MUTE, bits);
7142 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7143 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7144}
7145
7146static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7147 unsigned int res)
7148{
7149 if ((res >> 26) == ALC880_HP_EVENT)
7150 alc883_lenovo_101e_all_automute(codec);
7151 if ((res >> 26) == ALC880_FRONT_EVENT)
7152 alc883_lenovo_101e_ispeaker_automute(codec);
7153}
7154
676a9b53
TI
7155/* toggle speaker-output according to the hp-jack state */
7156static void alc883_acer_aspire_automute(struct hda_codec *codec)
7157{
7158 unsigned int present;
7159
7160 present = snd_hda_codec_read(codec, 0x14, 0,
7161 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7162 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7163 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7164 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7165 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7166}
7167
7168static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7169 unsigned int res)
7170{
7171 if ((res >> 26) == ALC880_HP_EVENT)
7172 alc883_acer_aspire_automute(codec);
7173}
7174
d1a991a6
KY
7175static struct hda_verb alc883_acer_eapd_verbs[] = {
7176 /* HP Pin: output 0 (0x0c) */
7177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7178 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7179 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7180 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7182 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7184 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7185 /* eanable EAPD on medion laptop */
7186 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7187 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7188 /* enable unsolicited event */
7189 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7190 { }
7191};
7192
9c7f852e
TI
7193/*
7194 * generic initialization of ADC, input mixers and output mixers
7195 */
7196static struct hda_verb alc883_auto_init_verbs[] = {
7197 /*
7198 * Unmute ADC0-2 and set the default input to mic-in
7199 */
7200 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7201 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7202 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7203 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7204
cb53c626 7205 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7206 * mixer widget
f12ab1e0
TI
7207 * Note: PASD motherboards uses the Line In 2 as the input for
7208 * front panel mic (mic 2)
9c7f852e
TI
7209 */
7210 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7215 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7216
7217 /*
7218 * Set up output mixers (0x0c - 0x0f)
7219 */
7220 /* set vol=0 to output mixers */
7221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7223 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7225 /* set up input amps for analog loopback */
7226 /* Amp Indices: DAC = 0, mixer = 1 */
7227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7230 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7231 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7235 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7236 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7237
7238 /* FIXME: use matrix-type input source selection */
7239 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7240 /* Input mixer1 */
7241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7244 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7245 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7246 /* Input mixer2 */
7247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7250 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7251 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7252
7253 { }
7254};
7255
7256/* capture mixer elements */
7257static struct snd_kcontrol_new alc883_capture_mixer[] = {
7258 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7259 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7260 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7261 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7262 {
7263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7264 /* The multiple "Capture Source" controls confuse alsamixer
7265 * So call somewhat different..
7266 * FIXME: the controls appear in the "playback" view!
7267 */
7268 /* .name = "Capture Source", */
7269 .name = "Input Source",
7270 .count = 2,
7271 .info = alc882_mux_enum_info,
7272 .get = alc882_mux_enum_get,
7273 .put = alc882_mux_enum_put,
7274 },
7275 { } /* end */
7276};
7277
cb53c626
TI
7278#ifdef CONFIG_SND_HDA_POWER_SAVE
7279#define alc883_loopbacks alc880_loopbacks
7280#endif
7281
9c7f852e
TI
7282/* pcm configuration: identiacal with ALC880 */
7283#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7284#define alc883_pcm_analog_capture alc880_pcm_analog_capture
7285#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7286#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7287
7288/*
7289 * configuration and preset
7290 */
f5fcc13c
TI
7291static const char *alc883_models[ALC883_MODEL_LAST] = {
7292 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7293 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7294 [ALC883_3ST_6ch] = "3stack-6ch",
7295 [ALC883_6ST_DIG] = "6stack-dig",
7296 [ALC883_TARGA_DIG] = "targa-dig",
7297 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7298 [ALC883_ACER] = "acer",
2880a867 7299 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7300 [ALC883_MEDION] = "medion",
272a527c 7301 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7302 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7303 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7304 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7305 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7306 [ALC883_HAIER_W66] = "haier-w66",
4723c022
CM
7307 [ALC888_6ST_HP] = "6stack-hp",
7308 [ALC888_3ST_HP] = "3stack-hp",
a8848bd6 7309 [ALC883_MITAC] = "mitac",
f5fcc13c
TI
7310 [ALC883_AUTO] = "auto",
7311};
7312
7313static struct snd_pci_quirk alc883_cfg_tbl[] = {
7314 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7315 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7316 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7317 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7318 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
febe3375 7319 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7320 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7321 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7322 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7323 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
f5fcc13c 7324 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7325 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7326 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7327 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7328 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7329 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7330 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7331 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7332 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
f5fcc13c 7333 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7334 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7335 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7336 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7337 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7338 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7339 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7340 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7341 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7342 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7343 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7344 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7345 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7346 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7347 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741
TI
7348 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7349 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7350 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7351 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
272a527c 7352 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7353 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7354 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7355 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7356 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
189609ae 7357 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7358 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7359 {}
7360};
7361
7362static struct alc_config_preset alc883_presets[] = {
7363 [ALC883_3ST_2ch_DIG] = {
7364 .mixers = { alc883_3ST_2ch_mixer },
7365 .init_verbs = { alc883_init_verbs },
7366 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7367 .dac_nids = alc883_dac_nids,
7368 .dig_out_nid = ALC883_DIGOUT_NID,
7369 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7370 .adc_nids = alc883_adc_nids,
7371 .dig_in_nid = ALC883_DIGIN_NID,
7372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7373 .channel_mode = alc883_3ST_2ch_modes,
7374 .input_mux = &alc883_capture_source,
7375 },
7376 [ALC883_3ST_6ch_DIG] = {
7377 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7378 .init_verbs = { alc883_init_verbs },
7379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7380 .dac_nids = alc883_dac_nids,
7381 .dig_out_nid = ALC883_DIGOUT_NID,
7382 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7383 .adc_nids = alc883_adc_nids,
7384 .dig_in_nid = ALC883_DIGIN_NID,
7385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7386 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7387 .need_dac_fix = 1,
9c7f852e 7388 .input_mux = &alc883_capture_source,
f12ab1e0 7389 },
9c7f852e
TI
7390 [ALC883_3ST_6ch] = {
7391 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7392 .init_verbs = { alc883_init_verbs },
7393 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7394 .dac_nids = alc883_dac_nids,
7395 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7396 .adc_nids = alc883_adc_nids,
7397 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7398 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7399 .need_dac_fix = 1,
9c7f852e 7400 .input_mux = &alc883_capture_source,
f12ab1e0 7401 },
9c7f852e
TI
7402 [ALC883_6ST_DIG] = {
7403 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7404 .init_verbs = { alc883_init_verbs },
7405 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7406 .dac_nids = alc883_dac_nids,
7407 .dig_out_nid = ALC883_DIGOUT_NID,
7408 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7409 .adc_nids = alc883_adc_nids,
7410 .dig_in_nid = ALC883_DIGIN_NID,
7411 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7412 .channel_mode = alc883_sixstack_modes,
7413 .input_mux = &alc883_capture_source,
7414 },
ccc656ce
KY
7415 [ALC883_TARGA_DIG] = {
7416 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7417 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7418 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7419 .dac_nids = alc883_dac_nids,
7420 .dig_out_nid = ALC883_DIGOUT_NID,
7421 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7422 .adc_nids = alc883_adc_nids,
7423 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7424 .channel_mode = alc883_3ST_6ch_modes,
7425 .need_dac_fix = 1,
7426 .input_mux = &alc883_capture_source,
7427 .unsol_event = alc883_tagra_unsol_event,
7428 .init_hook = alc883_tagra_automute,
7429 },
7430 [ALC883_TARGA_2ch_DIG] = {
7431 .mixers = { alc883_tagra_2ch_mixer},
7432 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7434 .dac_nids = alc883_dac_nids,
7435 .dig_out_nid = ALC883_DIGOUT_NID,
7436 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7437 .adc_nids = alc883_adc_nids,
7438 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7439 .channel_mode = alc883_3ST_2ch_modes,
7440 .input_mux = &alc883_capture_source,
7441 .unsol_event = alc883_tagra_unsol_event,
7442 .init_hook = alc883_tagra_automute,
7443 },
bab282b9 7444 [ALC883_ACER] = {
676a9b53 7445 .mixers = { alc883_base_mixer },
bab282b9
VA
7446 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7447 * and the headphone jack. Turn this on and rely on the
7448 * standard mute methods whenever the user wants to turn
7449 * these outputs off.
7450 */
7451 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7452 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7453 .dac_nids = alc883_dac_nids,
7454 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7455 .adc_nids = alc883_adc_nids,
7456 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7457 .channel_mode = alc883_3ST_2ch_modes,
7458 .input_mux = &alc883_capture_source,
7459 },
2880a867 7460 [ALC883_ACER_ASPIRE] = {
676a9b53 7461 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7462 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7463 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7464 .dac_nids = alc883_dac_nids,
7465 .dig_out_nid = ALC883_DIGOUT_NID,
7466 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7467 .adc_nids = alc883_adc_nids,
7468 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7469 .channel_mode = alc883_3ST_2ch_modes,
7470 .input_mux = &alc883_capture_source,
676a9b53
TI
7471 .unsol_event = alc883_acer_aspire_unsol_event,
7472 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7473 },
c07584c8
TD
7474 [ALC883_MEDION] = {
7475 .mixers = { alc883_fivestack_mixer,
7476 alc883_chmode_mixer },
7477 .init_verbs = { alc883_init_verbs,
b373bdeb 7478 alc883_medion_eapd_verbs },
c07584c8
TD
7479 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7480 .dac_nids = alc883_dac_nids,
7481 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7482 .adc_nids = alc883_adc_nids,
7483 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7484 .channel_mode = alc883_sixstack_modes,
7485 .input_mux = &alc883_capture_source,
b373bdeb 7486 },
272a527c
KY
7487 [ALC883_MEDION_MD2] = {
7488 .mixers = { alc883_medion_md2_mixer},
7489 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7491 .dac_nids = alc883_dac_nids,
7492 .dig_out_nid = ALC883_DIGOUT_NID,
7493 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7494 .adc_nids = alc883_adc_nids,
7495 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7496 .channel_mode = alc883_3ST_2ch_modes,
7497 .input_mux = &alc883_capture_source,
7498 .unsol_event = alc883_medion_md2_unsol_event,
7499 .init_hook = alc883_medion_md2_automute,
7500 },
b373bdeb 7501 [ALC883_LAPTOP_EAPD] = {
676a9b53 7502 .mixers = { alc883_base_mixer },
b373bdeb
AN
7503 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7504 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7505 .dac_nids = alc883_dac_nids,
7506 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7507 .adc_nids = alc883_adc_nids,
7508 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7509 .channel_mode = alc883_3ST_2ch_modes,
7510 .input_mux = &alc883_capture_source,
7511 },
bc9f98a9
KY
7512 [ALC883_LENOVO_101E_2ch] = {
7513 .mixers = { alc883_lenovo_101e_2ch_mixer},
7514 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7515 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7516 .dac_nids = alc883_dac_nids,
7517 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7518 .adc_nids = alc883_adc_nids,
7519 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7520 .channel_mode = alc883_3ST_2ch_modes,
7521 .input_mux = &alc883_lenovo_101e_capture_source,
7522 .unsol_event = alc883_lenovo_101e_unsol_event,
7523 .init_hook = alc883_lenovo_101e_all_automute,
7524 },
272a527c
KY
7525 [ALC883_LENOVO_NB0763] = {
7526 .mixers = { alc883_lenovo_nb0763_mixer },
7527 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7528 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7529 .dac_nids = alc883_dac_nids,
7530 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7531 .adc_nids = alc883_adc_nids,
7532 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7533 .channel_mode = alc883_3ST_2ch_modes,
7534 .need_dac_fix = 1,
7535 .input_mux = &alc883_lenovo_nb0763_capture_source,
7536 .unsol_event = alc883_medion_md2_unsol_event,
7537 .init_hook = alc883_medion_md2_automute,
7538 },
7539 [ALC888_LENOVO_MS7195_DIG] = {
7540 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7541 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7542 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7543 .dac_nids = alc883_dac_nids,
7544 .dig_out_nid = ALC883_DIGOUT_NID,
7545 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7546 .adc_nids = alc883_adc_nids,
7547 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7548 .channel_mode = alc883_3ST_6ch_modes,
7549 .need_dac_fix = 1,
7550 .input_mux = &alc883_capture_source,
7551 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7552 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7553 },
7554 [ALC883_HAIER_W66] = {
7555 .mixers = { alc883_tagra_2ch_mixer},
7556 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7557 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7558 .dac_nids = alc883_dac_nids,
7559 .dig_out_nid = ALC883_DIGOUT_NID,
7560 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7561 .adc_nids = alc883_adc_nids,
7562 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7563 .channel_mode = alc883_3ST_2ch_modes,
7564 .input_mux = &alc883_capture_source,
7565 .unsol_event = alc883_haier_w66_unsol_event,
7566 .init_hook = alc883_haier_w66_automute,
272a527c 7567 },
4723c022
CM
7568 [ALC888_6ST_HP] = {
7569 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7570 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
cd1e3b40
CM
7571 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7572 .dac_nids = alc883_dac_nids,
7573 .dig_out_nid = ALC883_DIGOUT_NID,
7574 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7575 .adc_nids = alc883_adc_nids,
7576 .dig_in_nid = ALC883_DIGIN_NID,
7577 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7578 .channel_mode = alc883_sixstack_modes,
7579 .input_mux = &alc883_capture_source,
7580 },
4723c022
CM
7581 [ALC888_3ST_HP] = {
7582 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7583 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7584 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7585 .dac_nids = alc883_dac_nids,
7586 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7587 .adc_nids = alc883_adc_nids,
4723c022
CM
7588 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7589 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7590 .need_dac_fix = 1,
7591 .input_mux = &alc883_capture_source,
7592 },
a8848bd6
AS
7593 [ALC883_MITAC] = {
7594 .mixers = { alc883_mitac_mixer },
7595 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7597 .dac_nids = alc883_dac_nids,
7598 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7599 .adc_nids = alc883_adc_nids,
7600 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7601 .channel_mode = alc883_3ST_2ch_modes,
7602 .input_mux = &alc883_capture_source,
7603 .unsol_event = alc883_mitac_unsol_event,
7604 .init_hook = alc883_mitac_automute,
7605 },
9c7f852e
TI
7606};
7607
7608
7609/*
7610 * BIOS auto configuration
7611 */
7612static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7613 hda_nid_t nid, int pin_type,
7614 int dac_idx)
7615{
7616 /* set as output */
7617 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7618 int idx;
7619
9c7f852e
TI
7620 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7621 idx = 4;
7622 else
7623 idx = spec->multiout.dac_nids[dac_idx] - 2;
7624
7625 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7626 pin_type);
7627 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7628 AMP_OUT_UNMUTE);
7629 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7630
7631}
7632
7633static void alc883_auto_init_multi_out(struct hda_codec *codec)
7634{
7635 struct alc_spec *spec = codec->spec;
7636 int i;
7637
bc9f98a9 7638 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 7639 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7640 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7641 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 7642 if (nid)
baba8ee9 7643 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7644 i);
9c7f852e
TI
7645 }
7646}
7647
7648static void alc883_auto_init_hp_out(struct hda_codec *codec)
7649{
7650 struct alc_spec *spec = codec->spec;
7651 hda_nid_t pin;
7652
eb06ed8f 7653 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
7654 if (pin) /* connect to front */
7655 /* use dac 0 */
7656 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7657}
7658
7659#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7660#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7661
7662static void alc883_auto_init_analog_input(struct hda_codec *codec)
7663{
7664 struct alc_spec *spec = codec->spec;
7665 int i;
7666
7667 for (i = 0; i < AUTO_PIN_LAST; i++) {
7668 hda_nid_t nid = spec->autocfg.input_pins[i];
7669 if (alc883_is_input_pin(nid)) {
7670 snd_hda_codec_write(codec, nid, 0,
7671 AC_VERB_SET_PIN_WIDGET_CONTROL,
7672 (i <= AUTO_PIN_FRONT_MIC ?
7673 PIN_VREF80 : PIN_IN));
7674 if (nid != ALC883_PIN_CD_NID)
7675 snd_hda_codec_write(codec, nid, 0,
7676 AC_VERB_SET_AMP_GAIN_MUTE,
7677 AMP_OUT_MUTE);
7678 }
7679 }
7680}
7681
7682/* almost identical with ALC880 parser... */
7683static int alc883_parse_auto_config(struct hda_codec *codec)
7684{
7685 struct alc_spec *spec = codec->spec;
7686 int err = alc880_parse_auto_config(codec);
7687
7688 if (err < 0)
7689 return err;
776e184e
TI
7690 else if (!err)
7691 return 0; /* no config found */
7692
7693 err = alc_auto_add_mic_boost(codec);
7694 if (err < 0)
7695 return err;
7696
7697 /* hack - override the init verbs */
7698 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
7699 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7700 spec->num_mixers++;
776e184e
TI
7701
7702 return 1; /* config found */
9c7f852e
TI
7703}
7704
7705/* additional initialization for auto-configuration model */
7706static void alc883_auto_init(struct hda_codec *codec)
7707{
7708 alc883_auto_init_multi_out(codec);
7709 alc883_auto_init_hp_out(codec);
7710 alc883_auto_init_analog_input(codec);
7711}
7712
7713static int patch_alc883(struct hda_codec *codec)
7714{
7715 struct alc_spec *spec;
7716 int err, board_config;
7717
7718 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7719 if (spec == NULL)
7720 return -ENOMEM;
7721
7722 codec->spec = spec;
7723
f5fcc13c
TI
7724 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7725 alc883_models,
7726 alc883_cfg_tbl);
7727 if (board_config < 0) {
9c7f852e
TI
7728 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7729 "trying auto-probe from BIOS...\n");
7730 board_config = ALC883_AUTO;
7731 }
7732
7733 if (board_config == ALC883_AUTO) {
7734 /* automatic parse from the BIOS config */
7735 err = alc883_parse_auto_config(codec);
7736 if (err < 0) {
7737 alc_free(codec);
7738 return err;
f12ab1e0 7739 } else if (!err) {
9c7f852e
TI
7740 printk(KERN_INFO
7741 "hda_codec: Cannot set up configuration "
7742 "from BIOS. Using base mode...\n");
7743 board_config = ALC883_3ST_2ch_DIG;
7744 }
7745 }
7746
7747 if (board_config != ALC883_AUTO)
7748 setup_preset(spec, &alc883_presets[board_config]);
7749
7750 spec->stream_name_analog = "ALC883 Analog";
7751 spec->stream_analog_playback = &alc883_pcm_analog_playback;
7752 spec->stream_analog_capture = &alc883_pcm_analog_capture;
7753
7754 spec->stream_name_digital = "ALC883 Digital";
7755 spec->stream_digital_playback = &alc883_pcm_digital_playback;
7756 spec->stream_digital_capture = &alc883_pcm_digital_capture;
7757
f12ab1e0 7758 if (!spec->adc_nids && spec->input_mux) {
4b146cb0
TI
7759 spec->adc_nids = alc883_adc_nids;
7760 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7761 }
9c7f852e
TI
7762
7763 codec->patch_ops = alc_patch_ops;
7764 if (board_config == ALC883_AUTO)
7765 spec->init_hook = alc883_auto_init;
cb53c626
TI
7766#ifdef CONFIG_SND_HDA_POWER_SAVE
7767 if (!spec->loopback.amplist)
7768 spec->loopback.amplist = alc883_loopbacks;
7769#endif
9c7f852e
TI
7770
7771 return 0;
7772}
7773
7774/*
7775 * ALC262 support
7776 */
7777
7778#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
7779#define ALC262_DIGIN_NID ALC880_DIGIN_NID
7780
7781#define alc262_dac_nids alc260_dac_nids
7782#define alc262_adc_nids alc882_adc_nids
7783#define alc262_adc_nids_alt alc882_adc_nids_alt
7784
7785#define alc262_modes alc260_modes
7786#define alc262_capture_source alc882_capture_source
7787
7788static struct snd_kcontrol_new alc262_base_mixer[] = {
7789 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7790 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7791 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7792 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7794 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7797 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7798 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7799 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 7800 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7801 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7802 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7803 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7805 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7806 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7807 { } /* end */
7808};
7809
ccc656ce
KY
7810static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7811 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7812 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7819 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
7820 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 7822 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce
KY
7823 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7824 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7825 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7827 { } /* end */
7828};
7829
9c7f852e
TI
7830static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7831 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7832 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7834 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7835 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7836
7837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7839 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7840 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7841 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 7842 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7843 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7844 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7845 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7846 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7847 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7848 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7849 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7850 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7851 { } /* end */
7852};
7853
cd7509a4
KY
7854static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7856 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7857 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7859 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7860 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7861 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7862 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 7863 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
7864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7868 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7869 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7870 { } /* end */
7871};
7872
7873static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7874 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7875 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7876 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
7877 { } /* end */
7878};
7879
66d2a9d6
KY
7880static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7881 .ops = &snd_hda_bind_vol,
7882 .values = {
7883 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7884 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7885 0
7886 },
7887};
7888
7889static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7890 .ops = &snd_hda_bind_sw,
7891 .values = {
7892 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7893 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7894 0
7895 },
7896};
7897
7898/* mute/unmute internal speaker according to the hp jack and mute state */
7899static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7900{
7901 struct alc_spec *spec = codec->spec;
7902 unsigned int mute;
7903
7904 if (force || !spec->sense_updated) {
7905 unsigned int present;
7906 present = snd_hda_codec_read(codec, 0x15, 0,
7907 AC_VERB_GET_PIN_SENSE, 0);
7908 spec->jack_present = (present & 0x80000000) != 0;
7909 spec->sense_updated = 1;
7910 }
7911 if (spec->jack_present)
7912 mute = (0x7080 | ((0)<<8)); /* mute internal speaker */
7913 else /* unmute internal speaker if necessary */
7914 mute = (0x7000 | ((0)<<8));
7915 snd_hda_codec_write(codec, 0x0c, 0,
7916 AC_VERB_SET_AMP_GAIN_MUTE, mute );
7917}
7918
7919static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7920 unsigned int res)
7921{
7922 if ((res >> 26) != ALC880_HP_EVENT)
7923 return;
7924 alc262_hp_t5735_automute(codec, 1);
7925}
7926
7927static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7928{
7929 alc262_hp_t5735_automute(codec, 1);
7930}
7931
7932static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7933 HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7934 HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7935 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7936 HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7937 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7938 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7942 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7944 { } /* end */
7945};
7946
7947static struct hda_verb alc262_hp_t5735_verbs[] = {
7948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7950
7951 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7952 { }
7953};
7954
0724ea2a
TI
7955/* bind hp and internal speaker mute (with plug check) */
7956static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7957 struct snd_ctl_elem_value *ucontrol)
7958{
7959 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7960 long *valp = ucontrol->value.integer.value;
7961 int change;
7962
7963 /* change hp mute */
7964 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7965 HDA_AMP_MUTE,
7966 valp[0] ? 0 : HDA_AMP_MUTE);
7967 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7968 HDA_AMP_MUTE,
7969 valp[1] ? 0 : HDA_AMP_MUTE);
7970 if (change) {
7971 /* change speaker according to HP jack state */
7972 struct alc_spec *spec = codec->spec;
7973 unsigned int mute;
7974 if (spec->jack_present)
7975 mute = HDA_AMP_MUTE;
7976 else
7977 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7978 HDA_OUTPUT, 0);
7979 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7980 HDA_AMP_MUTE, mute);
7981 }
7982 return change;
7983}
5b31954e 7984
272a527c 7985static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
7986 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7987 {
7988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7989 .name = "Master Playback Switch",
7990 .info = snd_hda_mixer_amp_switch_info,
7991 .get = snd_hda_mixer_amp_switch_get,
7992 .put = alc262_sony_master_sw_put,
7993 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7994 },
272a527c
KY
7995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7997 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7998 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7999 { } /* end */
8000};
8001
83c34218
KY
8002static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8004 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8008 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8009 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8010 { } /* end */
8011};
272a527c 8012
9c7f852e
TI
8013#define alc262_capture_mixer alc882_capture_mixer
8014#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8015
8016/*
8017 * generic initialization of ADC, input mixers and output mixers
8018 */
8019static struct hda_verb alc262_init_verbs[] = {
8020 /*
8021 * Unmute ADC0-2 and set the default input to mic-in
8022 */
8023 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8028 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8029
cb53c626 8030 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8031 * mixer widget
f12ab1e0
TI
8032 * Note: PASD motherboards uses the Line In 2 as the input for
8033 * front panel mic (mic 2)
9c7f852e
TI
8034 */
8035 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8036 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8037 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8039 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8041
8042 /*
df694daa
KY
8043 * Set up output mixers (0x0c - 0x0e)
8044 */
8045 /* set vol=0 to output mixers */
8046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8049 /* set up input amps for analog loopback */
8050 /* Amp Indices: DAC = 0, mixer = 1 */
8051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8053 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8054 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8055 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8056 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8057
8058 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8060 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8061 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8063 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8064
8065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8069 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8070
8071 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8072 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8073
8074 /* FIXME: use matrix-type input source selection */
8075 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8076 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8081 /* Input mixer2 */
8082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8085 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8086 /* Input mixer3 */
8087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8091
8092 { }
8093};
1da177e4 8094
ccc656ce
KY
8095static struct hda_verb alc262_hippo_unsol_verbs[] = {
8096 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8098 {}
8099};
8100
8101static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8102 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8103 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8104 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8105
8106 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8108 {}
8109};
8110
272a527c
KY
8111static struct hda_verb alc262_sony_unsol_verbs[] = {
8112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8114 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8115
8116 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8118};
8119
ccc656ce 8120/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8121static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8122{
8123 struct alc_spec *spec = codec->spec;
8124 unsigned int mute;
5b31954e 8125 unsigned int present;
ccc656ce 8126
5b31954e
TI
8127 /* need to execute and sync at first */
8128 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8129 present = snd_hda_codec_read(codec, 0x15, 0,
8130 AC_VERB_GET_PIN_SENSE, 0);
8131 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8132 if (spec->jack_present) {
8133 /* mute internal speaker */
47fd830a
TI
8134 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8135 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8136 } else {
8137 /* unmute internal speaker if necessary */
8138 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8139 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8140 HDA_AMP_MUTE, mute);
ccc656ce
KY
8141 }
8142}
8143
8144/* unsolicited event for HP jack sensing */
8145static void alc262_hippo_unsol_event(struct hda_codec *codec,
8146 unsigned int res)
8147{
8148 if ((res >> 26) != ALC880_HP_EVENT)
8149 return;
5b31954e 8150 alc262_hippo_automute(codec);
ccc656ce
KY
8151}
8152
5b31954e 8153static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8154{
ccc656ce 8155 unsigned int mute;
5b31954e 8156 unsigned int present;
ccc656ce 8157
5b31954e
TI
8158 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8159 present = snd_hda_codec_read(codec, 0x1b, 0,
8160 AC_VERB_GET_PIN_SENSE, 0);
8161 present = (present & 0x80000000) != 0;
8162 if (present) {
ccc656ce 8163 /* mute internal speaker */
47fd830a
TI
8164 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8165 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8166 } else {
8167 /* unmute internal speaker if necessary */
8168 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8169 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8170 HDA_AMP_MUTE, mute);
ccc656ce
KY
8171 }
8172}
8173
8174/* unsolicited event for HP jack sensing */
8175static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8176 unsigned int res)
8177{
8178 if ((res >> 26) != ALC880_HP_EVENT)
8179 return;
5b31954e 8180 alc262_hippo1_automute(codec);
ccc656ce
KY
8181}
8182
834be88d
TI
8183/*
8184 * fujitsu model
8185 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8186 */
8187
8188#define ALC_HP_EVENT 0x37
8189
8190static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8191 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8193 {}
8194};
8195
8196static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8197 .num_items = 3,
834be88d
TI
8198 .items = {
8199 { "Mic", 0x0 },
39d3ed38 8200 { "Int Mic", 0x1 },
834be88d
TI
8201 { "CD", 0x4 },
8202 },
8203};
8204
9c7f852e
TI
8205static struct hda_input_mux alc262_HP_capture_source = {
8206 .num_items = 5,
8207 .items = {
8208 { "Mic", 0x0 },
accbe498 8209 { "Front Mic", 0x1 },
9c7f852e
TI
8210 { "Line", 0x2 },
8211 { "CD", 0x4 },
8212 { "AUX IN", 0x6 },
8213 },
8214};
8215
accbe498 8216static struct hda_input_mux alc262_HP_D7000_capture_source = {
8217 .num_items = 4,
8218 .items = {
8219 { "Mic", 0x0 },
8220 { "Front Mic", 0x2 },
8221 { "Line", 0x1 },
8222 { "CD", 0x4 },
8223 },
8224};
8225
834be88d
TI
8226/* mute/unmute internal speaker according to the hp jack and mute state */
8227static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8228{
8229 struct alc_spec *spec = codec->spec;
8230 unsigned int mute;
8231
f12ab1e0 8232 if (force || !spec->sense_updated) {
834be88d
TI
8233 unsigned int present;
8234 /* need to execute and sync at first */
8235 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8236 present = snd_hda_codec_read(codec, 0x14, 0,
8237 AC_VERB_GET_PIN_SENSE, 0);
8238 spec->jack_present = (present & 0x80000000) != 0;
8239 spec->sense_updated = 1;
8240 }
8241 if (spec->jack_present) {
8242 /* mute internal speaker */
47fd830a
TI
8243 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8244 HDA_AMP_MUTE, HDA_AMP_MUTE);
834be88d
TI
8245 } else {
8246 /* unmute internal speaker if necessary */
8247 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
47fd830a
TI
8248 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8249 HDA_AMP_MUTE, mute);
834be88d
TI
8250 }
8251}
8252
8253/* unsolicited event for HP jack sensing */
8254static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8255 unsigned int res)
8256{
8257 if ((res >> 26) != ALC_HP_EVENT)
8258 return;
8259 alc262_fujitsu_automute(codec, 1);
8260}
8261
8262/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8263static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8264 .ops = &snd_hda_bind_vol,
8265 .values = {
8266 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8267 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8268 0
8269 },
8270};
834be88d
TI
8271
8272/* bind hp and internal speaker mute (with plug check) */
8273static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8274 struct snd_ctl_elem_value *ucontrol)
8275{
8276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8277 long *valp = ucontrol->value.integer.value;
8278 int change;
8279
8280 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
47fd830a
TI
8281 HDA_AMP_MUTE,
8282 valp[0] ? 0 : HDA_AMP_MUTE);
834be88d 8283 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
47fd830a
TI
8284 HDA_AMP_MUTE,
8285 valp[1] ? 0 : HDA_AMP_MUTE);
82beb8fd
TI
8286 if (change)
8287 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8288 return change;
8289}
8290
8291static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8292 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8293 {
8294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8295 .name = "Master Playback Switch",
8296 .info = snd_hda_mixer_amp_switch_info,
8297 .get = snd_hda_mixer_amp_switch_get,
8298 .put = alc262_fujitsu_master_sw_put,
8299 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8300 },
8301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8303 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8306 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8307 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8308 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8309 { } /* end */
8310};
8311
304dcaac
TI
8312/* additional init verbs for Benq laptops */
8313static struct hda_verb alc262_EAPD_verbs[] = {
8314 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8315 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8316 {}
8317};
8318
83c34218
KY
8319static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8320 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8322
8323 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8324 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8325 {}
8326};
8327
f651b50b
TD
8328/* Samsung Q1 Ultra Vista model setup */
8329static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8330 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8336 { } /* end */
8337};
8338
8339static struct hda_verb alc262_ultra_verbs[] = {
8340 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8342 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8343 /* Mic is on Node 0x19 */
8344 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8345 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8347 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8349 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8351 {}
8352};
8353
8354static struct hda_input_mux alc262_ultra_capture_source = {
8355 .num_items = 1,
8356 .items = {
8357 { "Mic", 0x1 },
8358 },
8359};
8360
8361/* mute/unmute internal speaker according to the hp jack and mute state */
8362static void alc262_ultra_automute(struct hda_codec *codec)
8363{
8364 struct alc_spec *spec = codec->spec;
8365 unsigned int mute;
8366 unsigned int present;
8367
8368 /* need to execute and sync at first */
8369 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8370 present = snd_hda_codec_read(codec, 0x15, 0,
8371 AC_VERB_GET_PIN_SENSE, 0);
8372 spec->jack_present = (present & 0x80000000) != 0;
8373 if (spec->jack_present) {
8374 /* mute internal speaker */
8375 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8376 HDA_AMP_MUTE, HDA_AMP_MUTE);
8377 } else {
8378 /* unmute internal speaker if necessary */
8379 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8380 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8381 HDA_AMP_MUTE, mute);
8382 }
8383}
8384
8385/* unsolicited event for HP jack sensing */
8386static void alc262_ultra_unsol_event(struct hda_codec *codec,
8387 unsigned int res)
8388{
8389 if ((res >> 26) != ALC880_HP_EVENT)
8390 return;
8391 alc262_ultra_automute(codec);
8392}
8393
df694daa 8394/* add playback controls from the parsed DAC table */
f12ab1e0
TI
8395static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8396 const struct auto_pin_cfg *cfg)
df694daa
KY
8397{
8398 hda_nid_t nid;
8399 int err;
8400
8401 spec->multiout.num_dacs = 1; /* only use one dac */
8402 spec->multiout.dac_nids = spec->private_dac_nids;
8403 spec->multiout.dac_nids[0] = 2;
8404
8405 nid = cfg->line_out_pins[0];
8406 if (nid) {
f12ab1e0
TI
8407 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8408 "Front Playback Volume",
8409 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8410 if (err < 0)
df694daa 8411 return err;
f12ab1e0
TI
8412 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8413 "Front Playback Switch",
8414 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8415 if (err < 0)
df694daa
KY
8416 return err;
8417 }
8418
82bc955f 8419 nid = cfg->speaker_pins[0];
df694daa
KY
8420 if (nid) {
8421 if (nid == 0x16) {
f12ab1e0
TI
8422 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8423 "Speaker Playback Volume",
8424 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8425 HDA_OUTPUT));
8426 if (err < 0)
df694daa 8427 return err;
f12ab1e0
TI
8428 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8429 "Speaker Playback Switch",
8430 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8431 HDA_OUTPUT));
8432 if (err < 0)
df694daa
KY
8433 return err;
8434 } else {
f12ab1e0
TI
8435 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8436 "Speaker Playback Switch",
8437 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8438 HDA_OUTPUT));
8439 if (err < 0)
df694daa
KY
8440 return err;
8441 }
8442 }
eb06ed8f 8443 nid = cfg->hp_pins[0];
df694daa
KY
8444 if (nid) {
8445 /* spec->multiout.hp_nid = 2; */
8446 if (nid == 0x16) {
f12ab1e0
TI
8447 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8448 "Headphone Playback Volume",
8449 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8450 HDA_OUTPUT));
8451 if (err < 0)
df694daa 8452 return err;
f12ab1e0
TI
8453 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8454 "Headphone Playback Switch",
8455 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8456 HDA_OUTPUT));
8457 if (err < 0)
df694daa
KY
8458 return err;
8459 } else {
f12ab1e0
TI
8460 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8461 "Headphone Playback Switch",
8462 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8463 HDA_OUTPUT));
8464 if (err < 0)
df694daa
KY
8465 return err;
8466 }
8467 }
f12ab1e0 8468 return 0;
df694daa
KY
8469}
8470
8471/* identical with ALC880 */
f12ab1e0
TI
8472#define alc262_auto_create_analog_input_ctls \
8473 alc880_auto_create_analog_input_ctls
df694daa
KY
8474
8475/*
8476 * generic initialization of ADC, input mixers and output mixers
8477 */
8478static struct hda_verb alc262_volume_init_verbs[] = {
8479 /*
8480 * Unmute ADC0-2 and set the default input to mic-in
8481 */
8482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8484 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8488
cb53c626 8489 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 8490 * mixer widget
f12ab1e0
TI
8491 * Note: PASD motherboards uses the Line In 2 as the input for
8492 * front panel mic (mic 2)
df694daa
KY
8493 */
8494 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
8500
8501 /*
8502 * Set up output mixers (0x0c - 0x0f)
8503 */
8504 /* set vol=0 to output mixers */
8505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508
8509 /* set up input amps for analog loopback */
8510 /* Amp Indices: DAC = 0, mixer = 1 */
8511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8517
8518 /* FIXME: use matrix-type input source selection */
8519 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8520 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8525 /* Input mixer2 */
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8530 /* Input mixer3 */
8531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8535
8536 { }
8537};
8538
9c7f852e
TI
8539static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8540 /*
8541 * Unmute ADC0-2 and set the default input to mic-in
8542 */
8543 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8544 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8545 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8547 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549
cb53c626 8550 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8551 * mixer widget
f12ab1e0
TI
8552 * Note: PASD motherboards uses the Line In 2 as the input for
8553 * front panel mic (mic 2)
9c7f852e
TI
8554 */
8555 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
8563
8564 /*
8565 * Set up output mixers (0x0c - 0x0e)
8566 */
8567 /* set vol=0 to output mixers */
8568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8569 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8571
8572 /* set up input amps for analog loopback */
8573 /* Amp Indices: DAC = 0, mixer = 1 */
8574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8575 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8576 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8578 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8579 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8580
8581 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8583 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8584
8585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8587
8588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8589 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8590
8591 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8593 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8594 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8595 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8596
8597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8598 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8599 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8601 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8602 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8603
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, (0x7000 | (0x03 << 8))},
8610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8612 /* Input mixer2 */
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8617 /* Input mixer3 */
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8622
8623 { }
8624};
8625
cd7509a4
KY
8626static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8627 /*
8628 * Unmute ADC0-2 and set the default input to mic-in
8629 */
8630 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8631 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8632 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8634 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8636
cb53c626 8637 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
8638 * mixer widget
8639 * Note: PASD motherboards uses the Line In 2 as the input for front
8640 * panel mic (mic 2)
8641 */
8642 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
8651 /*
8652 * Set up output mixers (0x0c - 0x0e)
8653 */
8654 /* set vol=0 to output mixers */
8655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8657 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8658
8659 /* set up input amps for analog loopback */
8660 /* Amp Indices: DAC = 0, mixer = 1 */
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8663 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8665 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8666 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8667
8668
8669 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
8670 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
8671 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
8672 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
8673 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
8674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
8675 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
8676
8677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8678 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8679
8680 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8681 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8682
8683 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8684 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8685 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8687 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8688 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8689
8690 /* FIXME: use matrix-type input source selection */
8691 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8692 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8696 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8698 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8699 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8700 /* Input mixer2 */
8701 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8702 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8703 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8704 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8705 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8706 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8707 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8708 /* Input mixer3 */
8709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8712 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8714 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8716
8717 { }
8718};
8719
cb53c626
TI
8720#ifdef CONFIG_SND_HDA_POWER_SAVE
8721#define alc262_loopbacks alc880_loopbacks
8722#endif
8723
df694daa
KY
8724/* pcm configuration: identiacal with ALC880 */
8725#define alc262_pcm_analog_playback alc880_pcm_analog_playback
8726#define alc262_pcm_analog_capture alc880_pcm_analog_capture
8727#define alc262_pcm_digital_playback alc880_pcm_digital_playback
8728#define alc262_pcm_digital_capture alc880_pcm_digital_capture
8729
8730/*
8731 * BIOS auto configuration
8732 */
8733static int alc262_parse_auto_config(struct hda_codec *codec)
8734{
8735 struct alc_spec *spec = codec->spec;
8736 int err;
8737 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8738
f12ab1e0
TI
8739 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8740 alc262_ignore);
8741 if (err < 0)
df694daa 8742 return err;
f12ab1e0 8743 if (!spec->autocfg.line_outs)
df694daa 8744 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
8745 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8746 if (err < 0)
8747 return err;
8748 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8749 if (err < 0)
df694daa
KY
8750 return err;
8751
8752 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8753
8754 if (spec->autocfg.dig_out_pin)
8755 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8756 if (spec->autocfg.dig_in_pin)
8757 spec->dig_in_nid = ALC262_DIGIN_NID;
8758
8759 if (spec->kctl_alloc)
8760 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8761
8762 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 8763 spec->num_mux_defs = 1;
df694daa
KY
8764 spec->input_mux = &spec->private_imux;
8765
776e184e
TI
8766 err = alc_auto_add_mic_boost(codec);
8767 if (err < 0)
8768 return err;
8769
df694daa
KY
8770 return 1;
8771}
8772
8773#define alc262_auto_init_multi_out alc882_auto_init_multi_out
8774#define alc262_auto_init_hp_out alc882_auto_init_hp_out
8775#define alc262_auto_init_analog_input alc882_auto_init_analog_input
8776
8777
8778/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 8779static void alc262_auto_init(struct hda_codec *codec)
df694daa 8780{
df694daa
KY
8781 alc262_auto_init_multi_out(codec);
8782 alc262_auto_init_hp_out(codec);
8783 alc262_auto_init_analog_input(codec);
df694daa
KY
8784}
8785
8786/*
8787 * configuration and preset
8788 */
f5fcc13c
TI
8789static const char *alc262_models[ALC262_MODEL_LAST] = {
8790 [ALC262_BASIC] = "basic",
8791 [ALC262_HIPPO] = "hippo",
8792 [ALC262_HIPPO_1] = "hippo_1",
8793 [ALC262_FUJITSU] = "fujitsu",
8794 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 8795 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 8796 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
f5fcc13c 8797 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
8798 [ALC262_BENQ_T31] = "benq-t31",
8799 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 8800 [ALC262_ULTRA] = "ultra",
f5fcc13c
TI
8801 [ALC262_AUTO] = "auto",
8802};
8803
8804static struct snd_pci_quirk alc262_cfg_tbl[] = {
8805 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8806 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 8807 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
8808 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8809 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 8810 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 8811 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 8812 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 8813 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 8814 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8815 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 8816 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8817 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 8818 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8819 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 8820 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8821 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
8822 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8823 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8824 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
8825 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8826 ALC262_HP_TC_T5735),
ac3e3741 8827 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 8828 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 8829 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 8830 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
8831 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8832 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
f651b50b 8833 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
ac3e3741
TI
8834 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8835 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8836 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
8837 {}
8838};
8839
8840static struct alc_config_preset alc262_presets[] = {
8841 [ALC262_BASIC] = {
8842 .mixers = { alc262_base_mixer },
8843 .init_verbs = { alc262_init_verbs },
8844 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8845 .dac_nids = alc262_dac_nids,
8846 .hp_nid = 0x03,
8847 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8848 .channel_mode = alc262_modes,
a3bcba38 8849 .input_mux = &alc262_capture_source,
df694daa 8850 },
ccc656ce
KY
8851 [ALC262_HIPPO] = {
8852 .mixers = { alc262_base_mixer },
8853 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8854 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8855 .dac_nids = alc262_dac_nids,
8856 .hp_nid = 0x03,
8857 .dig_out_nid = ALC262_DIGOUT_NID,
8858 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8859 .channel_mode = alc262_modes,
8860 .input_mux = &alc262_capture_source,
8861 .unsol_event = alc262_hippo_unsol_event,
5b31954e 8862 .init_hook = alc262_hippo_automute,
ccc656ce
KY
8863 },
8864 [ALC262_HIPPO_1] = {
8865 .mixers = { alc262_hippo1_mixer },
8866 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8867 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8868 .dac_nids = alc262_dac_nids,
8869 .hp_nid = 0x02,
8870 .dig_out_nid = ALC262_DIGOUT_NID,
8871 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8872 .channel_mode = alc262_modes,
8873 .input_mux = &alc262_capture_source,
8874 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 8875 .init_hook = alc262_hippo1_automute,
ccc656ce 8876 },
834be88d
TI
8877 [ALC262_FUJITSU] = {
8878 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
8879 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8880 alc262_fujitsu_unsol_verbs },
834be88d
TI
8881 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8882 .dac_nids = alc262_dac_nids,
8883 .hp_nid = 0x03,
8884 .dig_out_nid = ALC262_DIGOUT_NID,
8885 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8886 .channel_mode = alc262_modes,
8887 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 8888 .unsol_event = alc262_fujitsu_unsol_event,
834be88d 8889 },
9c7f852e
TI
8890 [ALC262_HP_BPC] = {
8891 .mixers = { alc262_HP_BPC_mixer },
8892 .init_verbs = { alc262_HP_BPC_init_verbs },
8893 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8894 .dac_nids = alc262_dac_nids,
8895 .hp_nid = 0x03,
8896 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8897 .channel_mode = alc262_modes,
8898 .input_mux = &alc262_HP_capture_source,
f12ab1e0 8899 },
cd7509a4
KY
8900 [ALC262_HP_BPC_D7000_WF] = {
8901 .mixers = { alc262_HP_BPC_WildWest_mixer },
8902 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8903 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8904 .dac_nids = alc262_dac_nids,
8905 .hp_nid = 0x03,
8906 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8907 .channel_mode = alc262_modes,
accbe498 8908 .input_mux = &alc262_HP_D7000_capture_source,
f12ab1e0 8909 },
cd7509a4
KY
8910 [ALC262_HP_BPC_D7000_WL] = {
8911 .mixers = { alc262_HP_BPC_WildWest_mixer,
8912 alc262_HP_BPC_WildWest_option_mixer },
8913 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8914 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8915 .dac_nids = alc262_dac_nids,
8916 .hp_nid = 0x03,
8917 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8918 .channel_mode = alc262_modes,
accbe498 8919 .input_mux = &alc262_HP_D7000_capture_source,
f12ab1e0 8920 },
66d2a9d6
KY
8921 [ALC262_HP_TC_T5735] = {
8922 .mixers = { alc262_hp_t5735_mixer },
8923 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8924 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8925 .dac_nids = alc262_dac_nids,
8926 .hp_nid = 0x03,
8927 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8928 .channel_mode = alc262_modes,
8929 .input_mux = &alc262_capture_source,
8930 .unsol_event = alc262_hp_t5735_unsol_event,
8931 .init_hook = alc262_hp_t5735_init_hook,
8932 },
304dcaac
TI
8933 [ALC262_BENQ_ED8] = {
8934 .mixers = { alc262_base_mixer },
8935 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8936 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8937 .dac_nids = alc262_dac_nids,
8938 .hp_nid = 0x03,
8939 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8940 .channel_mode = alc262_modes,
8941 .input_mux = &alc262_capture_source,
f12ab1e0 8942 },
272a527c
KY
8943 [ALC262_SONY_ASSAMD] = {
8944 .mixers = { alc262_sony_mixer },
8945 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8946 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8947 .dac_nids = alc262_dac_nids,
8948 .hp_nid = 0x02,
8949 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8950 .channel_mode = alc262_modes,
8951 .input_mux = &alc262_capture_source,
8952 .unsol_event = alc262_hippo_unsol_event,
5b31954e 8953 .init_hook = alc262_hippo_automute,
83c34218
KY
8954 },
8955 [ALC262_BENQ_T31] = {
8956 .mixers = { alc262_benq_t31_mixer },
8957 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8958 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8959 .dac_nids = alc262_dac_nids,
8960 .hp_nid = 0x03,
8961 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8962 .channel_mode = alc262_modes,
8963 .input_mux = &alc262_capture_source,
8964 .unsol_event = alc262_hippo_unsol_event,
5b31954e 8965 .init_hook = alc262_hippo_automute,
272a527c 8966 },
f651b50b
TD
8967 [ALC262_ULTRA] = {
8968 .mixers = { alc262_ultra_mixer },
8969 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8970 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8971 .dac_nids = alc262_dac_nids,
8972 .hp_nid = 0x03,
8973 .dig_out_nid = ALC262_DIGOUT_NID,
8974 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8975 .channel_mode = alc262_modes,
8976 .input_mux = &alc262_ultra_capture_source,
8977 .unsol_event = alc262_ultra_unsol_event,
8978 .init_hook = alc262_ultra_automute,
8979 },
df694daa
KY
8980};
8981
8982static int patch_alc262(struct hda_codec *codec)
8983{
8984 struct alc_spec *spec;
8985 int board_config;
8986 int err;
8987
dc041e0b 8988 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
8989 if (spec == NULL)
8990 return -ENOMEM;
8991
8992 codec->spec = spec;
8993#if 0
f12ab1e0
TI
8994 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
8995 * under-run
8996 */
df694daa
KY
8997 {
8998 int tmp;
8999 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9000 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9001 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9002 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9003 }
9004#endif
9005
f5fcc13c
TI
9006 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9007 alc262_models,
9008 alc262_cfg_tbl);
cd7509a4 9009
f5fcc13c 9010 if (board_config < 0) {
9c7f852e
TI
9011 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9012 "trying auto-probe from BIOS...\n");
df694daa
KY
9013 board_config = ALC262_AUTO;
9014 }
9015
9016 if (board_config == ALC262_AUTO) {
9017 /* automatic parse from the BIOS config */
9018 err = alc262_parse_auto_config(codec);
9019 if (err < 0) {
9020 alc_free(codec);
9021 return err;
f12ab1e0 9022 } else if (!err) {
9c7f852e
TI
9023 printk(KERN_INFO
9024 "hda_codec: Cannot set up configuration "
9025 "from BIOS. Using base mode...\n");
df694daa
KY
9026 board_config = ALC262_BASIC;
9027 }
9028 }
9029
9030 if (board_config != ALC262_AUTO)
9031 setup_preset(spec, &alc262_presets[board_config]);
9032
9033 spec->stream_name_analog = "ALC262 Analog";
9034 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9035 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9036
9037 spec->stream_name_digital = "ALC262 Digital";
9038 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9039 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9040
f12ab1e0 9041 if (!spec->adc_nids && spec->input_mux) {
df694daa 9042 /* check whether NID 0x07 is valid */
4a471b7d
TI
9043 unsigned int wcap = get_wcaps(codec, 0x07);
9044
f12ab1e0
TI
9045 /* get type */
9046 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9047 if (wcap != AC_WID_AUD_IN) {
9048 spec->adc_nids = alc262_adc_nids_alt;
9049 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
f12ab1e0
TI
9050 spec->mixers[spec->num_mixers] =
9051 alc262_capture_alt_mixer;
df694daa
KY
9052 spec->num_mixers++;
9053 } else {
9054 spec->adc_nids = alc262_adc_nids;
9055 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9056 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9057 spec->num_mixers++;
9058 }
9059 }
9060
9061 codec->patch_ops = alc_patch_ops;
9062 if (board_config == ALC262_AUTO)
ae6b813a 9063 spec->init_hook = alc262_auto_init;
cb53c626
TI
9064#ifdef CONFIG_SND_HDA_POWER_SAVE
9065 if (!spec->loopback.amplist)
9066 spec->loopback.amplist = alc262_loopbacks;
9067#endif
834be88d 9068
df694daa
KY
9069 return 0;
9070}
9071
a361d84b
KY
9072/*
9073 * ALC268 channel source setting (2 channel)
9074 */
9075#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9076#define alc268_modes alc260_modes
9077
9078static hda_nid_t alc268_dac_nids[2] = {
9079 /* front, hp */
9080 0x02, 0x03
9081};
9082
9083static hda_nid_t alc268_adc_nids[2] = {
9084 /* ADC0-1 */
9085 0x08, 0x07
9086};
9087
9088static hda_nid_t alc268_adc_nids_alt[1] = {
9089 /* ADC0 */
9090 0x08
9091};
9092
9093static struct snd_kcontrol_new alc268_base_mixer[] = {
9094 /* output mixer control */
9095 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9099 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9101 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9102 { }
9103};
9104
d1a991a6
KY
9105static struct hda_verb alc268_eapd_verbs[] = {
9106 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9107 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9108 { }
9109};
9110
d273809e
TI
9111/* Toshiba specific */
9112#define alc268_toshiba_automute alc262_hippo_automute
9113
9114static struct hda_verb alc268_toshiba_verbs[] = {
9115 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9116 { } /* end */
9117};
9118
9119/* Acer specific */
889c4395 9120/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9121static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9122 .ops = &snd_hda_bind_vol,
9123 .values = {
9124 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9125 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9126 0
9127 },
9128};
9129
889c4395
TI
9130/* mute/unmute internal speaker according to the hp jack and mute state */
9131static void alc268_acer_automute(struct hda_codec *codec, int force)
9132{
9133 struct alc_spec *spec = codec->spec;
9134 unsigned int mute;
9135
9136 if (force || !spec->sense_updated) {
9137 unsigned int present;
9138 present = snd_hda_codec_read(codec, 0x14, 0,
9139 AC_VERB_GET_PIN_SENSE, 0);
9140 spec->jack_present = (present & 0x80000000) != 0;
9141 spec->sense_updated = 1;
9142 }
9143 if (spec->jack_present)
9144 mute = HDA_AMP_MUTE; /* mute internal speaker */
9145 else /* unmute internal speaker if necessary */
9146 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9147 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9148 HDA_AMP_MUTE, mute);
9149}
9150
9151
9152/* bind hp and internal speaker mute (with plug check) */
9153static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9154 struct snd_ctl_elem_value *ucontrol)
9155{
9156 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9157 long *valp = ucontrol->value.integer.value;
9158 int change;
9159
9160 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9161 HDA_AMP_MUTE,
9162 valp[0] ? 0 : HDA_AMP_MUTE);
9163 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9164 HDA_AMP_MUTE,
9165 valp[1] ? 0 : HDA_AMP_MUTE);
9166 if (change)
9167 alc268_acer_automute(codec, 0);
9168 return change;
9169}
d273809e
TI
9170
9171static struct snd_kcontrol_new alc268_acer_mixer[] = {
9172 /* output mixer control */
9173 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9174 {
9175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9176 .name = "Master Playback Switch",
9177 .info = snd_hda_mixer_amp_switch_info,
9178 .get = snd_hda_mixer_amp_switch_get,
9179 .put = alc268_acer_master_sw_put,
9180 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9181 },
33bf17ab
TI
9182 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9183 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9185 { }
9186};
9187
9188static struct hda_verb alc268_acer_verbs[] = {
9189 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9190 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9191
9192 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9193 { }
9194};
9195
9196/* unsolicited event for HP jack sensing */
9197static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9198 unsigned int res)
9199{
889c4395 9200 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9201 return;
9202 alc268_toshiba_automute(codec);
9203}
9204
9205static void alc268_acer_unsol_event(struct hda_codec *codec,
9206 unsigned int res)
9207{
889c4395 9208 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9209 return;
9210 alc268_acer_automute(codec, 1);
9211}
9212
889c4395
TI
9213static void alc268_acer_init_hook(struct hda_codec *codec)
9214{
9215 alc268_acer_automute(codec, 1);
9216}
9217
a361d84b
KY
9218/*
9219 * generic initialization of ADC, input mixers and output mixers
9220 */
9221static struct hda_verb alc268_base_init_verbs[] = {
9222 /* Unmute DAC0-1 and set vol = 0 */
9223 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9224 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9225 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9227 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229
9230 /*
9231 * Set up output mixers (0x0c - 0x0e)
9232 */
9233 /* set vol=0 to output mixers */
9234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9235 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9236 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9237 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9238
9239 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9240 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9241
9242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9243 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9244 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9245 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9246 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9247 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9248 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9249 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9250
9251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9252 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9253 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9254 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9255 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9257 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9258 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9259
a9b3aa8a
JZ
9260 /* Unmute Selector 23h,24h and set the default input to mic-in */
9261
9262 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9263 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9264 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 9266
a361d84b
KY
9267 { }
9268};
9269
9270/*
9271 * generic initialization of ADC, input mixers and output mixers
9272 */
9273static struct hda_verb alc268_volume_init_verbs[] = {
9274 /* set output DAC */
9275 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9276 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9277 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9278 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9279
9280 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9281 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9282 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9283 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9285
9286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9288 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9289 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9290 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9291
9292 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9293 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9294 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9295 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9296
9297 /* set PCBEEP vol = 0 */
9298 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9299
9300 { }
9301};
9302
9303#define alc268_mux_enum_info alc_mux_enum_info
9304#define alc268_mux_enum_get alc_mux_enum_get
9305
9306static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9307 struct snd_ctl_elem_value *ucontrol)
9308{
9309 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9310 struct alc_spec *spec = codec->spec;
a9b3aa8a 9311
a361d84b
KY
9312 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9313 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9314 hda_nid_t nid = capture_mixers[adc_idx];
a361d84b 9315
a9b3aa8a
JZ
9316 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9317 nid,
9318 &spec->cur_mux[adc_idx]);
a361d84b
KY
9319}
9320
9321static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9322 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9323 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9324 {
9325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9326 /* The multiple "Capture Source" controls confuse alsamixer
9327 * So call somewhat different..
9328 * FIXME: the controls appear in the "playback" view!
9329 */
9330 /* .name = "Capture Source", */
9331 .name = "Input Source",
9332 .count = 1,
9333 .info = alc268_mux_enum_info,
9334 .get = alc268_mux_enum_get,
9335 .put = alc268_mux_enum_put,
9336 },
9337 { } /* end */
9338};
9339
9340static struct snd_kcontrol_new alc268_capture_mixer[] = {
9341 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9342 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9343 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9344 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9345 {
9346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9347 /* The multiple "Capture Source" controls confuse alsamixer
9348 * So call somewhat different..
9349 * FIXME: the controls appear in the "playback" view!
9350 */
9351 /* .name = "Capture Source", */
9352 .name = "Input Source",
9353 .count = 2,
9354 .info = alc268_mux_enum_info,
9355 .get = alc268_mux_enum_get,
9356 .put = alc268_mux_enum_put,
9357 },
9358 { } /* end */
9359};
9360
9361static struct hda_input_mux alc268_capture_source = {
9362 .num_items = 4,
9363 .items = {
9364 { "Mic", 0x0 },
9365 { "Front Mic", 0x1 },
9366 { "Line", 0x2 },
9367 { "CD", 0x3 },
9368 },
9369};
9370
86c53bd2
JW
9371#ifdef CONFIG_SND_DEBUG
9372static struct snd_kcontrol_new alc268_test_mixer[] = {
9373 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9374 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9375 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9377
9378 /* Volume widgets */
9379 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9380 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9381 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9382 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9383 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9384 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9385 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9386 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9387 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9388 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9389 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9390 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9391 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
9392 HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),
9393 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9394 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9395 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9396 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9397
9398 /* Modes for retasking pin widgets */
9399 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9400 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9401 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9402 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9403
9404 /* Controls for GPIO pins, assuming they are configured as outputs */
9405 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9406 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9407 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9408 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9409
9410 /* Switches to allow the digital SPDIF output pin to be enabled.
9411 * The ALC268 does not have an SPDIF input.
9412 */
9413 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9414
9415 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9416 * this output to turn on an external amplifier.
9417 */
9418 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9419 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9420
9421 { } /* end */
9422};
9423#endif
9424
a361d84b
KY
9425/* create input playback/capture controls for the given pin */
9426static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9427 const char *ctlname, int idx)
9428{
9429 char name[32];
9430 int err;
9431
9432 sprintf(name, "%s Playback Volume", ctlname);
9433 if (nid == 0x14) {
9434 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9435 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9436 HDA_OUTPUT));
9437 if (err < 0)
9438 return err;
9439 } else if (nid == 0x15) {
9440 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9441 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9442 HDA_OUTPUT));
9443 if (err < 0)
9444 return err;
9445 } else
9446 return -1;
9447 sprintf(name, "%s Playback Switch", ctlname);
9448 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9449 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9450 if (err < 0)
9451 return err;
9452 return 0;
9453}
9454
9455/* add playback controls from the parsed DAC table */
9456static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9457 const struct auto_pin_cfg *cfg)
9458{
9459 hda_nid_t nid;
9460 int err;
9461
9462 spec->multiout.num_dacs = 2; /* only use one dac */
9463 spec->multiout.dac_nids = spec->private_dac_nids;
9464 spec->multiout.dac_nids[0] = 2;
9465 spec->multiout.dac_nids[1] = 3;
9466
9467 nid = cfg->line_out_pins[0];
9468 if (nid)
9469 alc268_new_analog_output(spec, nid, "Front", 0);
9470
9471 nid = cfg->speaker_pins[0];
9472 if (nid == 0x1d) {
9473 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9474 "Speaker Playback Volume",
9475 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9476 if (err < 0)
9477 return err;
9478 }
9479 nid = cfg->hp_pins[0];
9480 if (nid)
9481 alc268_new_analog_output(spec, nid, "Headphone", 0);
9482
9483 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9484 if (nid == 0x16) {
9485 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9486 "Mono Playback Switch",
9487 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9488 if (err < 0)
9489 return err;
9490 }
9491 return 0;
9492}
9493
9494/* create playback/capture controls for input pins */
9495static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9496 const struct auto_pin_cfg *cfg)
9497{
9498 struct hda_input_mux *imux = &spec->private_imux;
9499 int i, idx1;
9500
9501 for (i = 0; i < AUTO_PIN_LAST; i++) {
9502 switch(cfg->input_pins[i]) {
9503 case 0x18:
9504 idx1 = 0; /* Mic 1 */
9505 break;
9506 case 0x19:
9507 idx1 = 1; /* Mic 2 */
9508 break;
9509 case 0x1a:
9510 idx1 = 2; /* Line In */
9511 break;
9512 case 0x1c:
9513 idx1 = 3; /* CD */
9514 break;
9515 default:
9516 continue;
9517 }
9518 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9519 imux->items[imux->num_items].index = idx1;
9520 imux->num_items++;
9521 }
9522 return 0;
9523}
9524
9525static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9526{
9527 struct alc_spec *spec = codec->spec;
9528 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9529 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9530 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9531 unsigned int dac_vol1, dac_vol2;
9532
9533 if (speaker_nid) {
9534 snd_hda_codec_write(codec, speaker_nid, 0,
9535 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9536 snd_hda_codec_write(codec, 0x0f, 0,
9537 AC_VERB_SET_AMP_GAIN_MUTE,
9538 AMP_IN_UNMUTE(1));
9539 snd_hda_codec_write(codec, 0x10, 0,
9540 AC_VERB_SET_AMP_GAIN_MUTE,
9541 AMP_IN_UNMUTE(1));
9542 } else {
9543 snd_hda_codec_write(codec, 0x0f, 0,
9544 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9545 snd_hda_codec_write(codec, 0x10, 0,
9546 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9547 }
9548
9549 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
9550 if (line_nid == 0x14)
9551 dac_vol2 = AMP_OUT_ZERO;
9552 else if (line_nid == 0x15)
9553 dac_vol1 = AMP_OUT_ZERO;
9554 if (hp_nid == 0x14)
9555 dac_vol2 = AMP_OUT_ZERO;
9556 else if (hp_nid == 0x15)
9557 dac_vol1 = AMP_OUT_ZERO;
9558 if (line_nid != 0x16 || hp_nid != 0x16 ||
9559 spec->autocfg.line_out_pins[1] != 0x16 ||
9560 spec->autocfg.line_out_pins[2] != 0x16)
9561 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9562
9563 snd_hda_codec_write(codec, 0x02, 0,
9564 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9565 snd_hda_codec_write(codec, 0x03, 0,
9566 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9567}
9568
9569/* pcm configuration: identiacal with ALC880 */
9570#define alc268_pcm_analog_playback alc880_pcm_analog_playback
9571#define alc268_pcm_analog_capture alc880_pcm_analog_capture
9572#define alc268_pcm_digital_playback alc880_pcm_digital_playback
9573
9574/*
9575 * BIOS auto configuration
9576 */
9577static int alc268_parse_auto_config(struct hda_codec *codec)
9578{
9579 struct alc_spec *spec = codec->spec;
9580 int err;
9581 static hda_nid_t alc268_ignore[] = { 0 };
9582
9583 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9584 alc268_ignore);
9585 if (err < 0)
9586 return err;
9587 if (!spec->autocfg.line_outs)
9588 return 0; /* can't find valid BIOS pin config */
9589
9590 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9591 if (err < 0)
9592 return err;
9593 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9594 if (err < 0)
9595 return err;
9596
9597 spec->multiout.max_channels = 2;
9598
9599 /* digital only support output */
9600 if (spec->autocfg.dig_out_pin)
9601 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9602
9603 if (spec->kctl_alloc)
9604 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9605
9606 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9607 spec->num_mux_defs = 1;
9608 spec->input_mux = &spec->private_imux;
9609
776e184e
TI
9610 err = alc_auto_add_mic_boost(codec);
9611 if (err < 0)
9612 return err;
9613
a361d84b
KY
9614 return 1;
9615}
9616
9617#define alc268_auto_init_multi_out alc882_auto_init_multi_out
9618#define alc268_auto_init_hp_out alc882_auto_init_hp_out
9619#define alc268_auto_init_analog_input alc882_auto_init_analog_input
9620
9621/* init callback for auto-configuration model -- overriding the default init */
9622static void alc268_auto_init(struct hda_codec *codec)
9623{
9624 alc268_auto_init_multi_out(codec);
9625 alc268_auto_init_hp_out(codec);
9626 alc268_auto_init_mono_speaker_out(codec);
9627 alc268_auto_init_analog_input(codec);
9628}
9629
9630/*
9631 * configuration and preset
9632 */
9633static const char *alc268_models[ALC268_MODEL_LAST] = {
9634 [ALC268_3ST] = "3stack",
983f8ae4 9635 [ALC268_TOSHIBA] = "toshiba",
d273809e 9636 [ALC268_ACER] = "acer",
86c53bd2
JW
9637#ifdef CONFIG_SND_DEBUG
9638 [ALC268_TEST] = "test",
9639#endif
a361d84b
KY
9640 [ALC268_AUTO] = "auto",
9641};
9642
9643static struct snd_pci_quirk alc268_cfg_tbl[] = {
ac3e3741
TI
9644 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9645 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9646 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 9647 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 9648 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 9649 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
b875bf3a 9650 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
a361d84b
KY
9651 {}
9652};
9653
9654static struct alc_config_preset alc268_presets[] = {
9655 [ALC268_3ST] = {
9656 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9657 .init_verbs = { alc268_base_init_verbs },
9658 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9659 .dac_nids = alc268_dac_nids,
9660 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9661 .adc_nids = alc268_adc_nids_alt,
9662 .hp_nid = 0x03,
9663 .dig_out_nid = ALC268_DIGOUT_NID,
9664 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9665 .channel_mode = alc268_modes,
9666 .input_mux = &alc268_capture_source,
9667 },
d1a991a6
KY
9668 [ALC268_TOSHIBA] = {
9669 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
d273809e
TI
9670 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9671 alc268_toshiba_verbs },
d1a991a6
KY
9672 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9673 .dac_nids = alc268_dac_nids,
9674 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9675 .adc_nids = alc268_adc_nids_alt,
9676 .hp_nid = 0x03,
9677 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9678 .channel_mode = alc268_modes,
9679 .input_mux = &alc268_capture_source,
d273809e
TI
9680 .unsol_event = alc268_toshiba_unsol_event,
9681 .init_hook = alc268_toshiba_automute,
9682 },
9683 [ALC268_ACER] = {
9684 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9685 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9686 alc268_acer_verbs },
9687 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9688 .dac_nids = alc268_dac_nids,
9689 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9690 .adc_nids = alc268_adc_nids_alt,
9691 .hp_nid = 0x02,
9692 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9693 .channel_mode = alc268_modes,
9694 .input_mux = &alc268_capture_source,
9695 .unsol_event = alc268_acer_unsol_event,
889c4395 9696 .init_hook = alc268_acer_init_hook,
d1a991a6 9697 },
86c53bd2
JW
9698#ifdef CONFIG_SND_DEBUG
9699 [ALC268_TEST] = {
9700 .mixers = { alc268_test_mixer, alc268_capture_mixer },
9701 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9702 alc268_volume_init_verbs },
9703 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9704 .dac_nids = alc268_dac_nids,
9705 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9706 .adc_nids = alc268_adc_nids_alt,
9707 .hp_nid = 0x03,
9708 .dig_out_nid = ALC268_DIGOUT_NID,
9709 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9710 .channel_mode = alc268_modes,
9711 .input_mux = &alc268_capture_source,
9712 },
9713#endif
a361d84b
KY
9714};
9715
9716static int patch_alc268(struct hda_codec *codec)
9717{
9718 struct alc_spec *spec;
9719 int board_config;
9720 int err;
9721
9722 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9723 if (spec == NULL)
9724 return -ENOMEM;
9725
9726 codec->spec = spec;
9727
9728 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9729 alc268_models,
9730 alc268_cfg_tbl);
9731
9732 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9733 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9734 "trying auto-probe from BIOS...\n");
9735 board_config = ALC268_AUTO;
9736 }
9737
9738 if (board_config == ALC268_AUTO) {
9739 /* automatic parse from the BIOS config */
9740 err = alc268_parse_auto_config(codec);
9741 if (err < 0) {
9742 alc_free(codec);
9743 return err;
9744 } else if (!err) {
9745 printk(KERN_INFO
9746 "hda_codec: Cannot set up configuration "
9747 "from BIOS. Using base mode...\n");
9748 board_config = ALC268_3ST;
9749 }
9750 }
9751
9752 if (board_config != ALC268_AUTO)
9753 setup_preset(spec, &alc268_presets[board_config]);
9754
9755 spec->stream_name_analog = "ALC268 Analog";
9756 spec->stream_analog_playback = &alc268_pcm_analog_playback;
9757 spec->stream_analog_capture = &alc268_pcm_analog_capture;
9758
9759 spec->stream_name_digital = "ALC268 Digital";
9760 spec->stream_digital_playback = &alc268_pcm_digital_playback;
9761
9762 if (board_config == ALC268_AUTO) {
9763 if (!spec->adc_nids && spec->input_mux) {
9764 /* check whether NID 0x07 is valid */
9765 unsigned int wcap = get_wcaps(codec, 0x07);
9766
9767 /* get type */
9768 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9769 if (wcap != AC_WID_AUD_IN) {
9770 spec->adc_nids = alc268_adc_nids_alt;
9771 spec->num_adc_nids =
9772 ARRAY_SIZE(alc268_adc_nids_alt);
9773 spec->mixers[spec->num_mixers] =
9774 alc268_capture_alt_mixer;
9775 spec->num_mixers++;
9776 } else {
9777 spec->adc_nids = alc268_adc_nids;
9778 spec->num_adc_nids =
9779 ARRAY_SIZE(alc268_adc_nids);
9780 spec->mixers[spec->num_mixers] =
9781 alc268_capture_mixer;
9782 spec->num_mixers++;
9783 }
9784 }
9785 }
9786 codec->patch_ops = alc_patch_ops;
9787 if (board_config == ALC268_AUTO)
9788 spec->init_hook = alc268_auto_init;
9789
9790 return 0;
9791}
9792
f6a92248
KY
9793/*
9794 * ALC269 channel source setting (2 channel)
9795 */
9796#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
9797
9798#define alc269_dac_nids alc260_dac_nids
9799
9800static hda_nid_t alc269_adc_nids[1] = {
9801 /* ADC1 */
9802 0x07,
9803};
9804
9805#define alc269_modes alc260_modes
9806#define alc269_capture_source alc880_lg_lw_capture_source
9807
9808static struct snd_kcontrol_new alc269_base_mixer[] = {
9809 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9810 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9811 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9812 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9815 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9816 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9817 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9818 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9819 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9820 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9821 { } /* end */
9822};
9823
9824/* capture mixer elements */
9825static struct snd_kcontrol_new alc269_capture_mixer[] = {
9826 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9827 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9828 {
9829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9830 /* The multiple "Capture Source" controls confuse alsamixer
9831 * So call somewhat different..
9832 * FIXME: the controls appear in the "playback" view!
9833 */
9834 /* .name = "Capture Source", */
9835 .name = "Input Source",
9836 .count = 1,
9837 .info = alc_mux_enum_info,
9838 .get = alc_mux_enum_get,
9839 .put = alc_mux_enum_put,
9840 },
9841 { } /* end */
9842};
9843
9844/*
9845 * generic initialization of ADC, input mixers and output mixers
9846 */
9847static struct hda_verb alc269_init_verbs[] = {
9848 /*
9849 * Unmute ADC0 and set the default input to mic-in
9850 */
9851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9852
9853 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9854 * analog-loopback mixer widget
9855 * Note: PASD motherboards uses the Line In 2 as the input for
9856 * front panel mic (mic 2)
9857 */
9858 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9861 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9863 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9864
9865 /*
9866 * Set up output mixers (0x0c - 0x0e)
9867 */
9868 /* set vol=0 to output mixers */
9869 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9870 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9871
9872 /* set up input amps for analog loopback */
9873 /* Amp Indices: DAC = 0, mixer = 1 */
9874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9876 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9877 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9878 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9879 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9880
9881 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9883 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9884 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9886 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9887 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9888
9889 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9890 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9892 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9893 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9894 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9896
9897 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9898 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9899
9900 /* FIXME: use matrix-type input source selection */
9901 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
9902 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9903 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9904 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9905 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9907
9908 /* set EAPD */
9909 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9910 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9911 { }
9912};
9913
9914/* add playback controls from the parsed DAC table */
9915static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
9916 const struct auto_pin_cfg *cfg)
9917{
9918 hda_nid_t nid;
9919 int err;
9920
9921 spec->multiout.num_dacs = 1; /* only use one dac */
9922 spec->multiout.dac_nids = spec->private_dac_nids;
9923 spec->multiout.dac_nids[0] = 2;
9924
9925 nid = cfg->line_out_pins[0];
9926 if (nid) {
9927 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9928 "Front Playback Volume",
9929 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
9930 if (err < 0)
9931 return err;
9932 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9933 "Front Playback Switch",
9934 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9935 if (err < 0)
9936 return err;
9937 }
9938
9939 nid = cfg->speaker_pins[0];
9940 if (nid) {
9941 if (!cfg->line_out_pins[0]) {
9942 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9943 "Speaker Playback Volume",
9944 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9945 HDA_OUTPUT));
9946 if (err < 0)
9947 return err;
9948 }
9949 if (nid == 0x16) {
9950 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9951 "Speaker Playback Switch",
9952 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9953 HDA_OUTPUT));
9954 if (err < 0)
9955 return err;
9956 } else {
9957 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9958 "Speaker Playback Switch",
9959 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9960 HDA_OUTPUT));
9961 if (err < 0)
9962 return err;
9963 }
9964 }
9965 nid = cfg->hp_pins[0];
9966 if (nid) {
9967 /* spec->multiout.hp_nid = 2; */
9968 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
9969 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9970 "Headphone Playback Volume",
9971 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9972 HDA_OUTPUT));
9973 if (err < 0)
9974 return err;
9975 }
9976 if (nid == 0x16) {
9977 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9978 "Headphone Playback Switch",
9979 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9980 HDA_OUTPUT));
9981 if (err < 0)
9982 return err;
9983 } else {
9984 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9985 "Headphone Playback Switch",
9986 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9987 HDA_OUTPUT));
9988 if (err < 0)
9989 return err;
9990 }
9991 }
9992 return 0;
9993}
9994
9995#define alc269_auto_create_analog_input_ctls \
9996 alc880_auto_create_analog_input_ctls
9997
9998#ifdef CONFIG_SND_HDA_POWER_SAVE
9999#define alc269_loopbacks alc880_loopbacks
10000#endif
10001
10002/* pcm configuration: identiacal with ALC880 */
10003#define alc269_pcm_analog_playback alc880_pcm_analog_playback
10004#define alc269_pcm_analog_capture alc880_pcm_analog_capture
10005#define alc269_pcm_digital_playback alc880_pcm_digital_playback
10006#define alc269_pcm_digital_capture alc880_pcm_digital_capture
10007
10008/*
10009 * BIOS auto configuration
10010 */
10011static int alc269_parse_auto_config(struct hda_codec *codec)
10012{
10013 struct alc_spec *spec = codec->spec;
10014 int err;
10015 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10016
10017 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10018 alc269_ignore);
10019 if (err < 0)
10020 return err;
10021
10022 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10023 if (err < 0)
10024 return err;
10025 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10026 if (err < 0)
10027 return err;
10028
10029 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10030
10031 if (spec->autocfg.dig_out_pin)
10032 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10033
10034 if (spec->kctl_alloc)
10035 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10036
10037 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10038 spec->num_mux_defs = 1;
10039 spec->input_mux = &spec->private_imux;
10040
10041 err = alc_auto_add_mic_boost(codec);
10042 if (err < 0)
10043 return err;
10044
10045 return 1;
10046}
10047
10048#define alc269_auto_init_multi_out alc882_auto_init_multi_out
10049#define alc269_auto_init_hp_out alc882_auto_init_hp_out
10050#define alc269_auto_init_analog_input alc882_auto_init_analog_input
10051
10052
10053/* init callback for auto-configuration model -- overriding the default init */
10054static void alc269_auto_init(struct hda_codec *codec)
10055{
10056 alc269_auto_init_multi_out(codec);
10057 alc269_auto_init_hp_out(codec);
10058 alc269_auto_init_analog_input(codec);
10059}
10060
10061/*
10062 * configuration and preset
10063 */
10064static const char *alc269_models[ALC269_MODEL_LAST] = {
10065 [ALC269_BASIC] = "basic",
10066};
10067
10068static struct snd_pci_quirk alc269_cfg_tbl[] = {
10069 {}
10070};
10071
10072static struct alc_config_preset alc269_presets[] = {
10073 [ALC269_BASIC] = {
10074 .mixers = { alc269_base_mixer },
10075 .init_verbs = { alc269_init_verbs },
10076 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10077 .dac_nids = alc269_dac_nids,
10078 .hp_nid = 0x03,
10079 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10080 .channel_mode = alc269_modes,
10081 .input_mux = &alc269_capture_source,
10082 },
10083};
10084
10085static int patch_alc269(struct hda_codec *codec)
10086{
10087 struct alc_spec *spec;
10088 int board_config;
10089 int err;
10090
10091 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10092 if (spec == NULL)
10093 return -ENOMEM;
10094
10095 codec->spec = spec;
10096
10097 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10098 alc269_models,
10099 alc269_cfg_tbl);
10100
10101 if (board_config < 0) {
10102 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10103 "trying auto-probe from BIOS...\n");
10104 board_config = ALC269_AUTO;
10105 }
10106
10107 if (board_config == ALC269_AUTO) {
10108 /* automatic parse from the BIOS config */
10109 err = alc269_parse_auto_config(codec);
10110 if (err < 0) {
10111 alc_free(codec);
10112 return err;
10113 } else if (!err) {
10114 printk(KERN_INFO
10115 "hda_codec: Cannot set up configuration "
10116 "from BIOS. Using base mode...\n");
10117 board_config = ALC269_BASIC;
10118 }
10119 }
10120
10121 if (board_config != ALC269_AUTO)
10122 setup_preset(spec, &alc269_presets[board_config]);
10123
10124 spec->stream_name_analog = "ALC269 Analog";
10125 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10126 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10127
10128 spec->stream_name_digital = "ALC269 Digital";
10129 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10130 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10131
10132 spec->adc_nids = alc269_adc_nids;
10133 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10134 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10135 spec->num_mixers++;
10136
10137 codec->patch_ops = alc_patch_ops;
10138 if (board_config == ALC269_AUTO)
10139 spec->init_hook = alc269_auto_init;
10140#ifdef CONFIG_SND_HDA_POWER_SAVE
10141 if (!spec->loopback.amplist)
10142 spec->loopback.amplist = alc269_loopbacks;
10143#endif
10144
10145 return 0;
10146}
10147
df694daa
KY
10148/*
10149 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10150 */
10151
10152/*
10153 * set the path ways for 2 channel output
10154 * need to set the codec line out and mic 1 pin widgets to inputs
10155 */
10156static struct hda_verb alc861_threestack_ch2_init[] = {
10157 /* set pin widget 1Ah (line in) for input */
10158 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10159 /* set pin widget 18h (mic1/2) for input, for mic also enable
10160 * the vref
10161 */
df694daa
KY
10162 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10163
9c7f852e
TI
10164 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10165#if 0
10166 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10167 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10168#endif
df694daa
KY
10169 { } /* end */
10170};
10171/*
10172 * 6ch mode
10173 * need to set the codec line out and mic 1 pin widgets to outputs
10174 */
10175static struct hda_verb alc861_threestack_ch6_init[] = {
10176 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10177 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10178 /* set pin widget 18h (mic1) for output (CLFE)*/
10179 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10180
10181 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 10182 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 10183
9c7f852e
TI
10184 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10185#if 0
10186 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10187 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10188#endif
df694daa
KY
10189 { } /* end */
10190};
10191
10192static struct hda_channel_mode alc861_threestack_modes[2] = {
10193 { 2, alc861_threestack_ch2_init },
10194 { 6, alc861_threestack_ch6_init },
10195};
22309c3e
TI
10196/* Set mic1 as input and unmute the mixer */
10197static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10198 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10199 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10200 { } /* end */
10201};
10202/* Set mic1 as output and mute mixer */
10203static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10204 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10205 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10206 { } /* end */
10207};
10208
10209static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10210 { 2, alc861_uniwill_m31_ch2_init },
10211 { 4, alc861_uniwill_m31_ch4_init },
10212};
df694daa 10213
7cdbff94
MD
10214/* Set mic1 and line-in as input and unmute the mixer */
10215static struct hda_verb alc861_asus_ch2_init[] = {
10216 /* set pin widget 1Ah (line in) for input */
10217 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10218 /* set pin widget 18h (mic1/2) for input, for mic also enable
10219 * the vref
10220 */
7cdbff94
MD
10221 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10222
10223 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10224#if 0
10225 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10226 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10227#endif
10228 { } /* end */
10229};
10230/* Set mic1 nad line-in as output and mute mixer */
10231static struct hda_verb alc861_asus_ch6_init[] = {
10232 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10233 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10234 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10235 /* set pin widget 18h (mic1) for output (CLFE)*/
10236 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10237 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10238 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10239 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10240
10241 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10242#if 0
10243 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10244 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10245#endif
10246 { } /* end */
10247};
10248
10249static struct hda_channel_mode alc861_asus_modes[2] = {
10250 { 2, alc861_asus_ch2_init },
10251 { 6, alc861_asus_ch6_init },
10252};
10253
df694daa
KY
10254/* patch-ALC861 */
10255
10256static struct snd_kcontrol_new alc861_base_mixer[] = {
10257 /* output mixer control */
10258 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10259 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10260 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10261 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10262 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10263
10264 /*Input mixer control */
10265 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10266 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10267 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10268 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10269 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10270 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10272 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10273 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10275
df694daa
KY
10276 /* Capture mixer control */
10277 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10278 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10279 {
10280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10281 .name = "Capture Source",
10282 .count = 1,
10283 .info = alc_mux_enum_info,
10284 .get = alc_mux_enum_get,
10285 .put = alc_mux_enum_put,
10286 },
10287 { } /* end */
10288};
10289
10290static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10291 /* output mixer control */
10292 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10293 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10294 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10295 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10296 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10297
10298 /* Input mixer control */
10299 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10300 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10301 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10302 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10303 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10304 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10306 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10307 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10309
df694daa
KY
10310 /* Capture mixer control */
10311 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10312 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10313 {
10314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10315 .name = "Capture Source",
10316 .count = 1,
10317 .info = alc_mux_enum_info,
10318 .get = alc_mux_enum_get,
10319 .put = alc_mux_enum_put,
10320 },
10321 {
10322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10323 .name = "Channel Mode",
10324 .info = alc_ch_mode_info,
10325 .get = alc_ch_mode_get,
10326 .put = alc_ch_mode_put,
10327 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10328 },
10329 { } /* end */
a53d1aec
TD
10330};
10331
d1d985f0 10332static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
10333 /* output mixer control */
10334 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10336 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10337
10338 /*Capture mixer control */
10339 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10340 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10341 {
10342 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10343 .name = "Capture Source",
10344 .count = 1,
10345 .info = alc_mux_enum_info,
10346 .get = alc_mux_enum_get,
10347 .put = alc_mux_enum_put,
10348 },
10349
10350 { } /* end */
f12ab1e0 10351};
a53d1aec 10352
22309c3e
TI
10353static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10354 /* output mixer control */
10355 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10356 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10357 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10358 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10359 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10360
10361 /* Input mixer control */
10362 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10363 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10364 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10365 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10366 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10367 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10369 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10370 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10371 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10372
22309c3e
TI
10373 /* Capture mixer control */
10374 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10375 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10376 {
10377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10378 .name = "Capture Source",
10379 .count = 1,
10380 .info = alc_mux_enum_info,
10381 .get = alc_mux_enum_get,
10382 .put = alc_mux_enum_put,
10383 },
10384 {
10385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10386 .name = "Channel Mode",
10387 .info = alc_ch_mode_info,
10388 .get = alc_ch_mode_get,
10389 .put = alc_ch_mode_put,
10390 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10391 },
10392 { } /* end */
f12ab1e0 10393};
7cdbff94
MD
10394
10395static struct snd_kcontrol_new alc861_asus_mixer[] = {
10396 /* output mixer control */
10397 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10398 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10399 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10400 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10401 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10402
10403 /* Input mixer control */
10404 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10405 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10406 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10407 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10408 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10409 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10411 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10412 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
10413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10414
7cdbff94
MD
10415 /* Capture mixer control */
10416 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10417 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10418 {
10419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10420 .name = "Capture Source",
10421 .count = 1,
10422 .info = alc_mux_enum_info,
10423 .get = alc_mux_enum_get,
10424 .put = alc_mux_enum_put,
10425 },
10426 {
10427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10428 .name = "Channel Mode",
10429 .info = alc_ch_mode_info,
10430 .get = alc_ch_mode_get,
10431 .put = alc_ch_mode_put,
10432 .private_value = ARRAY_SIZE(alc861_asus_modes),
10433 },
10434 { }
56bb0cab
TI
10435};
10436
10437/* additional mixer */
d1d985f0 10438static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
10439 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10440 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10441 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10442 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10443 { }
10444};
7cdbff94 10445
df694daa
KY
10446/*
10447 * generic initialization of ADC, input mixers and output mixers
10448 */
10449static struct hda_verb alc861_base_init_verbs[] = {
10450 /*
10451 * Unmute ADC0 and set the default input to mic-in
10452 */
10453 /* port-A for surround (rear panel) */
10454 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10455 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10456 /* port-B for mic-in (rear panel) with vref */
10457 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10458 /* port-C for line-in (rear panel) */
10459 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10460 /* port-D for Front */
10461 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10462 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10463 /* port-E for HP out (front panel) */
10464 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10465 /* route front PCM to HP */
9dece1d7 10466 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10467 /* port-F for mic-in (front panel) with vref */
10468 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10469 /* port-G for CLFE (rear panel) */
10470 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10471 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10472 /* port-H for side (rear panel) */
10473 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10474 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10475 /* CD-in */
10476 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10477 /* route front mic to ADC1*/
10478 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10479 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10480
10481 /* Unmute DAC0~3 & spdif out*/
10482 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10483 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10484 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10485 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10487
10488 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10489 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10490 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10491 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10492 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10493
10494 /* Unmute Stereo Mixer 15 */
10495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
10499
10500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10502 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10503 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10504 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10505 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10507 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10508 /* hp used DAC 3 (Front) */
10509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10511
10512 { }
10513};
10514
10515static struct hda_verb alc861_threestack_init_verbs[] = {
10516 /*
10517 * Unmute ADC0 and set the default input to mic-in
10518 */
10519 /* port-A for surround (rear panel) */
10520 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10521 /* port-B for mic-in (rear panel) with vref */
10522 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10523 /* port-C for line-in (rear panel) */
10524 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10525 /* port-D for Front */
10526 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10527 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10528 /* port-E for HP out (front panel) */
10529 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10530 /* route front PCM to HP */
9dece1d7 10531 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10532 /* port-F for mic-in (front panel) with vref */
10533 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10534 /* port-G for CLFE (rear panel) */
10535 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10536 /* port-H for side (rear panel) */
10537 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10538 /* CD-in */
10539 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10540 /* route front mic to ADC1*/
10541 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10543 /* Unmute DAC0~3 & spdif out*/
10544 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10545 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10546 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10547 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10549
10550 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10551 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10552 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10553 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10554 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10555
10556 /* Unmute Stereo Mixer 15 */
10557 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10560 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
10561
10562 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10564 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10565 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10570 /* hp used DAC 3 (Front) */
10571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10573 { }
10574};
22309c3e
TI
10575
10576static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10577 /*
10578 * Unmute ADC0 and set the default input to mic-in
10579 */
10580 /* port-A for surround (rear panel) */
10581 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10582 /* port-B for mic-in (rear panel) with vref */
10583 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10584 /* port-C for line-in (rear panel) */
10585 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10586 /* port-D for Front */
10587 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10588 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10589 /* port-E for HP out (front panel) */
f12ab1e0
TI
10590 /* this has to be set to VREF80 */
10591 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 10592 /* route front PCM to HP */
9dece1d7 10593 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
10594 /* port-F for mic-in (front panel) with vref */
10595 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10596 /* port-G for CLFE (rear panel) */
10597 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10598 /* port-H for side (rear panel) */
10599 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10600 /* CD-in */
10601 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10602 /* route front mic to ADC1*/
10603 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10605 /* Unmute DAC0~3 & spdif out*/
10606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10608 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10609 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10610 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10611
10612 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10613 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10614 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10615 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10616 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10617
10618 /* Unmute Stereo Mixer 15 */
10619 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
10623
10624 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10626 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10627 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10630 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10632 /* hp used DAC 3 (Front) */
10633 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
10634 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10635 { }
10636};
10637
7cdbff94
MD
10638static struct hda_verb alc861_asus_init_verbs[] = {
10639 /*
10640 * Unmute ADC0 and set the default input to mic-in
10641 */
f12ab1e0
TI
10642 /* port-A for surround (rear panel)
10643 * according to codec#0 this is the HP jack
10644 */
7cdbff94
MD
10645 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10646 /* route front PCM to HP */
10647 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10648 /* port-B for mic-in (rear panel) with vref */
10649 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10650 /* port-C for line-in (rear panel) */
10651 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10652 /* port-D for Front */
10653 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10654 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10655 /* port-E for HP out (front panel) */
f12ab1e0
TI
10656 /* this has to be set to VREF80 */
10657 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 10658 /* route front PCM to HP */
9dece1d7 10659 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
10660 /* port-F for mic-in (front panel) with vref */
10661 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10662 /* port-G for CLFE (rear panel) */
10663 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10664 /* port-H for side (rear panel) */
10665 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10666 /* CD-in */
10667 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10668 /* route front mic to ADC1*/
10669 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10671 /* Unmute DAC0~3 & spdif out*/
10672 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10673 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10675 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10677 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10678 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10679 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10680 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10681 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10682
10683 /* Unmute Stereo Mixer 15 */
10684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
10688
10689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10690 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10691 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10692 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10696 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10697 /* hp used DAC 3 (Front) */
10698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
10699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10700 { }
10701};
10702
56bb0cab
TI
10703/* additional init verbs for ASUS laptops */
10704static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10705 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10706 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10707 { }
10708};
7cdbff94 10709
df694daa
KY
10710/*
10711 * generic initialization of ADC, input mixers and output mixers
10712 */
10713static struct hda_verb alc861_auto_init_verbs[] = {
10714 /*
10715 * Unmute ADC0 and set the default input to mic-in
10716 */
f12ab1e0 10717 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
10718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10719
10720 /* Unmute DAC0~3 & spdif out*/
10721 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10722 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10723 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10724 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10725 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10726
10727 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10728 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10729 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10730 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10731 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10732
10733 /* Unmute Stereo Mixer 15 */
10734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10737 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10738
10739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10741 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10746 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10747
10748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
10750 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10751 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10752 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10753 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
10754 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 10756
f12ab1e0 10757 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
10758
10759 { }
10760};
10761
a53d1aec
TD
10762static struct hda_verb alc861_toshiba_init_verbs[] = {
10763 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 10764
a53d1aec
TD
10765 { }
10766};
10767
10768/* toggle speaker-output according to the hp-jack state */
10769static void alc861_toshiba_automute(struct hda_codec *codec)
10770{
10771 unsigned int present;
10772
10773 present = snd_hda_codec_read(codec, 0x0f, 0,
10774 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
10775 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10776 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10777 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10778 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
10779}
10780
10781static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10782 unsigned int res)
10783{
a53d1aec
TD
10784 if ((res >> 26) == ALC880_HP_EVENT)
10785 alc861_toshiba_automute(codec);
10786}
10787
df694daa
KY
10788/* pcm configuration: identiacal with ALC880 */
10789#define alc861_pcm_analog_playback alc880_pcm_analog_playback
10790#define alc861_pcm_analog_capture alc880_pcm_analog_capture
10791#define alc861_pcm_digital_playback alc880_pcm_digital_playback
10792#define alc861_pcm_digital_capture alc880_pcm_digital_capture
10793
10794
10795#define ALC861_DIGOUT_NID 0x07
10796
10797static struct hda_channel_mode alc861_8ch_modes[1] = {
10798 { 8, NULL }
10799};
10800
10801static hda_nid_t alc861_dac_nids[4] = {
10802 /* front, surround, clfe, side */
10803 0x03, 0x06, 0x05, 0x04
10804};
10805
9c7f852e
TI
10806static hda_nid_t alc660_dac_nids[3] = {
10807 /* front, clfe, surround */
10808 0x03, 0x05, 0x06
10809};
10810
df694daa
KY
10811static hda_nid_t alc861_adc_nids[1] = {
10812 /* ADC0-2 */
10813 0x08,
10814};
10815
10816static struct hda_input_mux alc861_capture_source = {
10817 .num_items = 5,
10818 .items = {
10819 { "Mic", 0x0 },
10820 { "Front Mic", 0x3 },
10821 { "Line", 0x1 },
10822 { "CD", 0x4 },
10823 { "Mixer", 0x5 },
10824 },
10825};
10826
10827/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
10828static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10829 const struct auto_pin_cfg *cfg)
df694daa
KY
10830{
10831 int i;
10832 hda_nid_t nid;
10833
10834 spec->multiout.dac_nids = spec->private_dac_nids;
10835 for (i = 0; i < cfg->line_outs; i++) {
10836 nid = cfg->line_out_pins[i];
10837 if (nid) {
10838 if (i >= ARRAY_SIZE(alc861_dac_nids))
10839 continue;
10840 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10841 }
10842 }
10843 spec->multiout.num_dacs = cfg->line_outs;
10844 return 0;
10845}
10846
10847/* add playback controls from the parsed DAC table */
10848static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10849 const struct auto_pin_cfg *cfg)
10850{
10851 char name[32];
f12ab1e0
TI
10852 static const char *chname[4] = {
10853 "Front", "Surround", NULL /*CLFE*/, "Side"
10854 };
df694daa
KY
10855 hda_nid_t nid;
10856 int i, idx, err;
10857
10858 for (i = 0; i < cfg->line_outs; i++) {
10859 nid = spec->multiout.dac_nids[i];
f12ab1e0 10860 if (!nid)
df694daa
KY
10861 continue;
10862 if (nid == 0x05) {
10863 /* Center/LFE */
f12ab1e0
TI
10864 err = add_control(spec, ALC_CTL_BIND_MUTE,
10865 "Center Playback Switch",
10866 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10867 HDA_OUTPUT));
10868 if (err < 0)
df694daa 10869 return err;
f12ab1e0
TI
10870 err = add_control(spec, ALC_CTL_BIND_MUTE,
10871 "LFE Playback Switch",
10872 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10873 HDA_OUTPUT));
10874 if (err < 0)
df694daa
KY
10875 return err;
10876 } else {
f12ab1e0
TI
10877 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10878 idx++)
df694daa
KY
10879 if (nid == alc861_dac_nids[idx])
10880 break;
10881 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
10882 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10883 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10884 HDA_OUTPUT));
10885 if (err < 0)
df694daa
KY
10886 return err;
10887 }
10888 }
10889 return 0;
10890}
10891
10892static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10893{
10894 int err;
10895 hda_nid_t nid;
10896
f12ab1e0 10897 if (!pin)
df694daa
KY
10898 return 0;
10899
10900 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10901 nid = 0x03;
f12ab1e0
TI
10902 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10903 "Headphone Playback Switch",
10904 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10905 if (err < 0)
df694daa
KY
10906 return err;
10907 spec->multiout.hp_nid = nid;
10908 }
10909 return 0;
10910}
10911
10912/* create playback/capture controls for input pins */
f12ab1e0
TI
10913static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10914 const struct auto_pin_cfg *cfg)
df694daa 10915{
df694daa
KY
10916 struct hda_input_mux *imux = &spec->private_imux;
10917 int i, err, idx, idx1;
10918
10919 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 10920 switch (cfg->input_pins[i]) {
df694daa
KY
10921 case 0x0c:
10922 idx1 = 1;
f12ab1e0 10923 idx = 2; /* Line In */
df694daa
KY
10924 break;
10925 case 0x0f:
10926 idx1 = 2;
f12ab1e0 10927 idx = 2; /* Line In */
df694daa
KY
10928 break;
10929 case 0x0d:
10930 idx1 = 0;
f12ab1e0 10931 idx = 1; /* Mic In */
df694daa 10932 break;
f12ab1e0 10933 case 0x10:
df694daa 10934 idx1 = 3;
f12ab1e0 10935 idx = 1; /* Mic In */
df694daa
KY
10936 break;
10937 case 0x11:
10938 idx1 = 4;
f12ab1e0 10939 idx = 0; /* CD */
df694daa
KY
10940 break;
10941 default:
10942 continue;
10943 }
10944
4a471b7d
TI
10945 err = new_analog_input(spec, cfg->input_pins[i],
10946 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
10947 if (err < 0)
10948 return err;
10949
4a471b7d 10950 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 10951 imux->items[imux->num_items].index = idx1;
f12ab1e0 10952 imux->num_items++;
df694daa
KY
10953 }
10954 return 0;
10955}
10956
10957static struct snd_kcontrol_new alc861_capture_mixer[] = {
10958 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10959 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10960
10961 {
10962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10963 /* The multiple "Capture Source" controls confuse alsamixer
10964 * So call somewhat different..
10965 *FIXME: the controls appear in the "playback" view!
10966 */
10967 /* .name = "Capture Source", */
10968 .name = "Input Source",
10969 .count = 1,
10970 .info = alc_mux_enum_info,
10971 .get = alc_mux_enum_get,
10972 .put = alc_mux_enum_put,
10973 },
10974 { } /* end */
10975};
10976
f12ab1e0
TI
10977static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10978 hda_nid_t nid,
df694daa
KY
10979 int pin_type, int dac_idx)
10980{
10981 /* set as output */
10982
f12ab1e0
TI
10983 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10984 pin_type);
10985 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10986 AMP_OUT_UNMUTE);
df694daa
KY
10987
10988}
10989
10990static void alc861_auto_init_multi_out(struct hda_codec *codec)
10991{
10992 struct alc_spec *spec = codec->spec;
10993 int i;
10994
bc9f98a9 10995 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
10996 for (i = 0; i < spec->autocfg.line_outs; i++) {
10997 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10998 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 10999 if (nid)
baba8ee9 11000 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 11001 spec->multiout.dac_nids[i]);
df694daa
KY
11002 }
11003}
11004
11005static void alc861_auto_init_hp_out(struct hda_codec *codec)
11006{
11007 struct alc_spec *spec = codec->spec;
11008 hda_nid_t pin;
11009
eb06ed8f 11010 pin = spec->autocfg.hp_pins[0];
df694daa 11011 if (pin) /* connect to front */
f12ab1e0
TI
11012 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11013 spec->multiout.dac_nids[0]);
df694daa
KY
11014}
11015
11016static void alc861_auto_init_analog_input(struct hda_codec *codec)
11017{
11018 struct alc_spec *spec = codec->spec;
11019 int i;
11020
11021 for (i = 0; i < AUTO_PIN_LAST; i++) {
11022 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
11023 if (nid >= 0x0c && nid <= 0x11) {
11024 snd_hda_codec_write(codec, nid, 0,
11025 AC_VERB_SET_PIN_WIDGET_CONTROL,
11026 i <= AUTO_PIN_FRONT_MIC ?
11027 PIN_VREF80 : PIN_IN);
df694daa
KY
11028 }
11029 }
11030}
11031
11032/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
11033/* return 1 if successful, 0 if the proper config is not found,
11034 * or a negative error code
11035 */
df694daa
KY
11036static int alc861_parse_auto_config(struct hda_codec *codec)
11037{
11038 struct alc_spec *spec = codec->spec;
11039 int err;
11040 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11041
f12ab1e0
TI
11042 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11043 alc861_ignore);
11044 if (err < 0)
df694daa 11045 return err;
f12ab1e0 11046 if (!spec->autocfg.line_outs)
df694daa
KY
11047 return 0; /* can't find valid BIOS pin config */
11048
f12ab1e0
TI
11049 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11050 if (err < 0)
11051 return err;
11052 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11053 if (err < 0)
11054 return err;
11055 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11056 if (err < 0)
11057 return err;
11058 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11059 if (err < 0)
df694daa
KY
11060 return err;
11061
11062 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11063
11064 if (spec->autocfg.dig_out_pin)
11065 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11066
11067 if (spec->kctl_alloc)
11068 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11069
11070 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11071
a1e8d2da 11072 spec->num_mux_defs = 1;
df694daa
KY
11073 spec->input_mux = &spec->private_imux;
11074
11075 spec->adc_nids = alc861_adc_nids;
11076 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11077 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11078 spec->num_mixers++;
11079
11080 return 1;
11081}
11082
ae6b813a
TI
11083/* additional initialization for auto-configuration model */
11084static void alc861_auto_init(struct hda_codec *codec)
df694daa 11085{
df694daa
KY
11086 alc861_auto_init_multi_out(codec);
11087 alc861_auto_init_hp_out(codec);
11088 alc861_auto_init_analog_input(codec);
df694daa
KY
11089}
11090
cb53c626
TI
11091#ifdef CONFIG_SND_HDA_POWER_SAVE
11092static struct hda_amp_list alc861_loopbacks[] = {
11093 { 0x15, HDA_INPUT, 0 },
11094 { 0x15, HDA_INPUT, 1 },
11095 { 0x15, HDA_INPUT, 2 },
11096 { 0x15, HDA_INPUT, 3 },
11097 { } /* end */
11098};
11099#endif
11100
df694daa
KY
11101
11102/*
11103 * configuration and preset
11104 */
f5fcc13c
TI
11105static const char *alc861_models[ALC861_MODEL_LAST] = {
11106 [ALC861_3ST] = "3stack",
11107 [ALC660_3ST] = "3stack-660",
11108 [ALC861_3ST_DIG] = "3stack-dig",
11109 [ALC861_6ST_DIG] = "6stack-dig",
11110 [ALC861_UNIWILL_M31] = "uniwill-m31",
11111 [ALC861_TOSHIBA] = "toshiba",
11112 [ALC861_ASUS] = "asus",
11113 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11114 [ALC861_AUTO] = "auto",
11115};
11116
11117static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 11118 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
11119 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11120 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11121 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 11122 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 11123 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 11124 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
11125 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11126 * Any other models that need this preset?
11127 */
11128 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
11129 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11130 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 11131 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
11132 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11133 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11134 /* FIXME: the below seems conflict */
11135 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 11136 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 11137 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
11138 {}
11139};
11140
11141static struct alc_config_preset alc861_presets[] = {
11142 [ALC861_3ST] = {
11143 .mixers = { alc861_3ST_mixer },
11144 .init_verbs = { alc861_threestack_init_verbs },
11145 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11146 .dac_nids = alc861_dac_nids,
11147 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11148 .channel_mode = alc861_threestack_modes,
4e195a7b 11149 .need_dac_fix = 1,
df694daa
KY
11150 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11151 .adc_nids = alc861_adc_nids,
11152 .input_mux = &alc861_capture_source,
11153 },
11154 [ALC861_3ST_DIG] = {
11155 .mixers = { alc861_base_mixer },
11156 .init_verbs = { alc861_threestack_init_verbs },
11157 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11158 .dac_nids = alc861_dac_nids,
11159 .dig_out_nid = ALC861_DIGOUT_NID,
11160 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11161 .channel_mode = alc861_threestack_modes,
4e195a7b 11162 .need_dac_fix = 1,
df694daa
KY
11163 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11164 .adc_nids = alc861_adc_nids,
11165 .input_mux = &alc861_capture_source,
11166 },
11167 [ALC861_6ST_DIG] = {
11168 .mixers = { alc861_base_mixer },
11169 .init_verbs = { alc861_base_init_verbs },
11170 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11171 .dac_nids = alc861_dac_nids,
11172 .dig_out_nid = ALC861_DIGOUT_NID,
11173 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11174 .channel_mode = alc861_8ch_modes,
11175 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11176 .adc_nids = alc861_adc_nids,
11177 .input_mux = &alc861_capture_source,
11178 },
9c7f852e
TI
11179 [ALC660_3ST] = {
11180 .mixers = { alc861_3ST_mixer },
11181 .init_verbs = { alc861_threestack_init_verbs },
11182 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11183 .dac_nids = alc660_dac_nids,
11184 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11185 .channel_mode = alc861_threestack_modes,
4e195a7b 11186 .need_dac_fix = 1,
9c7f852e
TI
11187 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11188 .adc_nids = alc861_adc_nids,
11189 .input_mux = &alc861_capture_source,
11190 },
22309c3e
TI
11191 [ALC861_UNIWILL_M31] = {
11192 .mixers = { alc861_uniwill_m31_mixer },
11193 .init_verbs = { alc861_uniwill_m31_init_verbs },
11194 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11195 .dac_nids = alc861_dac_nids,
11196 .dig_out_nid = ALC861_DIGOUT_NID,
11197 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11198 .channel_mode = alc861_uniwill_m31_modes,
11199 .need_dac_fix = 1,
11200 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11201 .adc_nids = alc861_adc_nids,
11202 .input_mux = &alc861_capture_source,
11203 },
a53d1aec
TD
11204 [ALC861_TOSHIBA] = {
11205 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
11206 .init_verbs = { alc861_base_init_verbs,
11207 alc861_toshiba_init_verbs },
a53d1aec
TD
11208 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11209 .dac_nids = alc861_dac_nids,
11210 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11211 .channel_mode = alc883_3ST_2ch_modes,
11212 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11213 .adc_nids = alc861_adc_nids,
11214 .input_mux = &alc861_capture_source,
11215 .unsol_event = alc861_toshiba_unsol_event,
11216 .init_hook = alc861_toshiba_automute,
11217 },
7cdbff94
MD
11218 [ALC861_ASUS] = {
11219 .mixers = { alc861_asus_mixer },
11220 .init_verbs = { alc861_asus_init_verbs },
11221 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11222 .dac_nids = alc861_dac_nids,
11223 .dig_out_nid = ALC861_DIGOUT_NID,
11224 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11225 .channel_mode = alc861_asus_modes,
11226 .need_dac_fix = 1,
11227 .hp_nid = 0x06,
11228 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11229 .adc_nids = alc861_adc_nids,
11230 .input_mux = &alc861_capture_source,
11231 },
56bb0cab
TI
11232 [ALC861_ASUS_LAPTOP] = {
11233 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11234 .init_verbs = { alc861_asus_init_verbs,
11235 alc861_asus_laptop_init_verbs },
11236 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11237 .dac_nids = alc861_dac_nids,
11238 .dig_out_nid = ALC861_DIGOUT_NID,
11239 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11240 .channel_mode = alc883_3ST_2ch_modes,
11241 .need_dac_fix = 1,
11242 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11243 .adc_nids = alc861_adc_nids,
11244 .input_mux = &alc861_capture_source,
11245 },
11246};
df694daa
KY
11247
11248
11249static int patch_alc861(struct hda_codec *codec)
11250{
11251 struct alc_spec *spec;
11252 int board_config;
11253 int err;
11254
dc041e0b 11255 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11256 if (spec == NULL)
11257 return -ENOMEM;
11258
f12ab1e0 11259 codec->spec = spec;
df694daa 11260
f5fcc13c
TI
11261 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11262 alc861_models,
11263 alc861_cfg_tbl);
9c7f852e 11264
f5fcc13c 11265 if (board_config < 0) {
9c7f852e
TI
11266 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11267 "trying auto-probe from BIOS...\n");
df694daa
KY
11268 board_config = ALC861_AUTO;
11269 }
11270
11271 if (board_config == ALC861_AUTO) {
11272 /* automatic parse from the BIOS config */
11273 err = alc861_parse_auto_config(codec);
11274 if (err < 0) {
11275 alc_free(codec);
11276 return err;
f12ab1e0 11277 } else if (!err) {
9c7f852e
TI
11278 printk(KERN_INFO
11279 "hda_codec: Cannot set up configuration "
11280 "from BIOS. Using base mode...\n");
df694daa
KY
11281 board_config = ALC861_3ST_DIG;
11282 }
11283 }
11284
11285 if (board_config != ALC861_AUTO)
11286 setup_preset(spec, &alc861_presets[board_config]);
11287
11288 spec->stream_name_analog = "ALC861 Analog";
11289 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11290 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11291
11292 spec->stream_name_digital = "ALC861 Digital";
11293 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11294 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11295
11296 codec->patch_ops = alc_patch_ops;
11297 if (board_config == ALC861_AUTO)
ae6b813a 11298 spec->init_hook = alc861_auto_init;
cb53c626
TI
11299#ifdef CONFIG_SND_HDA_POWER_SAVE
11300 if (!spec->loopback.amplist)
11301 spec->loopback.amplist = alc861_loopbacks;
11302#endif
df694daa 11303
1da177e4
LT
11304 return 0;
11305}
11306
f32610ed
JS
11307/*
11308 * ALC861-VD support
11309 *
11310 * Based on ALC882
11311 *
11312 * In addition, an independent DAC
11313 */
11314#define ALC861VD_DIGOUT_NID 0x06
11315
11316static hda_nid_t alc861vd_dac_nids[4] = {
11317 /* front, surr, clfe, side surr */
11318 0x02, 0x03, 0x04, 0x05
11319};
11320
11321/* dac_nids for ALC660vd are in a different order - according to
11322 * Realtek's driver.
11323 * This should probably tesult in a different mixer for 6stack models
11324 * of ALC660vd codecs, but for now there is only 3stack mixer
11325 * - and it is the same as in 861vd.
11326 * adc_nids in ALC660vd are (is) the same as in 861vd
11327 */
11328static hda_nid_t alc660vd_dac_nids[3] = {
11329 /* front, rear, clfe, rear_surr */
11330 0x02, 0x04, 0x03
11331};
11332
11333static hda_nid_t alc861vd_adc_nids[1] = {
11334 /* ADC0 */
11335 0x09,
11336};
11337
11338/* input MUX */
11339/* FIXME: should be a matrix-type input source selection */
11340static struct hda_input_mux alc861vd_capture_source = {
11341 .num_items = 4,
11342 .items = {
11343 { "Mic", 0x0 },
11344 { "Front Mic", 0x1 },
11345 { "Line", 0x2 },
11346 { "CD", 0x4 },
11347 },
11348};
11349
272a527c
KY
11350static struct hda_input_mux alc861vd_dallas_capture_source = {
11351 .num_items = 3,
11352 .items = {
11353 { "Front Mic", 0x0 },
11354 { "ATAPI Mic", 0x1 },
11355 { "Line In", 0x5 },
11356 },
11357};
11358
d1a991a6
KY
11359static struct hda_input_mux alc861vd_hp_capture_source = {
11360 .num_items = 2,
11361 .items = {
11362 { "Front Mic", 0x0 },
11363 { "ATAPI Mic", 0x1 },
11364 },
11365};
11366
f32610ed
JS
11367#define alc861vd_mux_enum_info alc_mux_enum_info
11368#define alc861vd_mux_enum_get alc_mux_enum_get
11369
11370static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11371 struct snd_ctl_elem_value *ucontrol)
11372{
11373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11374 struct alc_spec *spec = codec->spec;
11375 const struct hda_input_mux *imux = spec->input_mux;
11376 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11377 static hda_nid_t capture_mixers[1] = { 0x22 };
11378 hda_nid_t nid = capture_mixers[adc_idx];
11379 unsigned int *cur_val = &spec->cur_mux[adc_idx];
11380 unsigned int i, idx;
11381
11382 idx = ucontrol->value.enumerated.item[0];
11383 if (idx >= imux->num_items)
11384 idx = imux->num_items - 1;
82beb8fd 11385 if (*cur_val == idx)
f32610ed
JS
11386 return 0;
11387 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
11388 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11389 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11390 imux->items[i].index,
11391 HDA_AMP_MUTE, v);
f32610ed
JS
11392 }
11393 *cur_val = idx;
11394 return 1;
11395}
11396
11397/*
11398 * 2ch mode
11399 */
11400static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11401 { 2, NULL }
11402};
11403
11404/*
11405 * 6ch mode
11406 */
11407static struct hda_verb alc861vd_6stack_ch6_init[] = {
11408 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11409 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11410 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11411 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11412 { } /* end */
11413};
11414
11415/*
11416 * 8ch mode
11417 */
11418static struct hda_verb alc861vd_6stack_ch8_init[] = {
11419 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11420 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11421 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11422 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11423 { } /* end */
11424};
11425
11426static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11427 { 6, alc861vd_6stack_ch6_init },
11428 { 8, alc861vd_6stack_ch8_init },
11429};
11430
11431static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11432 {
11433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11434 .name = "Channel Mode",
11435 .info = alc_ch_mode_info,
11436 .get = alc_ch_mode_get,
11437 .put = alc_ch_mode_put,
11438 },
11439 { } /* end */
11440};
11441
11442static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11443 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11444 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11445
11446 {
11447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11448 /* The multiple "Capture Source" controls confuse alsamixer
11449 * So call somewhat different..
11450 *FIXME: the controls appear in the "playback" view!
11451 */
11452 /* .name = "Capture Source", */
11453 .name = "Input Source",
11454 .count = 1,
11455 .info = alc861vd_mux_enum_info,
11456 .get = alc861vd_mux_enum_get,
11457 .put = alc861vd_mux_enum_put,
11458 },
11459 { } /* end */
11460};
11461
11462/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11463 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11464 */
11465static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11466 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11467 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11468
11469 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11470 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11471
11472 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11473 HDA_OUTPUT),
11474 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11475 HDA_OUTPUT),
11476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11478
11479 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11480 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11481
11482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11483
11484 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11487
11488 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11489 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11490 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11491
11492 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11493 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11494
11495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11497
11498 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11499 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11500
11501 { } /* end */
11502};
11503
11504static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11505 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11506 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11507
11508 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11509
11510 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11513
11514 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11516 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11517
11518 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11519 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11520
11521 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11522 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11523
11524 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11525 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11526
11527 { } /* end */
11528};
11529
bdd148a3
KY
11530static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11531 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11532 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11533 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11534
11535 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11536
11537 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11538 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11539 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11540
11541 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11542 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11543 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11544
11545 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11546 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11547
11548 { } /* end */
11549};
11550
272a527c
KY
11551/* Pin assignment: Front=0x14, HP = 0x15,
11552 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11553 */
11554static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11555 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11556 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11558 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11559 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11561 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11562 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11563 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11564 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
11565 { } /* end */
11566};
11567
d1a991a6
KY
11568/* Pin assignment: Speaker=0x14, Line-out = 0x15,
11569 * Front Mic=0x18, ATAPI Mic = 0x19,
11570 */
11571static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11572 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11573 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11575 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11576 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11577 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11578 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11579 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11580
11581 { } /* end */
11582};
11583
f32610ed
JS
11584/*
11585 * generic initialization of ADC, input mixers and output mixers
11586 */
11587static struct hda_verb alc861vd_volume_init_verbs[] = {
11588 /*
11589 * Unmute ADC0 and set the default input to mic-in
11590 */
11591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11593
11594 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11595 * the analog-loopback mixer widget
11596 */
11597 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
11603
11604 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
11605 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 11608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
11609
11610 /*
11611 * Set up output mixers (0x02 - 0x05)
11612 */
11613 /* set vol=0 to output mixers */
11614 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11615 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11616 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11617 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11618
11619 /* set up input amps for analog loopback */
11620 /* Amp Indices: DAC = 0, mixer = 1 */
11621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11623 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11624 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11625 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11626 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11627 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11628 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11629
11630 { }
11631};
11632
11633/*
11634 * 3-stack pin configuration:
11635 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11636 */
11637static struct hda_verb alc861vd_3stack_init_verbs[] = {
11638 /*
11639 * Set pin mode and muting
11640 */
11641 /* set front pin widgets 0x14 for output */
11642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11644 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11645
11646 /* Mic (rear) pin: input vref at 80% */
11647 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11648 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11649 /* Front Mic pin: input vref at 80% */
11650 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11652 /* Line In pin: input */
11653 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11654 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11655 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11657 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11658 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11659 /* CD pin widget for input */
11660 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11661
11662 { }
11663};
11664
11665/*
11666 * 6-stack pin configuration:
11667 */
11668static struct hda_verb alc861vd_6stack_init_verbs[] = {
11669 /*
11670 * Set pin mode and muting
11671 */
11672 /* set front pin widgets 0x14 for output */
11673 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11674 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11675 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11676
11677 /* Rear Pin: output 1 (0x0d) */
11678 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11681 /* CLFE Pin: output 2 (0x0e) */
11682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11684 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11685 /* Side Pin: output 3 (0x0f) */
11686 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11687 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11688 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11689
11690 /* Mic (rear) pin: input vref at 80% */
11691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11693 /* Front Mic pin: input vref at 80% */
11694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11696 /* Line In pin: input */
11697 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11699 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11700 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11701 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11702 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11703 /* CD pin widget for input */
11704 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11705
11706 { }
11707};
11708
bdd148a3
KY
11709static struct hda_verb alc861vd_eapd_verbs[] = {
11710 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11711 { }
11712};
11713
11714static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11718 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11719 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11720 {}
11721};
11722
11723/* toggle speaker-output according to the hp-jack state */
11724static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11725{
11726 unsigned int present;
11727 unsigned char bits;
11728
11729 present = snd_hda_codec_read(codec, 0x1b, 0,
11730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11731 bits = present ? HDA_AMP_MUTE : 0;
11732 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11733 HDA_AMP_MUTE, bits);
bdd148a3
KY
11734}
11735
11736static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11737{
11738 unsigned int present;
11739 unsigned char bits;
11740
11741 present = snd_hda_codec_read(codec, 0x18, 0,
11742 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11743 bits = present ? HDA_AMP_MUTE : 0;
11744 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11745 HDA_AMP_MUTE, bits);
bdd148a3
KY
11746}
11747
11748static void alc861vd_lenovo_automute(struct hda_codec *codec)
11749{
11750 alc861vd_lenovo_hp_automute(codec);
11751 alc861vd_lenovo_mic_automute(codec);
11752}
11753
11754static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11755 unsigned int res)
11756{
11757 switch (res >> 26) {
11758 case ALC880_HP_EVENT:
11759 alc861vd_lenovo_hp_automute(codec);
11760 break;
11761 case ALC880_MIC_EVENT:
11762 alc861vd_lenovo_mic_automute(codec);
11763 break;
11764 }
11765}
11766
272a527c
KY
11767static struct hda_verb alc861vd_dallas_verbs[] = {
11768 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11769 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11770 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11771 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11772
11773 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11775 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11779 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11780 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11781
11782 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11784 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11786 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11787 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11788 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11789 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11790
11791 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11792 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11794 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11796 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11798 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11799
11800 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11803 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11804
11805 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11806 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11807 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11808
11809 { } /* end */
11810};
11811
11812/* toggle speaker-output according to the hp-jack state */
11813static void alc861vd_dallas_automute(struct hda_codec *codec)
11814{
11815 unsigned int present;
11816
11817 present = snd_hda_codec_read(codec, 0x15, 0,
11818 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11819 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11820 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
11821}
11822
11823static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11824{
11825 if ((res >> 26) == ALC880_HP_EVENT)
11826 alc861vd_dallas_automute(codec);
11827}
11828
cb53c626
TI
11829#ifdef CONFIG_SND_HDA_POWER_SAVE
11830#define alc861vd_loopbacks alc880_loopbacks
11831#endif
11832
f32610ed
JS
11833/* pcm configuration: identiacal with ALC880 */
11834#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
11835#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
11836#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
11837#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
11838
11839/*
11840 * configuration and preset
11841 */
11842static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11843 [ALC660VD_3ST] = "3stack-660",
983f8ae4 11844 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
11845 [ALC861VD_3ST] = "3stack",
11846 [ALC861VD_3ST_DIG] = "3stack-digout",
11847 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 11848 [ALC861VD_LENOVO] = "lenovo",
272a527c 11849 [ALC861VD_DALLAS] = "dallas",
983f8ae4 11850 [ALC861VD_HP] = "hp",
f32610ed
JS
11851 [ALC861VD_AUTO] = "auto",
11852};
11853
11854static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
11855 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11856 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 11857 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 11858 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 11859 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 11860 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 11861 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 11862 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 11863 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 11864 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
39c5d41f 11865 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
11866 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11867 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 11868 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
11869 {}
11870};
11871
11872static struct alc_config_preset alc861vd_presets[] = {
11873 [ALC660VD_3ST] = {
11874 .mixers = { alc861vd_3st_mixer },
11875 .init_verbs = { alc861vd_volume_init_verbs,
11876 alc861vd_3stack_init_verbs },
11877 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11878 .dac_nids = alc660vd_dac_nids,
11879 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11880 .adc_nids = alc861vd_adc_nids,
11881 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11882 .channel_mode = alc861vd_3stack_2ch_modes,
11883 .input_mux = &alc861vd_capture_source,
11884 },
6963f84c
MC
11885 [ALC660VD_3ST_DIG] = {
11886 .mixers = { alc861vd_3st_mixer },
11887 .init_verbs = { alc861vd_volume_init_verbs,
11888 alc861vd_3stack_init_verbs },
11889 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11890 .dac_nids = alc660vd_dac_nids,
11891 .dig_out_nid = ALC861VD_DIGOUT_NID,
11892 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11893 .adc_nids = alc861vd_adc_nids,
11894 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11895 .channel_mode = alc861vd_3stack_2ch_modes,
11896 .input_mux = &alc861vd_capture_source,
11897 },
f32610ed
JS
11898 [ALC861VD_3ST] = {
11899 .mixers = { alc861vd_3st_mixer },
11900 .init_verbs = { alc861vd_volume_init_verbs,
11901 alc861vd_3stack_init_verbs },
11902 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11903 .dac_nids = alc861vd_dac_nids,
11904 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11905 .channel_mode = alc861vd_3stack_2ch_modes,
11906 .input_mux = &alc861vd_capture_source,
11907 },
11908 [ALC861VD_3ST_DIG] = {
11909 .mixers = { alc861vd_3st_mixer },
11910 .init_verbs = { alc861vd_volume_init_verbs,
11911 alc861vd_3stack_init_verbs },
11912 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11913 .dac_nids = alc861vd_dac_nids,
11914 .dig_out_nid = ALC861VD_DIGOUT_NID,
11915 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11916 .channel_mode = alc861vd_3stack_2ch_modes,
11917 .input_mux = &alc861vd_capture_source,
11918 },
11919 [ALC861VD_6ST_DIG] = {
11920 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11921 .init_verbs = { alc861vd_volume_init_verbs,
11922 alc861vd_6stack_init_verbs },
11923 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11924 .dac_nids = alc861vd_dac_nids,
11925 .dig_out_nid = ALC861VD_DIGOUT_NID,
11926 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11927 .channel_mode = alc861vd_6stack_modes,
11928 .input_mux = &alc861vd_capture_source,
11929 },
bdd148a3
KY
11930 [ALC861VD_LENOVO] = {
11931 .mixers = { alc861vd_lenovo_mixer },
11932 .init_verbs = { alc861vd_volume_init_verbs,
11933 alc861vd_3stack_init_verbs,
11934 alc861vd_eapd_verbs,
11935 alc861vd_lenovo_unsol_verbs },
11936 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11937 .dac_nids = alc660vd_dac_nids,
11938 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11939 .adc_nids = alc861vd_adc_nids,
11940 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11941 .channel_mode = alc861vd_3stack_2ch_modes,
11942 .input_mux = &alc861vd_capture_source,
11943 .unsol_event = alc861vd_lenovo_unsol_event,
11944 .init_hook = alc861vd_lenovo_automute,
11945 },
272a527c
KY
11946 [ALC861VD_DALLAS] = {
11947 .mixers = { alc861vd_dallas_mixer },
11948 .init_verbs = { alc861vd_dallas_verbs },
11949 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11950 .dac_nids = alc861vd_dac_nids,
11951 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11952 .adc_nids = alc861vd_adc_nids,
11953 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11954 .channel_mode = alc861vd_3stack_2ch_modes,
11955 .input_mux = &alc861vd_dallas_capture_source,
11956 .unsol_event = alc861vd_dallas_unsol_event,
11957 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
11958 },
11959 [ALC861VD_HP] = {
11960 .mixers = { alc861vd_hp_mixer },
11961 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11962 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11963 .dac_nids = alc861vd_dac_nids,
11964 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11965 .dig_out_nid = ALC861VD_DIGOUT_NID,
11966 .adc_nids = alc861vd_adc_nids,
11967 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11968 .channel_mode = alc861vd_3stack_2ch_modes,
11969 .input_mux = &alc861vd_hp_capture_source,
11970 .unsol_event = alc861vd_dallas_unsol_event,
11971 .init_hook = alc861vd_dallas_automute,
11972 },
f32610ed
JS
11973};
11974
11975/*
11976 * BIOS auto configuration
11977 */
11978static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11979 hda_nid_t nid, int pin_type, int dac_idx)
11980{
11981 /* set as output */
11982 snd_hda_codec_write(codec, nid, 0,
11983 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11984 snd_hda_codec_write(codec, nid, 0,
11985 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11986}
11987
11988static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11989{
11990 struct alc_spec *spec = codec->spec;
11991 int i;
11992
bc9f98a9 11993 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
11994 for (i = 0; i <= HDA_SIDE; i++) {
11995 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11996 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
11997 if (nid)
11998 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 11999 pin_type, i);
f32610ed
JS
12000 }
12001}
12002
12003
12004static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12005{
12006 struct alc_spec *spec = codec->spec;
12007 hda_nid_t pin;
12008
12009 pin = spec->autocfg.hp_pins[0];
12010 if (pin) /* connect to front and use dac 0 */
12011 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12012}
12013
12014#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12015#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12016
12017static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12018{
12019 struct alc_spec *spec = codec->spec;
12020 int i;
12021
12022 for (i = 0; i < AUTO_PIN_LAST; i++) {
12023 hda_nid_t nid = spec->autocfg.input_pins[i];
12024 if (alc861vd_is_input_pin(nid)) {
12025 snd_hda_codec_write(codec, nid, 0,
12026 AC_VERB_SET_PIN_WIDGET_CONTROL,
12027 i <= AUTO_PIN_FRONT_MIC ?
12028 PIN_VREF80 : PIN_IN);
12029 if (nid != ALC861VD_PIN_CD_NID)
12030 snd_hda_codec_write(codec, nid, 0,
12031 AC_VERB_SET_AMP_GAIN_MUTE,
12032 AMP_OUT_MUTE);
12033 }
12034 }
12035}
12036
12037#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12038#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12039
12040/* add playback controls from the parsed DAC table */
12041/* Based on ALC880 version. But ALC861VD has separate,
12042 * different NIDs for mute/unmute switch and volume control */
12043static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12044 const struct auto_pin_cfg *cfg)
12045{
12046 char name[32];
12047 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12048 hda_nid_t nid_v, nid_s;
12049 int i, err;
12050
12051 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 12052 if (!spec->multiout.dac_nids[i])
f32610ed
JS
12053 continue;
12054 nid_v = alc861vd_idx_to_mixer_vol(
12055 alc880_dac_to_idx(
12056 spec->multiout.dac_nids[i]));
12057 nid_s = alc861vd_idx_to_mixer_switch(
12058 alc880_dac_to_idx(
12059 spec->multiout.dac_nids[i]));
12060
12061 if (i == 2) {
12062 /* Center/LFE */
f12ab1e0
TI
12063 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12064 "Center Playback Volume",
12065 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12066 HDA_OUTPUT));
12067 if (err < 0)
f32610ed 12068 return err;
f12ab1e0
TI
12069 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12070 "LFE Playback Volume",
12071 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12072 HDA_OUTPUT));
12073 if (err < 0)
f32610ed 12074 return err;
f12ab1e0
TI
12075 err = add_control(spec, ALC_CTL_BIND_MUTE,
12076 "Center Playback Switch",
12077 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12078 HDA_INPUT));
12079 if (err < 0)
f32610ed 12080 return err;
f12ab1e0
TI
12081 err = add_control(spec, ALC_CTL_BIND_MUTE,
12082 "LFE Playback Switch",
12083 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12084 HDA_INPUT));
12085 if (err < 0)
f32610ed
JS
12086 return err;
12087 } else {
12088 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
12089 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12090 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12091 HDA_OUTPUT));
12092 if (err < 0)
f32610ed
JS
12093 return err;
12094 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 12095 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 12096 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
12097 HDA_INPUT));
12098 if (err < 0)
f32610ed
JS
12099 return err;
12100 }
12101 }
12102 return 0;
12103}
12104
12105/* add playback controls for speaker and HP outputs */
12106/* Based on ALC880 version. But ALC861VD has separate,
12107 * different NIDs for mute/unmute switch and volume control */
12108static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12109 hda_nid_t pin, const char *pfx)
12110{
12111 hda_nid_t nid_v, nid_s;
12112 int err;
12113 char name[32];
12114
f12ab1e0 12115 if (!pin)
f32610ed
JS
12116 return 0;
12117
12118 if (alc880_is_fixed_pin(pin)) {
12119 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12120 /* specify the DAC as the extra output */
f12ab1e0 12121 if (!spec->multiout.hp_nid)
f32610ed
JS
12122 spec->multiout.hp_nid = nid_v;
12123 else
12124 spec->multiout.extra_out_nid[0] = nid_v;
12125 /* control HP volume/switch on the output mixer amp */
12126 nid_v = alc861vd_idx_to_mixer_vol(
12127 alc880_fixed_pin_idx(pin));
12128 nid_s = alc861vd_idx_to_mixer_switch(
12129 alc880_fixed_pin_idx(pin));
12130
12131 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
12132 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12133 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12134 if (err < 0)
f32610ed
JS
12135 return err;
12136 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12137 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12138 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12139 if (err < 0)
f32610ed
JS
12140 return err;
12141 } else if (alc880_is_multi_pin(pin)) {
12142 /* set manual connection */
12143 /* we have only a switch on HP-out PIN */
12144 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12145 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12146 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12147 if (err < 0)
f32610ed
JS
12148 return err;
12149 }
12150 return 0;
12151}
12152
12153/* parse the BIOS configuration and set up the alc_spec
12154 * return 1 if successful, 0 if the proper config is not found,
12155 * or a negative error code
12156 * Based on ALC880 version - had to change it to override
12157 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12158static int alc861vd_parse_auto_config(struct hda_codec *codec)
12159{
12160 struct alc_spec *spec = codec->spec;
12161 int err;
12162 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12163
f12ab1e0
TI
12164 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12165 alc861vd_ignore);
12166 if (err < 0)
f32610ed 12167 return err;
f12ab1e0 12168 if (!spec->autocfg.line_outs)
f32610ed
JS
12169 return 0; /* can't find valid BIOS pin config */
12170
f12ab1e0
TI
12171 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12172 if (err < 0)
12173 return err;
12174 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12175 if (err < 0)
12176 return err;
12177 err = alc861vd_auto_create_extra_out(spec,
12178 spec->autocfg.speaker_pins[0],
12179 "Speaker");
12180 if (err < 0)
12181 return err;
12182 err = alc861vd_auto_create_extra_out(spec,
12183 spec->autocfg.hp_pins[0],
12184 "Headphone");
12185 if (err < 0)
12186 return err;
12187 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12188 if (err < 0)
f32610ed
JS
12189 return err;
12190
12191 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12192
12193 if (spec->autocfg.dig_out_pin)
12194 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12195
12196 if (spec->kctl_alloc)
12197 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12198
12199 spec->init_verbs[spec->num_init_verbs++]
12200 = alc861vd_volume_init_verbs;
12201
12202 spec->num_mux_defs = 1;
12203 spec->input_mux = &spec->private_imux;
12204
776e184e
TI
12205 err = alc_auto_add_mic_boost(codec);
12206 if (err < 0)
12207 return err;
12208
f32610ed
JS
12209 return 1;
12210}
12211
12212/* additional initialization for auto-configuration model */
12213static void alc861vd_auto_init(struct hda_codec *codec)
12214{
12215 alc861vd_auto_init_multi_out(codec);
12216 alc861vd_auto_init_hp_out(codec);
12217 alc861vd_auto_init_analog_input(codec);
12218}
12219
12220static int patch_alc861vd(struct hda_codec *codec)
12221{
12222 struct alc_spec *spec;
12223 int err, board_config;
12224
12225 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12226 if (spec == NULL)
12227 return -ENOMEM;
12228
12229 codec->spec = spec;
12230
12231 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12232 alc861vd_models,
12233 alc861vd_cfg_tbl);
12234
12235 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12236 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12237 "ALC861VD, trying auto-probe from BIOS...\n");
12238 board_config = ALC861VD_AUTO;
12239 }
12240
12241 if (board_config == ALC861VD_AUTO) {
12242 /* automatic parse from the BIOS config */
12243 err = alc861vd_parse_auto_config(codec);
12244 if (err < 0) {
12245 alc_free(codec);
12246 return err;
f12ab1e0 12247 } else if (!err) {
f32610ed
JS
12248 printk(KERN_INFO
12249 "hda_codec: Cannot set up configuration "
12250 "from BIOS. Using base mode...\n");
12251 board_config = ALC861VD_3ST;
12252 }
12253 }
12254
12255 if (board_config != ALC861VD_AUTO)
12256 setup_preset(spec, &alc861vd_presets[board_config]);
12257
12258 spec->stream_name_analog = "ALC861VD Analog";
12259 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12260 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12261
12262 spec->stream_name_digital = "ALC861VD Digital";
12263 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12264 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12265
12266 spec->adc_nids = alc861vd_adc_nids;
12267 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12268
12269 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12270 spec->num_mixers++;
12271
12272 codec->patch_ops = alc_patch_ops;
12273
12274 if (board_config == ALC861VD_AUTO)
12275 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
12276#ifdef CONFIG_SND_HDA_POWER_SAVE
12277 if (!spec->loopback.amplist)
12278 spec->loopback.amplist = alc861vd_loopbacks;
12279#endif
f32610ed
JS
12280
12281 return 0;
12282}
12283
bc9f98a9
KY
12284/*
12285 * ALC662 support
12286 *
12287 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12288 * configuration. Each pin widget can choose any input DACs and a mixer.
12289 * Each ADC is connected from a mixer of all inputs. This makes possible
12290 * 6-channel independent captures.
12291 *
12292 * In addition, an independent DAC for the multi-playback (not used in this
12293 * driver yet).
12294 */
12295#define ALC662_DIGOUT_NID 0x06
12296#define ALC662_DIGIN_NID 0x0a
12297
12298static hda_nid_t alc662_dac_nids[4] = {
12299 /* front, rear, clfe, rear_surr */
12300 0x02, 0x03, 0x04
12301};
12302
12303static hda_nid_t alc662_adc_nids[1] = {
12304 /* ADC1-2 */
12305 0x09,
12306};
12307/* input MUX */
12308/* FIXME: should be a matrix-type input source selection */
12309
12310static struct hda_input_mux alc662_capture_source = {
12311 .num_items = 4,
12312 .items = {
12313 { "Mic", 0x0 },
12314 { "Front Mic", 0x1 },
12315 { "Line", 0x2 },
12316 { "CD", 0x4 },
12317 },
12318};
12319
12320static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12321 .num_items = 2,
12322 .items = {
12323 { "Mic", 0x1 },
12324 { "Line", 0x2 },
12325 },
12326};
291702f0
KY
12327
12328static struct hda_input_mux alc662_eeepc_capture_source = {
12329 .num_items = 2,
12330 .items = {
12331 { "i-Mic", 0x1 },
12332 { "e-Mic", 0x0 },
12333 },
12334};
12335
bc9f98a9
KY
12336#define alc662_mux_enum_info alc_mux_enum_info
12337#define alc662_mux_enum_get alc_mux_enum_get
12338
12339static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12340 struct snd_ctl_elem_value *ucontrol)
12341{
12342 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12343 struct alc_spec *spec = codec->spec;
12344 const struct hda_input_mux *imux = spec->input_mux;
12345 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
d1a991a6 12346 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
bc9f98a9
KY
12347 hda_nid_t nid = capture_mixers[adc_idx];
12348 unsigned int *cur_val = &spec->cur_mux[adc_idx];
12349 unsigned int i, idx;
12350
12351 idx = ucontrol->value.enumerated.item[0];
12352 if (idx >= imux->num_items)
12353 idx = imux->num_items - 1;
82beb8fd 12354 if (*cur_val == idx)
bc9f98a9
KY
12355 return 0;
12356 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
12357 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12358 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12359 imux->items[i].index,
12360 HDA_AMP_MUTE, v);
bc9f98a9
KY
12361 }
12362 *cur_val = idx;
12363 return 1;
12364}
12365/*
12366 * 2ch mode
12367 */
12368static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12369 { 2, NULL }
12370};
12371
12372/*
12373 * 2ch mode
12374 */
12375static struct hda_verb alc662_3ST_ch2_init[] = {
12376 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12377 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12378 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12379 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12380 { } /* end */
12381};
12382
12383/*
12384 * 6ch mode
12385 */
12386static struct hda_verb alc662_3ST_ch6_init[] = {
12387 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12388 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12389 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12390 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12391 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12392 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12393 { } /* end */
12394};
12395
12396static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12397 { 2, alc662_3ST_ch2_init },
12398 { 6, alc662_3ST_ch6_init },
12399};
12400
12401/*
12402 * 2ch mode
12403 */
12404static struct hda_verb alc662_sixstack_ch6_init[] = {
12405 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12406 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12407 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12408 { } /* end */
12409};
12410
12411/*
12412 * 6ch mode
12413 */
12414static struct hda_verb alc662_sixstack_ch8_init[] = {
12415 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12416 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12417 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12418 { } /* end */
12419};
12420
12421static struct hda_channel_mode alc662_5stack_modes[2] = {
12422 { 2, alc662_sixstack_ch6_init },
12423 { 6, alc662_sixstack_ch8_init },
12424};
12425
12426/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12427 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12428 */
12429
12430static struct snd_kcontrol_new alc662_base_mixer[] = {
12431 /* output mixer control */
12432 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12433 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12434 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12435 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12437 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12438 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12439 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12441
12442 /*Input mixer control */
12443 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12444 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12445 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12446 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12447 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12448 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
12451 { } /* end */
12452};
12453
12454static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12455 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12456 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12458 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12459 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, 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 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12467 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12468 { } /* end */
12469};
12470
12471static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12472 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12473 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12474 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12475 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12476 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12477 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12478 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12479 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12481 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12482 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12487 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12488 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12489 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12490 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12491 { } /* end */
12492};
12493
12494static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12495 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12496 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12497 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12498 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12499 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12500 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12501 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12503 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
12504 { } /* end */
12505};
12506
291702f0
KY
12507static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12508 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12509
12510 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12511 HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12512
12513 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12514 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12515 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12516
12517 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12518 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12519 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12520 { } /* end */
12521};
12522
bc9f98a9
KY
12523static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12524 {
12525 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12526 .name = "Channel Mode",
12527 .info = alc_ch_mode_info,
12528 .get = alc_ch_mode_get,
12529 .put = alc_ch_mode_put,
12530 },
12531 { } /* end */
12532};
12533
12534static struct hda_verb alc662_init_verbs[] = {
12535 /* ADC: mute amp left and right */
12536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12537 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12538 /* Front mixer: unmute input/output amp left and right (volume = 0) */
12539
cb53c626
TI
12540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 12545
b60dd394
KY
12546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
12552
12553 /* Front Pin: output 0 (0x0c) */
12554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12555 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12556
12557 /* Rear Pin: output 1 (0x0d) */
12558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12560
12561 /* CLFE Pin: output 2 (0x0e) */
12562 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12564
12565 /* Mic (rear) pin: input vref at 80% */
12566 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12568 /* Front Mic pin: input vref at 80% */
12569 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12570 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12571 /* Line In pin: input */
12572 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12573 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12574 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12576 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12577 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12578 /* CD pin widget for input */
12579 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12580
12581 /* FIXME: use matrix-type input source selection */
12582 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12583 /* Input mixer */
12584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
12588
12589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
bc9f98a9
KY
12593 { }
12594};
12595
12596static struct hda_verb alc662_sue_init_verbs[] = {
12597 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12598 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
12599 {}
12600};
12601
12602static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12603 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12604 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12605 {}
bc9f98a9
KY
12606};
12607
12608/*
12609 * generic initialization of ADC, input mixers and output mixers
12610 */
12611static struct hda_verb alc662_auto_init_verbs[] = {
12612 /*
12613 * Unmute ADC and set the default input to mic-in
12614 */
12615 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12616 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12617
12618 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12619 * mixer widget
12620 * Note: PASD motherboards uses the Line In 2 as the input for front
12621 * panel mic (mic 2)
12622 */
12623 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
12629
12630 /*
12631 * Set up output mixers (0x0c - 0x0f)
12632 */
12633 /* set vol=0 to output mixers */
12634 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12635 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12636 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12637
12638 /* set up input amps for analog loopback */
12639 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
12640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
12646
12647
12648 /* FIXME: use matrix-type input source selection */
12649 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12650 /* Input mixer */
12651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 12652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
12653 { }
12654};
12655
12656/* capture mixer elements */
12657static struct snd_kcontrol_new alc662_capture_mixer[] = {
12658 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12659 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12660 {
12661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12662 /* The multiple "Capture Source" controls confuse alsamixer
12663 * So call somewhat different..
12664 * FIXME: the controls appear in the "playback" view!
12665 */
12666 /* .name = "Capture Source", */
12667 .name = "Input Source",
12668 .count = 1,
6e7939bb
HRK
12669 .info = alc662_mux_enum_info,
12670 .get = alc662_mux_enum_get,
12671 .put = alc662_mux_enum_put,
bc9f98a9
KY
12672 },
12673 { } /* end */
12674};
12675
12676static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12677{
12678 unsigned int present;
f12ab1e0 12679 unsigned char bits;
bc9f98a9
KY
12680
12681 present = snd_hda_codec_read(codec, 0x14, 0,
12682 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12683 bits = present ? HDA_AMP_MUTE : 0;
12684 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12685 HDA_AMP_MUTE, bits);
bc9f98a9
KY
12686}
12687
12688static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12689{
12690 unsigned int present;
f12ab1e0 12691 unsigned char bits;
bc9f98a9
KY
12692
12693 present = snd_hda_codec_read(codec, 0x1b, 0,
12694 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12695 bits = present ? HDA_AMP_MUTE : 0;
12696 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12697 HDA_AMP_MUTE, bits);
12698 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12699 HDA_AMP_MUTE, bits);
bc9f98a9
KY
12700}
12701
12702static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12703 unsigned int res)
12704{
12705 if ((res >> 26) == ALC880_HP_EVENT)
12706 alc662_lenovo_101e_all_automute(codec);
12707 if ((res >> 26) == ALC880_FRONT_EVENT)
12708 alc662_lenovo_101e_ispeaker_automute(codec);
12709}
12710
291702f0
KY
12711static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12712{
12713 unsigned int present;
12714
12715 present = snd_hda_codec_read(codec, 0x18, 0,
12716 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12717 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12718 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12719 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12720 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12721 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12722 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12723 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12724 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12725}
12726
12727/* unsolicited event for HP jack sensing */
12728static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12729 unsigned int res)
12730{
12731 if ((res >> 26) == ALC880_HP_EVENT)
12732 alc262_hippo1_automute( codec );
12733
12734 if ((res >> 26) == ALC880_MIC_EVENT)
12735 alc662_eeepc_mic_automute(codec);
12736}
12737
12738static void alc662_eeepc_inithook(struct hda_codec *codec)
12739{
12740 alc262_hippo1_automute( codec );
12741 alc662_eeepc_mic_automute(codec);
12742}
12743
cb53c626
TI
12744#ifdef CONFIG_SND_HDA_POWER_SAVE
12745#define alc662_loopbacks alc880_loopbacks
12746#endif
12747
bc9f98a9
KY
12748
12749/* pcm configuration: identiacal with ALC880 */
12750#define alc662_pcm_analog_playback alc880_pcm_analog_playback
12751#define alc662_pcm_analog_capture alc880_pcm_analog_capture
12752#define alc662_pcm_digital_playback alc880_pcm_digital_playback
12753#define alc662_pcm_digital_capture alc880_pcm_digital_capture
12754
12755/*
12756 * configuration and preset
12757 */
12758static const char *alc662_models[ALC662_MODEL_LAST] = {
12759 [ALC662_3ST_2ch_DIG] = "3stack-dig",
12760 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
12761 [ALC662_3ST_6ch] = "3stack-6ch",
12762 [ALC662_5ST_DIG] = "6stack-dig",
12763 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 12764 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
bc9f98a9
KY
12765 [ALC662_AUTO] = "auto",
12766};
12767
12768static struct snd_pci_quirk alc662_cfg_tbl[] = {
291702f0 12769 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
ac3e3741 12770 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
bc9f98a9
KY
12771 {}
12772};
12773
12774static struct alc_config_preset alc662_presets[] = {
12775 [ALC662_3ST_2ch_DIG] = {
291702f0 12776 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
12777 .init_verbs = { alc662_init_verbs },
12778 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12779 .dac_nids = alc662_dac_nids,
12780 .dig_out_nid = ALC662_DIGOUT_NID,
12781 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12782 .adc_nids = alc662_adc_nids,
12783 .dig_in_nid = ALC662_DIGIN_NID,
12784 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12785 .channel_mode = alc662_3ST_2ch_modes,
12786 .input_mux = &alc662_capture_source,
12787 },
12788 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
12789 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12790 alc662_capture_mixer },
bc9f98a9
KY
12791 .init_verbs = { alc662_init_verbs },
12792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12793 .dac_nids = alc662_dac_nids,
12794 .dig_out_nid = ALC662_DIGOUT_NID,
12795 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12796 .adc_nids = alc662_adc_nids,
12797 .dig_in_nid = ALC662_DIGIN_NID,
12798 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12799 .channel_mode = alc662_3ST_6ch_modes,
12800 .need_dac_fix = 1,
12801 .input_mux = &alc662_capture_source,
f12ab1e0 12802 },
bc9f98a9 12803 [ALC662_3ST_6ch] = {
291702f0
KY
12804 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12805 alc662_capture_mixer },
bc9f98a9
KY
12806 .init_verbs = { alc662_init_verbs },
12807 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12808 .dac_nids = alc662_dac_nids,
12809 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12810 .adc_nids = alc662_adc_nids,
12811 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12812 .channel_mode = alc662_3ST_6ch_modes,
12813 .need_dac_fix = 1,
12814 .input_mux = &alc662_capture_source,
f12ab1e0 12815 },
bc9f98a9 12816 [ALC662_5ST_DIG] = {
291702f0
KY
12817 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12818 alc662_capture_mixer },
bc9f98a9
KY
12819 .init_verbs = { alc662_init_verbs },
12820 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12821 .dac_nids = alc662_dac_nids,
12822 .dig_out_nid = ALC662_DIGOUT_NID,
12823 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12824 .adc_nids = alc662_adc_nids,
12825 .dig_in_nid = ALC662_DIGIN_NID,
12826 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12827 .channel_mode = alc662_5stack_modes,
12828 .input_mux = &alc662_capture_source,
12829 },
12830 [ALC662_LENOVO_101E] = {
291702f0 12831 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
12832 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12834 .dac_nids = alc662_dac_nids,
12835 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12836 .adc_nids = alc662_adc_nids,
12837 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12838 .channel_mode = alc662_3ST_2ch_modes,
12839 .input_mux = &alc662_lenovo_101e_capture_source,
12840 .unsol_event = alc662_lenovo_101e_unsol_event,
12841 .init_hook = alc662_lenovo_101e_all_automute,
12842 },
291702f0
KY
12843 [ALC662_ASUS_EEEPC_P701] = {
12844 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12845 .init_verbs = { alc662_init_verbs,
12846 alc662_eeepc_sue_init_verbs },
12847 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12848 .dac_nids = alc662_dac_nids,
12849 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12850 .adc_nids = alc662_adc_nids,
12851 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12852 .channel_mode = alc662_3ST_2ch_modes,
12853 .input_mux = &alc662_eeepc_capture_source,
12854 .unsol_event = alc662_eeepc_unsol_event,
12855 .init_hook = alc662_eeepc_inithook,
12856 },
bc9f98a9
KY
12857
12858};
12859
12860
12861/*
12862 * BIOS auto configuration
12863 */
12864
12865/* add playback controls from the parsed DAC table */
12866static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12867 const struct auto_pin_cfg *cfg)
12868{
12869 char name[32];
12870 static const char *chname[4] = {
12871 "Front", "Surround", NULL /*CLFE*/, "Side"
12872 };
12873 hda_nid_t nid;
12874 int i, err;
12875
12876 for (i = 0; i < cfg->line_outs; i++) {
12877 if (!spec->multiout.dac_nids[i])
12878 continue;
b60dd394 12879 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
12880 if (i == 2) {
12881 /* Center/LFE */
12882 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12883 "Center Playback Volume",
f12ab1e0
TI
12884 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12885 HDA_OUTPUT));
bc9f98a9
KY
12886 if (err < 0)
12887 return err;
12888 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12889 "LFE Playback Volume",
f12ab1e0
TI
12890 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12891 HDA_OUTPUT));
bc9f98a9
KY
12892 if (err < 0)
12893 return err;
12894 err = add_control(spec, ALC_CTL_BIND_MUTE,
12895 "Center Playback Switch",
f12ab1e0
TI
12896 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12897 HDA_INPUT));
bc9f98a9
KY
12898 if (err < 0)
12899 return err;
12900 err = add_control(spec, ALC_CTL_BIND_MUTE,
12901 "LFE Playback Switch",
f12ab1e0
TI
12902 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12903 HDA_INPUT));
bc9f98a9
KY
12904 if (err < 0)
12905 return err;
12906 } else {
12907 sprintf(name, "%s Playback Volume", chname[i]);
12908 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
12909 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12910 HDA_OUTPUT));
bc9f98a9
KY
12911 if (err < 0)
12912 return err;
12913 sprintf(name, "%s Playback Switch", chname[i]);
12914 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
12915 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12916 HDA_INPUT));
bc9f98a9
KY
12917 if (err < 0)
12918 return err;
12919 }
12920 }
12921 return 0;
12922}
12923
12924/* add playback controls for speaker and HP outputs */
12925static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12926 const char *pfx)
12927{
12928 hda_nid_t nid;
12929 int err;
12930 char name[32];
12931
12932 if (!pin)
12933 return 0;
12934
12935 if (alc880_is_fixed_pin(pin)) {
12936 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12937 /* printk("DAC nid=%x\n",nid); */
12938 /* specify the DAC as the extra output */
12939 if (!spec->multiout.hp_nid)
12940 spec->multiout.hp_nid = nid;
12941 else
12942 spec->multiout.extra_out_nid[0] = nid;
12943 /* control HP volume/switch on the output mixer amp */
12944 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12945 sprintf(name, "%s Playback Volume", pfx);
12946 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12948 if (err < 0)
12949 return err;
12950 sprintf(name, "%s Playback Switch", pfx);
12951 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12952 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12953 if (err < 0)
12954 return err;
12955 } else if (alc880_is_multi_pin(pin)) {
12956 /* set manual connection */
12957 /* we have only a switch on HP-out PIN */
12958 sprintf(name, "%s Playback Switch", pfx);
12959 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12960 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12961 if (err < 0)
12962 return err;
12963 }
12964 return 0;
12965}
12966
12967/* create playback/capture controls for input pins */
12968static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12969 const struct auto_pin_cfg *cfg)
12970{
12971 struct hda_input_mux *imux = &spec->private_imux;
12972 int i, err, idx;
12973
12974 for (i = 0; i < AUTO_PIN_LAST; i++) {
12975 if (alc880_is_input_pin(cfg->input_pins[i])) {
12976 idx = alc880_input_pin_idx(cfg->input_pins[i]);
12977 err = new_analog_input(spec, cfg->input_pins[i],
12978 auto_pin_cfg_labels[i],
12979 idx, 0x0b);
12980 if (err < 0)
12981 return err;
12982 imux->items[imux->num_items].label =
12983 auto_pin_cfg_labels[i];
12984 imux->items[imux->num_items].index =
12985 alc880_input_pin_idx(cfg->input_pins[i]);
12986 imux->num_items++;
12987 }
12988 }
12989 return 0;
12990}
12991
12992static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12993 hda_nid_t nid, int pin_type,
12994 int dac_idx)
12995{
12996 /* set as output */
12997 snd_hda_codec_write(codec, nid, 0,
12998 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12999 snd_hda_codec_write(codec, nid, 0,
13000 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
13001 /* need the manual connection? */
13002 if (alc880_is_multi_pin(nid)) {
13003 struct alc_spec *spec = codec->spec;
13004 int idx = alc880_multi_pin_idx(nid);
13005 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13006 AC_VERB_SET_CONNECT_SEL,
13007 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13008 }
13009}
13010
13011static void alc662_auto_init_multi_out(struct hda_codec *codec)
13012{
13013 struct alc_spec *spec = codec->spec;
13014 int i;
13015
13016 for (i = 0; i <= HDA_SIDE; i++) {
13017 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13018 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 13019 if (nid)
baba8ee9 13020 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
13021 i);
13022 }
13023}
13024
13025static void alc662_auto_init_hp_out(struct hda_codec *codec)
13026{
13027 struct alc_spec *spec = codec->spec;
13028 hda_nid_t pin;
13029
13030 pin = spec->autocfg.hp_pins[0];
13031 if (pin) /* connect to front */
13032 /* use dac 0 */
13033 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13034}
13035
13036#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13037#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13038
13039static void alc662_auto_init_analog_input(struct hda_codec *codec)
13040{
13041 struct alc_spec *spec = codec->spec;
13042 int i;
13043
13044 for (i = 0; i < AUTO_PIN_LAST; i++) {
13045 hda_nid_t nid = spec->autocfg.input_pins[i];
13046 if (alc662_is_input_pin(nid)) {
13047 snd_hda_codec_write(codec, nid, 0,
13048 AC_VERB_SET_PIN_WIDGET_CONTROL,
13049 (i <= AUTO_PIN_FRONT_MIC ?
13050 PIN_VREF80 : PIN_IN));
13051 if (nid != ALC662_PIN_CD_NID)
13052 snd_hda_codec_write(codec, nid, 0,
13053 AC_VERB_SET_AMP_GAIN_MUTE,
13054 AMP_OUT_MUTE);
13055 }
13056 }
13057}
13058
13059static int alc662_parse_auto_config(struct hda_codec *codec)
13060{
13061 struct alc_spec *spec = codec->spec;
13062 int err;
13063 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13064
13065 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13066 alc662_ignore);
13067 if (err < 0)
13068 return err;
13069 if (!spec->autocfg.line_outs)
13070 return 0; /* can't find valid BIOS pin config */
13071
f12ab1e0
TI
13072 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13073 if (err < 0)
13074 return err;
13075 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13076 if (err < 0)
13077 return err;
13078 err = alc662_auto_create_extra_out(spec,
13079 spec->autocfg.speaker_pins[0],
13080 "Speaker");
13081 if (err < 0)
13082 return err;
13083 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13084 "Headphone");
13085 if (err < 0)
13086 return err;
13087 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13088 if (err < 0)
bc9f98a9
KY
13089 return err;
13090
13091 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13092
13093 if (spec->autocfg.dig_out_pin)
13094 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13095
13096 if (spec->kctl_alloc)
13097 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13098
13099 spec->num_mux_defs = 1;
13100 spec->input_mux = &spec->private_imux;
13101
8c87286f 13102 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
13103 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13104 spec->num_mixers++;
8c87286f 13105 return 1;
bc9f98a9
KY
13106}
13107
13108/* additional initialization for auto-configuration model */
13109static void alc662_auto_init(struct hda_codec *codec)
13110{
13111 alc662_auto_init_multi_out(codec);
13112 alc662_auto_init_hp_out(codec);
13113 alc662_auto_init_analog_input(codec);
13114}
13115
13116static int patch_alc662(struct hda_codec *codec)
13117{
13118 struct alc_spec *spec;
13119 int err, board_config;
13120
13121 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13122 if (!spec)
13123 return -ENOMEM;
13124
13125 codec->spec = spec;
13126
13127 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13128 alc662_models,
13129 alc662_cfg_tbl);
13130 if (board_config < 0) {
13131 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13132 "trying auto-probe from BIOS...\n");
13133 board_config = ALC662_AUTO;
13134 }
13135
13136 if (board_config == ALC662_AUTO) {
13137 /* automatic parse from the BIOS config */
13138 err = alc662_parse_auto_config(codec);
13139 if (err < 0) {
13140 alc_free(codec);
13141 return err;
8c87286f 13142 } else if (!err) {
bc9f98a9
KY
13143 printk(KERN_INFO
13144 "hda_codec: Cannot set up configuration "
13145 "from BIOS. Using base mode...\n");
13146 board_config = ALC662_3ST_2ch_DIG;
13147 }
13148 }
13149
13150 if (board_config != ALC662_AUTO)
13151 setup_preset(spec, &alc662_presets[board_config]);
13152
13153 spec->stream_name_analog = "ALC662 Analog";
13154 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13155 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13156
13157 spec->stream_name_digital = "ALC662 Digital";
13158 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13159 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13160
13161 if (!spec->adc_nids && spec->input_mux) {
13162 spec->adc_nids = alc662_adc_nids;
13163 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13164 }
13165
13166 codec->patch_ops = alc_patch_ops;
13167 if (board_config == ALC662_AUTO)
13168 spec->init_hook = alc662_auto_init;
cb53c626
TI
13169#ifdef CONFIG_SND_HDA_POWER_SAVE
13170 if (!spec->loopback.amplist)
13171 spec->loopback.amplist = alc662_loopbacks;
13172#endif
bc9f98a9
KY
13173
13174 return 0;
13175}
13176
1da177e4
LT
13177/*
13178 * patch entries
13179 */
13180struct hda_codec_preset snd_hda_preset_realtek[] = {
13181 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 13182 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 13183 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 13184 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 13185 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 13186 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 13187 .patch = patch_alc861 },
f32610ed
JS
13188 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13189 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13190 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
13191 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13192 .patch = patch_alc883 },
13193 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13194 .patch = patch_alc662 },
f32610ed 13195 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 13196 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 13197 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
df694daa 13198 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 13199 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 13200 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
13201 {} /* terminator */
13202};