]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] return ENODEV for disconnected devices
[thirdparty/kernel/stable.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <sound/driver.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
31#include <sound/core.h>
32#include "hda_codec.h"
33#include "hda_local.h"
34
35
36/* ALC880 board config type */
37enum {
1da177e4
LT
38 ALC880_3ST,
39 ALC880_3ST_DIG,
40 ALC880_5ST,
41 ALC880_5ST_DIG,
42 ALC880_W810,
dfc0ff62 43 ALC880_Z71V,
b6482d48 44 ALC880_6ST,
16ded525
TI
45 ALC880_6ST_DIG,
46 ALC880_F1734,
47 ALC880_ASUS,
48 ALC880_ASUS_DIG,
49 ALC880_ASUS_W1V,
df694daa 50 ALC880_ASUS_DIG2,
16ded525 51 ALC880_UNIWILL_DIG,
df694daa
KY
52 ALC880_CLEVO,
53 ALC880_TCL_S700,
e9edcee0
TI
54#ifdef CONFIG_SND_DEBUG
55 ALC880_TEST,
56#endif
df694daa 57 ALC880_AUTO,
16ded525
TI
58 ALC880_MODEL_LAST /* last tag */
59};
60
61/* ALC260 models */
62enum {
63 ALC260_BASIC,
64 ALC260_HP,
df694daa
KY
65 ALC260_HP_3013,
66 ALC260_FUJITSU_S702X,
0bfc90e9 67 ALC260_ACER,
7cf51e48
JW
68#ifdef CONFIG_SND_DEBUG
69 ALC260_TEST,
70#endif
df694daa 71 ALC260_AUTO,
16ded525 72 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
73};
74
df694daa
KY
75/* ALC262 models */
76enum {
77 ALC262_BASIC,
834be88d 78 ALC262_FUJITSU,
df694daa
KY
79 ALC262_AUTO,
80 ALC262_MODEL_LAST /* last tag */
81};
82
83/* ALC861 models */
84enum {
85 ALC861_3ST,
86 ALC861_3ST_DIG,
87 ALC861_6ST_DIG,
88 ALC861_AUTO,
89 ALC861_MODEL_LAST,
90};
91
92/* ALC882 models */
93enum {
94 ALC882_3ST_DIG,
95 ALC882_6ST_DIG,
96 ALC882_AUTO,
97 ALC882_MODEL_LAST,
98};
99
100/* for GPIO Poll */
101#define GPIO_MASK 0x03
102
1da177e4
LT
103struct alc_spec {
104 /* codec parameterization */
df694daa 105 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
106 unsigned int num_mixers;
107
df694daa 108 const struct hda_verb *init_verbs[5]; /* initialization verbs
e9edcee0
TI
109 * don't forget NULL termination!
110 */
111 unsigned int num_init_verbs;
1da177e4 112
16ded525 113 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
114 struct hda_pcm_stream *stream_analog_playback;
115 struct hda_pcm_stream *stream_analog_capture;
116
16ded525 117 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
118 struct hda_pcm_stream *stream_digital_playback;
119 struct hda_pcm_stream *stream_digital_capture;
120
121 /* playback */
16ded525
TI
122 struct hda_multi_out multiout; /* playback set-up
123 * max_channels, dacs must be set
124 * dig_out_nid and hp_nid are optional
125 */
1da177e4
LT
126
127 /* capture */
128 unsigned int num_adc_nids;
129 hda_nid_t *adc_nids;
16ded525 130 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
131
132 /* capture source */
133 const struct hda_input_mux *input_mux;
134 unsigned int cur_mux[3];
135
136 /* channel model */
d2a6d7dc 137 const struct hda_channel_mode *channel_mode;
1da177e4
LT
138 int num_channel_mode;
139
140 /* PCM information */
4c5186ed 141 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 142
e9edcee0
TI
143 /* dynamic controls, init_verbs and input_mux */
144 struct auto_pin_cfg autocfg;
145 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 146 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 147 struct hda_input_mux private_imux;
df694daa 148 hda_nid_t private_dac_nids[5];
834be88d
TI
149
150 /* for pin sensing */
151 unsigned int sense_updated: 1;
152 unsigned int jack_present: 1;
df694daa
KY
153};
154
155/*
156 * configuration template - to be copied to the spec instance
157 */
158struct alc_config_preset {
159 struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */
160 const struct hda_verb *init_verbs[5];
161 unsigned int num_dacs;
162 hda_nid_t *dac_nids;
163 hda_nid_t dig_out_nid; /* optional */
164 hda_nid_t hp_nid; /* optional */
165 unsigned int num_adc_nids;
166 hda_nid_t *adc_nids;
167 hda_nid_t dig_in_nid;
168 unsigned int num_channel_mode;
169 const struct hda_channel_mode *channel_mode;
170 const struct hda_input_mux *input_mux;
1da177e4
LT
171};
172
1da177e4
LT
173
174/*
175 * input MUX handling
176 */
c8b6bf9b 177static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
178{
179 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
180 struct alc_spec *spec = codec->spec;
181 return snd_hda_input_mux_info(spec->input_mux, uinfo);
182}
183
c8b6bf9b 184static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
185{
186 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
187 struct alc_spec *spec = codec->spec;
188 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
189
190 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
191 return 0;
192}
193
c8b6bf9b 194static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
195{
196 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
197 struct alc_spec *spec = codec->spec;
198 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
199 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
200 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
201}
202
e9edcee0 203
1da177e4
LT
204/*
205 * channel mode setting
206 */
df694daa 207static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4
LT
208{
209 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
210 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
211 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
212 spec->num_channel_mode);
1da177e4
LT
213}
214
df694daa 215static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
216{
217 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
218 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
219 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
220 spec->num_channel_mode, spec->multiout.max_channels);
1da177e4
LT
221}
222
df694daa 223static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
224{
225 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
226 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
227 return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
228 spec->num_channel_mode, &spec->multiout.max_channels);
1da177e4
LT
229}
230
a9430dd8 231/*
4c5186ed
JW
232 * Control the mode of pin widget settings via the mixer. "pc" is used
233 * instead of "%" to avoid consequences of accidently treating the % as
234 * being part of a format specifier. Maximum allowed length of a value is
235 * 63 characters plus NULL terminator.
7cf51e48
JW
236 *
237 * Note: some retasking pin complexes seem to ignore requests for input
238 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
239 * are requested. Therefore order this list so that this behaviour will not
240 * cause problems when mixer clients move through the enum sequentially.
241 * NIDs 0x0f and 0x10 have been observed to have this behaviour.
4c5186ed
JW
242 */
243static char *alc_pin_mode_names[] = {
7cf51e48
JW
244 "Mic 50pc bias", "Mic 80pc bias",
245 "Line in", "Line out", "Headphone out",
4c5186ed
JW
246};
247static unsigned char alc_pin_mode_values[] = {
7cf51e48 248 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
249};
250/* The control can present all 5 options, or it can limit the options based
251 * in the pin being assumed to be exclusively an input or an output pin.
a9430dd8 252 */
4c5186ed
JW
253#define ALC_PIN_DIR_IN 0x00
254#define ALC_PIN_DIR_OUT 0x01
255#define ALC_PIN_DIR_INOUT 0x02
256
257/* Info about the pin modes supported by the three different pin directions.
258 * For each direction the minimum and maximum values are given.
259 */
260static signed char alc_pin_mode_dir_info[3][2] = {
261 { 0, 2 }, /* ALC_PIN_DIR_IN */
262 { 3, 4 }, /* ALC_PIN_DIR_OUT */
263 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
264};
265#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
266#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
267#define alc_pin_mode_n_items(_dir) \
268 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
269
270static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
a9430dd8 271{
4c5186ed
JW
272 unsigned int item_num = uinfo->value.enumerated.item;
273 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
274
275 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 276 uinfo->count = 1;
4c5186ed
JW
277 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
278
279 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
280 item_num = alc_pin_mode_min(dir);
281 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
282 return 0;
283}
284
4c5186ed 285static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
a9430dd8 286{
4c5186ed 287 unsigned int i;
a9430dd8
JW
288 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
289 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 290 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 291 long *valp = ucontrol->value.integer.value;
4c5186ed 292 unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
a9430dd8 293
4c5186ed
JW
294 /* Find enumerated value for current pinctl setting */
295 i = alc_pin_mode_min(dir);
296 while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir))
297 i++;
298 *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir);
a9430dd8
JW
299 return 0;
300}
301
4c5186ed 302static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
a9430dd8 303{
4c5186ed 304 signed int change;
a9430dd8
JW
305 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
306 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
307 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
308 long val = *ucontrol->value.integer.value;
a9430dd8 309 unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
a9430dd8 310
4c5186ed
JW
311 if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir))
312 val = alc_pin_mode_min(dir);
313
314 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
315 if (change) {
316 /* Set pin mode to that requested */
a9430dd8 317 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
4c5186ed 318 alc_pin_mode_values[val]);
cdcd9268
JW
319
320 /* Also enable the retasking pin's input/output as required
321 * for the requested pin mode. Enum values of 2 or less are
322 * input modes.
323 *
324 * Dynamically switching the input/output buffers probably
325 * reduces noise slightly, particularly on input. However,
326 * havingboth input and output buffers enabled
327 * simultaneously doesn't seem to be problematic.
328 */
329 if (val <= 2) {
330 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
331 AMP_OUT_MUTE);
332 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
333 AMP_IN_UNMUTE(0));
334 } else {
335 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
336 AMP_IN_MUTE(0));
337 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
338 AMP_OUT_UNMUTE);
339 }
340 }
a9430dd8
JW
341 return change;
342}
343
4c5186ed 344#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 345 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
346 .info = alc_pin_mode_info, \
347 .get = alc_pin_mode_get, \
348 .put = alc_pin_mode_put, \
349 .private_value = nid | (dir<<16) }
df694daa 350
5c8f858d
JW
351/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
352 * together using a mask with more than one bit set. This control is
353 * currently used only by the ALC260 test model. At this stage they are not
354 * needed for any "production" models.
355 */
356#ifdef CONFIG_SND_DEBUG
357static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
358{
359 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
360 uinfo->count = 1;
361 uinfo->value.integer.min = 0;
362 uinfo->value.integer.max = 1;
363 return 0;
364}
365static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
366{
367 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
368 hda_nid_t nid = kcontrol->private_value & 0xffff;
369 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
370 long *valp = ucontrol->value.integer.value;
371 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);
372
373 *valp = (val & mask) != 0;
374 return 0;
375}
376static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
377{
378 signed int change;
379 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
380 hda_nid_t nid = kcontrol->private_value & 0xffff;
381 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
382 long val = *ucontrol->value.integer.value;
383 unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);
384
385 /* Set/unset the masked GPIO bit(s) as needed */
386 change = (val==0?0:mask) != (gpio_data & mask);
387 if (val==0)
388 gpio_data &= ~mask;
389 else
390 gpio_data |= mask;
391 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data);
392
393 return change;
394}
395#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
396 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
397 .info = alc_gpio_data_info, \
398 .get = alc_gpio_data_get, \
399 .put = alc_gpio_data_put, \
400 .private_value = nid | (mask<<16) }
401#endif /* CONFIG_SND_DEBUG */
402
92621f13
JW
403/* A switch control to allow the enabling of the digital IO pins on the
404 * ALC260. This is incredibly simplistic; the intention of this control is
405 * to provide something in the test model allowing digital outputs to be
406 * identified if present. If models are found which can utilise these
407 * outputs a more complete mixer control can be devised for those models if
408 * necessary.
409 */
410#ifdef CONFIG_SND_DEBUG
411static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
412{
413 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
414 uinfo->count = 1;
415 uinfo->value.integer.min = 0;
416 uinfo->value.integer.max = 1;
417 return 0;
418}
419static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
420{
421 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
422 hda_nid_t nid = kcontrol->private_value & 0xffff;
423 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
424 long *valp = ucontrol->value.integer.value;
425 unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00);
426
427 *valp = (val & mask) != 0;
428 return 0;
429}
430static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
431{
432 signed int change;
433 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
434 hda_nid_t nid = kcontrol->private_value & 0xffff;
435 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
436 long val = *ucontrol->value.integer.value;
437 unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00);
438
439 /* Set/unset the masked control bit(s) as needed */
440 change = (val==0?0:mask) != (ctrl_data & mask);
441 if (val==0)
442 ctrl_data &= ~mask;
443 else
444 ctrl_data |= mask;
445 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data);
446
447 return change;
448}
449#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
450 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
451 .info = alc_spdif_ctrl_info, \
452 .get = alc_spdif_ctrl_get, \
453 .put = alc_spdif_ctrl_put, \
454 .private_value = nid | (mask<<16) }
455#endif /* CONFIG_SND_DEBUG */
456
df694daa
KY
457/*
458 * set up from the preset table
459 */
460static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *preset)
461{
462 int i;
463
464 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
465 spec->mixers[spec->num_mixers++] = preset->mixers[i];
466 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++)
467 spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i];
468
469 spec->channel_mode = preset->channel_mode;
470 spec->num_channel_mode = preset->num_channel_mode;
471
472 spec->multiout.max_channels = spec->channel_mode[0].channels;
473
474 spec->multiout.num_dacs = preset->num_dacs;
475 spec->multiout.dac_nids = preset->dac_nids;
476 spec->multiout.dig_out_nid = preset->dig_out_nid;
477 spec->multiout.hp_nid = preset->hp_nid;
478
479 spec->input_mux = preset->input_mux;
480
481 spec->num_adc_nids = preset->num_adc_nids;
482 spec->adc_nids = preset->adc_nids;
483 spec->dig_in_nid = preset->dig_in_nid;
484}
485
1da177e4 486/*
e9edcee0
TI
487 * ALC880 3-stack model
488 *
489 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
490 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, F-Mic = 0x1b
491 * HP = 0x19
1da177e4
LT
492 */
493
e9edcee0
TI
494static hda_nid_t alc880_dac_nids[4] = {
495 /* front, rear, clfe, rear_surr */
496 0x02, 0x05, 0x04, 0x03
497};
498
499static hda_nid_t alc880_adc_nids[3] = {
500 /* ADC0-2 */
501 0x07, 0x08, 0x09,
502};
503
504/* The datasheet says the node 0x07 is connected from inputs,
505 * but it shows zero connection in the real implementation on some devices.
df694daa 506 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 507 */
e9edcee0
TI
508static hda_nid_t alc880_adc_nids_alt[2] = {
509 /* ADC1-2 */
510 0x08, 0x09,
511};
512
513#define ALC880_DIGOUT_NID 0x06
514#define ALC880_DIGIN_NID 0x0a
515
516static struct hda_input_mux alc880_capture_source = {
517 .num_items = 4,
518 .items = {
519 { "Mic", 0x0 },
520 { "Front Mic", 0x3 },
521 { "Line", 0x2 },
522 { "CD", 0x4 },
523 },
524};
525
526/* channel source setting (2/6 channel selection for 3-stack) */
527/* 2ch mode */
528static struct hda_verb alc880_threestack_ch2_init[] = {
529 /* set line-in to input, mute it */
530 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
531 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
532 /* set mic-in to input vref 80%, mute it */
533 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
534 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
535 { } /* end */
536};
537
538/* 6ch mode */
539static struct hda_verb alc880_threestack_ch6_init[] = {
540 /* set line-in to output, unmute it */
541 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
542 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
543 /* set mic-in to output, unmute it */
544 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
545 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
546 { } /* end */
547};
548
d2a6d7dc 549static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
550 { 2, alc880_threestack_ch2_init },
551 { 6, alc880_threestack_ch6_init },
552};
553
c8b6bf9b 554static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 555 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 556 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 557 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 558 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
559 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
560 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
561 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
562 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
565 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
566 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
567 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
568 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
569 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
570 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
571 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
572 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
574 {
575 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
576 .name = "Channel Mode",
df694daa
KY
577 .info = alc_ch_mode_info,
578 .get = alc_ch_mode_get,
579 .put = alc_ch_mode_put,
e9edcee0
TI
580 },
581 { } /* end */
582};
583
584/* capture mixer elements */
c8b6bf9b 585static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
586 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
587 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
588 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
589 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
590 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
591 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
592 {
593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594 /* The multiple "Capture Source" controls confuse alsamixer
595 * So call somewhat different..
596 * FIXME: the controls appear in the "playback" view!
597 */
598 /* .name = "Capture Source", */
599 .name = "Input Source",
e9edcee0 600 .count = 3,
1da177e4
LT
601 .info = alc_mux_enum_info,
602 .get = alc_mux_enum_get,
603 .put = alc_mux_enum_put,
604 },
1da177e4
LT
605 { } /* end */
606};
607
e9edcee0 608/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 609static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
610 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
611 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
612 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
613 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
614 {
615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
616 /* The multiple "Capture Source" controls confuse alsamixer
617 * So call somewhat different..
618 * FIXME: the controls appear in the "playback" view!
619 */
620 /* .name = "Capture Source", */
621 .name = "Input Source",
622 .count = 2,
623 .info = alc_mux_enum_info,
624 .get = alc_mux_enum_get,
625 .put = alc_mux_enum_put,
626 },
1da177e4
LT
627 { } /* end */
628};
629
e9edcee0
TI
630
631
632/*
633 * ALC880 5-stack model
634 *
635 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), Side = 0x02 (0xd)
636 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
637 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
638 */
639
640/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 641static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 642 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 643 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
644 { } /* end */
645};
646
e9edcee0
TI
647/* channel source setting (6/8 channel selection for 5-stack) */
648/* 6ch mode */
649static struct hda_verb alc880_fivestack_ch6_init[] = {
650 /* set line-in to input, mute it */
651 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
652 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
653 { } /* end */
654};
655
e9edcee0
TI
656/* 8ch mode */
657static struct hda_verb alc880_fivestack_ch8_init[] = {
658 /* set line-in to output, unmute it */
659 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
660 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
661 { } /* end */
662};
663
d2a6d7dc 664static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
665 { 6, alc880_fivestack_ch6_init },
666 { 8, alc880_fivestack_ch8_init },
667};
668
669
670/*
671 * ALC880 6-stack model
672 *
673 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), Side = 0x05 (0x0f)
674 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
675 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
676 */
677
678static hda_nid_t alc880_6st_dac_nids[4] = {
679 /* front, rear, clfe, rear_surr */
680 0x02, 0x03, 0x04, 0x05
681};
682
683static struct hda_input_mux alc880_6stack_capture_source = {
684 .num_items = 4,
685 .items = {
686 { "Mic", 0x0 },
687 { "Front Mic", 0x1 },
688 { "Line", 0x2 },
689 { "CD", 0x4 },
690 },
691};
692
693/* fixed 8-channels */
d2a6d7dc 694static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
695 { 8, NULL },
696};
697
c8b6bf9b 698static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 699 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 700 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 701 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 702 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
703 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
704 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
705 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
706 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 707 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 708 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
709 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
710 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
711 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
712 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
714 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
715 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
716 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
717 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
718 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
719 {
720 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
721 .name = "Channel Mode",
df694daa
KY
722 .info = alc_ch_mode_info,
723 .get = alc_ch_mode_get,
724 .put = alc_ch_mode_put,
16ded525
TI
725 },
726 { } /* end */
727};
728
e9edcee0
TI
729
730/*
731 * ALC880 W810 model
732 *
733 * W810 has rear IO for:
734 * Front (DAC 02)
735 * Surround (DAC 03)
736 * Center/LFE (DAC 04)
737 * Digital out (06)
738 *
739 * The system also has a pair of internal speakers, and a headphone jack.
740 * These are both connected to Line2 on the codec, hence to DAC 02.
741 *
742 * There is a variable resistor to control the speaker or headphone
743 * volume. This is a hardware-only device without a software API.
744 *
745 * Plugging headphones in will disable the internal speakers. This is
746 * implemented in hardware, not via the driver using jack sense. In
747 * a similar fashion, plugging into the rear socket marked "front" will
748 * disable both the speakers and headphones.
749 *
750 * For input, there's a microphone jack, and an "audio in" jack.
751 * These may not do anything useful with this driver yet, because I
752 * haven't setup any initialization verbs for these yet...
753 */
754
755static hda_nid_t alc880_w810_dac_nids[3] = {
756 /* front, rear/surround, clfe */
757 0x02, 0x03, 0x04
16ded525
TI
758};
759
e9edcee0 760/* fixed 6 channels */
d2a6d7dc 761static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
762 { 6, NULL }
763};
764
765/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 766static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 767 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 768 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 769 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 770 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
771 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
772 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
773 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
774 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
776 { } /* end */
777};
778
779
780/*
781 * Z710V model
782 *
783 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
784 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), Line = 0x1a
785 */
786
787static hda_nid_t alc880_z71v_dac_nids[1] = {
788 0x02
789};
790#define ALC880_Z71V_HP_DAC 0x03
791
792/* fixed 2 channels */
d2a6d7dc 793static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
794 { 2, NULL }
795};
796
c8b6bf9b 797static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 798 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 799 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 800 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 801 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
802 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
803 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
804 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
805 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
806 { } /* end */
807};
808
e9edcee0
TI
809
810/* FIXME! */
811/*
812 * ALC880 F1734 model
813 *
814 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
815 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
816 */
817
818static hda_nid_t alc880_f1734_dac_nids[1] = {
819 0x03
820};
821#define ALC880_F1734_HP_DAC 0x02
822
c8b6bf9b 823static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 824 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 825 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 826 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 827 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
828 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
829 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
831 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
832 { } /* end */
833};
834
835
836/* FIXME! */
837/*
838 * ALC880 ASUS model
839 *
840 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
841 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
842 * Mic = 0x18, Line = 0x1a
843 */
844
845#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
846#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
847
c8b6bf9b 848static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 849 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 850 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 851 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 852 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
853 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
854 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
855 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
856 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
863 {
864 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
865 .name = "Channel Mode",
df694daa
KY
866 .info = alc_ch_mode_info,
867 .get = alc_ch_mode_get,
868 .put = alc_ch_mode_put,
16ded525
TI
869 },
870 { } /* end */
871};
e9edcee0
TI
872
873/* FIXME! */
874/*
875 * ALC880 ASUS W1V model
876 *
877 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
878 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
879 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
880 */
881
882/* additional mixers to alc880_asus_mixer */
c8b6bf9b 883static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
884 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
885 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
886 { } /* end */
887};
888
3c10a9d9 889/* additional mixers to alc880_asus_mixer */
c8b6bf9b 890static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
891 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
892 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
893 { } /* end */
894};
e9edcee0 895
df694daa
KY
896/* TCL S700 */
897static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
898 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
899 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
901 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
902 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
905 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
906 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
907 {
908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
909 /* The multiple "Capture Source" controls confuse alsamixer
910 * So call somewhat different..
911 * FIXME: the controls appear in the "playback" view!
912 */
913 /* .name = "Capture Source", */
914 .name = "Input Source",
915 .count = 1,
916 .info = alc_mux_enum_info,
917 .get = alc_mux_enum_get,
918 .put = alc_mux_enum_put,
919 },
920 { } /* end */
921};
922
1da177e4 923/*
e9edcee0 924 * build control elements
1da177e4
LT
925 */
926static int alc_build_controls(struct hda_codec *codec)
927{
928 struct alc_spec *spec = codec->spec;
929 int err;
930 int i;
931
932 for (i = 0; i < spec->num_mixers; i++) {
933 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
934 if (err < 0)
935 return err;
936 }
937
938 if (spec->multiout.dig_out_nid) {
939 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
940 if (err < 0)
941 return err;
942 }
943 if (spec->dig_in_nid) {
944 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
945 if (err < 0)
946 return err;
947 }
948 return 0;
949}
950
e9edcee0 951
1da177e4
LT
952/*
953 * initialize the codec volumes, etc
954 */
955
e9edcee0
TI
956/*
957 * generic initialization of ADC, input mixers and output mixers
958 */
959static struct hda_verb alc880_volume_init_verbs[] = {
960 /*
961 * Unmute ADC0-2 and set the default input to mic-in
962 */
71fe7b82 963 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 964 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 965 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 967 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 968 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 969
e9edcee0
TI
970 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
971 * mixer widget
1da177e4
LT
972 * Note: PASD motherboards uses the Line In 2 as the input for front panel
973 * mic (mic 2)
974 */
e9edcee0 975 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16ded525 976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e9edcee0
TI
977 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1da177e4 981
e9edcee0
TI
982 /*
983 * Set up output mixers (0x0c - 0x0f)
1da177e4 984 */
e9edcee0
TI
985 /* set vol=0 to output mixers */
986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
987 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
988 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
989 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
990 /* set up input amps for analog loopback */
991 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
992 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
993 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
994 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
995 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1000
1001 { }
1002};
1003
e9edcee0
TI
1004/*
1005 * 3-stack pin configuration:
1006 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1007 */
1008static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1009 /*
1010 * preset connection lists of input pins
1011 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1012 */
1013 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1014 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1015 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1016
1017 /*
1018 * Set pin mode and muting
1019 */
1020 /* set front pin widgets 0x14 for output */
05acb863 1021 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1022 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1023 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1024 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1025 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1026 /* Mic2 (as headphone out) for HP output */
1027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1028 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1029 /* Line In pin widget for input */
05acb863 1030 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1031 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1032 /* Line2 (as front mic) pin widget for input and vref at 80% */
1033 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1034 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1035 /* CD pin widget for input */
05acb863 1036 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1037
e9edcee0
TI
1038 { }
1039};
1da177e4 1040
e9edcee0
TI
1041/*
1042 * 5-stack pin configuration:
1043 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1044 * line-in/side = 0x1a, f-mic = 0x1b
1045 */
1046static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1047 /*
1048 * preset connection lists of input pins
1049 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1050 */
e9edcee0
TI
1051 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1052 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1053
e9edcee0
TI
1054 /*
1055 * Set pin mode and muting
1da177e4 1056 */
e9edcee0
TI
1057 /* set pin widgets 0x14-0x17 for output */
1058 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1060 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1061 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1062 /* unmute pins for output (no gain on this amp) */
1063 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1065 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1066 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1067
1068 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1069 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1070 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1071 /* Mic2 (as headphone out) for HP output */
1072 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1073 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1074 /* Line In pin widget for input */
1075 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1076 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1077 /* Line2 (as front mic) pin widget for input and vref at 80% */
1078 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1079 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1080 /* CD pin widget for input */
1081 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1082
1083 { }
1084};
1085
e9edcee0
TI
1086/*
1087 * W810 pin configuration:
1088 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1089 */
1090static struct hda_verb alc880_pin_w810_init_verbs[] = {
1091 /* hphone/speaker input selector: front DAC */
1092 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1093
05acb863 1094 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1095 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1097 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1099 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1100
e9edcee0 1101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1102 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1103
1da177e4
LT
1104 { }
1105};
1106
e9edcee0
TI
1107/*
1108 * Z71V pin configuration:
1109 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1110 */
1111static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1113 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1114 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1115 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1116
16ded525 1117 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1121
1122 { }
1123};
1124
e9edcee0
TI
1125/*
1126 * 6-stack pin configuration:
1127 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, f-mic = 0x19,
1128 * line = 0x1a, HP = 0x1b
1129 */
1130static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1131 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1132
16ded525 1133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1135 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1136 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1137 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1138 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1139 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1140 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1141
16ded525 1142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1143 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1144 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1145 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1146 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1147 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1149 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1150 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1151
e9edcee0
TI
1152 { }
1153};
1154
1155/* FIXME! */
1156/*
1157 * F1734 pin configuration:
1158 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1159 */
1160static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1161 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1162 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1163 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1164 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1165
e9edcee0 1166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1167 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1169 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1170
e9edcee0
TI
1171 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1174 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1177 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1178 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1179 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62
TI
1180
1181 { }
1182};
1183
e9edcee0
TI
1184/* FIXME! */
1185/*
1186 * ASUS pin configuration:
1187 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1188 */
1189static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1190 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1191 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1192 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1193 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1194
1195 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1197 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1198 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1200 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1201 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1202 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1203
1204 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1206 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1208 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1210 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1212 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1213
e9edcee0
TI
1214 { }
1215};
16ded525 1216
e9edcee0
TI
1217/* Enable GPIO mask and set output */
1218static struct hda_verb alc880_gpio1_init_verbs[] = {
1219 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1220 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1221 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
df694daa
KY
1222
1223 { }
e9edcee0 1224};
16ded525 1225
e9edcee0
TI
1226/* Enable GPIO mask and set output */
1227static struct hda_verb alc880_gpio2_init_verbs[] = {
1228 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1229 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1230 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
df694daa
KY
1231
1232 { }
1233};
1234
1235/* Clevo m520g init */
1236static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1237 /* headphone output */
1238 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1239 /* line-out */
1240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1241 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1242 /* Line-in */
1243 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1244 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1245 /* CD */
1246 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1247 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1248 /* Mic1 (rear panel) */
1249 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1250 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1251 /* Mic2 (front panel) */
1252 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1253 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1254 /* headphone */
1255 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1256 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1257 /* change to EAPD mode */
1258 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1259 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1260
1261 { }
16ded525
TI
1262};
1263
df694daa
KY
1264static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1265 /* Headphone output */
1266 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1267 /* Front output*/
1268 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1269 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1270
1271 /* Line In pin widget for input */
1272 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1273 /* CD pin widget for input */
1274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1275 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1276 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1277
1278 /* change to EAPD mode */
1279 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1280 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1281
1282 { }
1283};
16ded525 1284
e9edcee0
TI
1285/*
1286 */
1287
1da177e4
LT
1288static int alc_init(struct hda_codec *codec)
1289{
1290 struct alc_spec *spec = codec->spec;
e9edcee0
TI
1291 unsigned int i;
1292
1293 for (i = 0; i < spec->num_init_verbs; i++)
1294 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1da177e4
LT
1295 return 0;
1296}
1297
1298#ifdef CONFIG_PM
1299/*
1300 * resume
1301 */
1302static int alc_resume(struct hda_codec *codec)
1303{
1304 struct alc_spec *spec = codec->spec;
1305 int i;
1306
1307 alc_init(codec);
e9edcee0 1308 for (i = 0; i < spec->num_mixers; i++)
1da177e4 1309 snd_hda_resume_ctls(codec, spec->mixers[i]);
1da177e4
LT
1310 if (spec->multiout.dig_out_nid)
1311 snd_hda_resume_spdif_out(codec);
1312 if (spec->dig_in_nid)
1313 snd_hda_resume_spdif_in(codec);
1314
1315 return 0;
1316}
1317#endif
1318
1319/*
1320 * Analog playback callbacks
1321 */
1322static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1323 struct hda_codec *codec,
c8b6bf9b 1324 struct snd_pcm_substream *substream)
1da177e4
LT
1325{
1326 struct alc_spec *spec = codec->spec;
1327 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1328}
1329
1330static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1331 struct hda_codec *codec,
1332 unsigned int stream_tag,
1333 unsigned int format,
c8b6bf9b 1334 struct snd_pcm_substream *substream)
1da177e4
LT
1335{
1336 struct alc_spec *spec = codec->spec;
1337 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1338 format, substream);
1339}
1340
1341static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1342 struct hda_codec *codec,
c8b6bf9b 1343 struct snd_pcm_substream *substream)
1da177e4
LT
1344{
1345 struct alc_spec *spec = codec->spec;
1346 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1347}
1348
1349/*
1350 * Digital out
1351 */
1352static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1353 struct hda_codec *codec,
c8b6bf9b 1354 struct snd_pcm_substream *substream)
1da177e4
LT
1355{
1356 struct alc_spec *spec = codec->spec;
1357 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1358}
1359
1360static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1361 struct hda_codec *codec,
c8b6bf9b 1362 struct snd_pcm_substream *substream)
1da177e4
LT
1363{
1364 struct alc_spec *spec = codec->spec;
1365 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1366}
1367
1368/*
1369 * Analog capture
1370 */
1371static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1372 struct hda_codec *codec,
1373 unsigned int stream_tag,
1374 unsigned int format,
c8b6bf9b 1375 struct snd_pcm_substream *substream)
1da177e4
LT
1376{
1377 struct alc_spec *spec = codec->spec;
1378
1379 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1380 stream_tag, 0, format);
1381 return 0;
1382}
1383
1384static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1385 struct hda_codec *codec,
c8b6bf9b 1386 struct snd_pcm_substream *substream)
1da177e4
LT
1387{
1388 struct alc_spec *spec = codec->spec;
1389
1390 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1391 return 0;
1392}
1393
1394
1395/*
1396 */
1397static struct hda_pcm_stream alc880_pcm_analog_playback = {
1398 .substreams = 1,
1399 .channels_min = 2,
1400 .channels_max = 8,
e9edcee0 1401 /* NID is set in alc_build_pcms */
1da177e4
LT
1402 .ops = {
1403 .open = alc880_playback_pcm_open,
1404 .prepare = alc880_playback_pcm_prepare,
1405 .cleanup = alc880_playback_pcm_cleanup
1406 },
1407};
1408
1409static struct hda_pcm_stream alc880_pcm_analog_capture = {
1410 .substreams = 2,
1411 .channels_min = 2,
1412 .channels_max = 2,
e9edcee0 1413 /* NID is set in alc_build_pcms */
1da177e4
LT
1414 .ops = {
1415 .prepare = alc880_capture_pcm_prepare,
1416 .cleanup = alc880_capture_pcm_cleanup
1417 },
1418};
1419
1420static struct hda_pcm_stream alc880_pcm_digital_playback = {
1421 .substreams = 1,
1422 .channels_min = 2,
1423 .channels_max = 2,
1424 /* NID is set in alc_build_pcms */
1425 .ops = {
1426 .open = alc880_dig_playback_pcm_open,
1427 .close = alc880_dig_playback_pcm_close
1428 },
1429};
1430
1431static struct hda_pcm_stream alc880_pcm_digital_capture = {
1432 .substreams = 1,
1433 .channels_min = 2,
1434 .channels_max = 2,
1435 /* NID is set in alc_build_pcms */
1436};
1437
4c5186ed
JW
1438/* Used by alc_build_pcms to flag that a PCM has no playback stream */
1439static struct hda_pcm_stream alc_pcm_null_playback = {
1440 .substreams = 0,
1441 .channels_min = 0,
1442 .channels_max = 0,
1443};
1444
1da177e4
LT
1445static int alc_build_pcms(struct hda_codec *codec)
1446{
1447 struct alc_spec *spec = codec->spec;
1448 struct hda_pcm *info = spec->pcm_rec;
1449 int i;
1450
1451 codec->num_pcms = 1;
1452 codec->pcm_info = info;
1453
1454 info->name = spec->stream_name_analog;
4a471b7d
TI
1455 if (spec->stream_analog_playback) {
1456 snd_assert(spec->multiout.dac_nids, return -EINVAL);
1457 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1458 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
1459 }
1460 if (spec->stream_analog_capture) {
1461 snd_assert(spec->adc_nids, return -EINVAL);
1462 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1463 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1464 }
1465
1466 if (spec->channel_mode) {
1467 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1468 for (i = 0; i < spec->num_channel_mode; i++) {
1469 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1470 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1471 }
1da177e4
LT
1472 }
1473 }
1474
4c5186ed
JW
1475 /* If the use of more than one ADC is requested for the current
1476 * model, configure a second analog capture-only PCM.
1477 */
1478 if (spec->num_adc_nids > 1) {
1479 codec->num_pcms++;
1480 info++;
1481 info->name = spec->stream_name_analog;
1482 /* No playback stream for second PCM */
1483 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
1484 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
1485 if (spec->stream_analog_capture) {
1486 snd_assert(spec->adc_nids, return -EINVAL);
1487 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1488 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
1489 }
1490 }
1491
1da177e4
LT
1492 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1493 codec->num_pcms++;
1494 info++;
1495 info->name = spec->stream_name_digital;
4a471b7d
TI
1496 if (spec->multiout.dig_out_nid &&
1497 spec->stream_digital_playback) {
1da177e4
LT
1498 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1499 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1500 }
4a471b7d
TI
1501 if (spec->dig_in_nid &&
1502 spec->stream_digital_capture) {
1da177e4
LT
1503 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1504 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1505 }
1506 }
1507
1508 return 0;
1509}
1510
1511static void alc_free(struct hda_codec *codec)
1512{
e9edcee0
TI
1513 struct alc_spec *spec = codec->spec;
1514 unsigned int i;
1515
1516 if (! spec)
1517 return;
1518
1519 if (spec->kctl_alloc) {
1520 for (i = 0; i < spec->num_kctl_used; i++)
1521 kfree(spec->kctl_alloc[i].name);
1522 kfree(spec->kctl_alloc);
1523 }
1524 kfree(spec);
1da177e4
LT
1525}
1526
1527/*
1528 */
1529static struct hda_codec_ops alc_patch_ops = {
1530 .build_controls = alc_build_controls,
1531 .build_pcms = alc_build_pcms,
1532 .init = alc_init,
1533 .free = alc_free,
1534#ifdef CONFIG_PM
1535 .resume = alc_resume,
1536#endif
1537};
1538
2fa522be
TI
1539
1540/*
1541 * Test configuration for debugging
1542 *
1543 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1544 * enum controls.
1545 */
1546#ifdef CONFIG_SND_DEBUG
1547static hda_nid_t alc880_test_dac_nids[4] = {
1548 0x02, 0x03, 0x04, 0x05
1549};
1550
1551static struct hda_input_mux alc880_test_capture_source = {
1552 .num_items = 5,
1553 .items = {
1554 { "In-1", 0x0 },
1555 { "In-2", 0x1 },
1556 { "In-3", 0x2 },
1557 { "In-4", 0x3 },
1558 { "CD", 0x4 },
1559 },
1560};
1561
d2a6d7dc 1562static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 1563 { 2, NULL },
fd2c326d 1564 { 4, NULL },
2fa522be 1565 { 6, NULL },
fd2c326d 1566 { 8, NULL },
2fa522be
TI
1567};
1568
c8b6bf9b 1569static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2fa522be
TI
1570{
1571 static char *texts[] = {
1572 "N/A", "Line Out", "HP Out",
1573 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1574 };
1575 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1576 uinfo->count = 1;
1577 uinfo->value.enumerated.items = 8;
1578 if (uinfo->value.enumerated.item >= 8)
1579 uinfo->value.enumerated.item = 7;
1580 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1581 return 0;
1582}
1583
c8b6bf9b 1584static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
1585{
1586 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1587 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1588 unsigned int pin_ctl, item = 0;
1589
1590 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1591 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1592 if (pin_ctl & AC_PINCTL_OUT_EN) {
1593 if (pin_ctl & AC_PINCTL_HP_EN)
1594 item = 2;
1595 else
1596 item = 1;
1597 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1598 switch (pin_ctl & AC_PINCTL_VREFEN) {
1599 case AC_PINCTL_VREF_HIZ: item = 3; break;
1600 case AC_PINCTL_VREF_50: item = 4; break;
1601 case AC_PINCTL_VREF_GRD: item = 5; break;
1602 case AC_PINCTL_VREF_80: item = 6; break;
1603 case AC_PINCTL_VREF_100: item = 7; break;
1604 }
1605 }
1606 ucontrol->value.enumerated.item[0] = item;
1607 return 0;
1608}
1609
c8b6bf9b 1610static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
1611{
1612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1613 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1614 static unsigned int ctls[] = {
1615 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1616 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1617 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1618 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1619 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1620 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1621 };
1622 unsigned int old_ctl, new_ctl;
1623
1624 old_ctl = snd_hda_codec_read(codec, nid, 0,
1625 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1626 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1627 if (old_ctl != new_ctl) {
1628 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1629 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1630 ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1631 return 1;
1632 }
1633 return 0;
1634}
1635
c8b6bf9b 1636static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2fa522be
TI
1637{
1638 static char *texts[] = {
1639 "Front", "Surround", "CLFE", "Side"
1640 };
1641 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1642 uinfo->count = 1;
1643 uinfo->value.enumerated.items = 4;
1644 if (uinfo->value.enumerated.item >= 4)
1645 uinfo->value.enumerated.item = 3;
1646 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1647 return 0;
1648}
1649
c8b6bf9b 1650static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
1651{
1652 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1653 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1654 unsigned int sel;
1655
1656 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1657 ucontrol->value.enumerated.item[0] = sel & 3;
1658 return 0;
1659}
1660
c8b6bf9b 1661static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
1662{
1663 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1664 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1665 unsigned int sel;
1666
1667 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1668 if (ucontrol->value.enumerated.item[0] != sel) {
1669 sel = ucontrol->value.enumerated.item[0] & 3;
1670 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1671 return 1;
1672 }
1673 return 0;
1674}
1675
1676#define PIN_CTL_TEST(xname,nid) { \
1677 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1678 .name = xname, \
1679 .info = alc_test_pin_ctl_info, \
1680 .get = alc_test_pin_ctl_get, \
1681 .put = alc_test_pin_ctl_put, \
1682 .private_value = nid \
1683 }
1684
1685#define PIN_SRC_TEST(xname,nid) { \
1686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1687 .name = xname, \
1688 .info = alc_test_pin_src_info, \
1689 .get = alc_test_pin_src_get, \
1690 .put = alc_test_pin_src_put, \
1691 .private_value = nid \
1692 }
1693
c8b6bf9b 1694static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
1695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1696 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1697 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1698 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
1699 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1700 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1701 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1702 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
1703 PIN_CTL_TEST("Front Pin Mode", 0x14),
1704 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1705 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1706 PIN_CTL_TEST("Side Pin Mode", 0x17),
1707 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1708 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1709 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1710 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1711 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1712 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1713 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1714 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1715 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1716 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1717 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1718 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1719 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1720 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1721 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1722 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1723 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1724 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
1725 {
1726 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1727 .name = "Channel Mode",
df694daa
KY
1728 .info = alc_ch_mode_info,
1729 .get = alc_ch_mode_get,
1730 .put = alc_ch_mode_put,
2fa522be
TI
1731 },
1732 { } /* end */
1733};
1734
1735static struct hda_verb alc880_test_init_verbs[] = {
1736 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
1737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1739 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1741 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1743 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 1745 /* Vol output for 0x0c-0x0f */
05acb863
TI
1746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 1750 /* Set output pins 0x14-0x17 */
05acb863
TI
1751 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1752 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1753 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1754 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 1755 /* Unmute output pins 0x14-0x17 */
05acb863
TI
1756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1758 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1759 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 1760 /* Set input pins 0x18-0x1c */
16ded525
TI
1761 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1762 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
1763 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 1766 /* Mute input pins 0x18-0x1b */
05acb863
TI
1767 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1768 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1770 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 1771 /* ADC set up */
05acb863 1772 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 1773 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 1774 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 1775 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 1776 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 1777 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
1778 /* Analog input/passthru */
1779 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1780 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1781 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1782 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1783 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
1784 { }
1785};
1786#endif
1787
1da177e4
LT
1788/*
1789 */
1790
1791static struct hda_board_config alc880_cfg_tbl[] = {
1792 /* Back 3 jack, front 2 jack */
1793 { .modelname = "3stack", .config = ALC880_3ST },
7291548d
TI
1794 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
1795 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
1796 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
1797 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
1798 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
1799 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
1800 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
1801 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
1802 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
1803 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
1804 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
1805 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
1806 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
1807 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
1808 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
1809 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
1810 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
1811 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
1812 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
1813 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
1814 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
1815 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
1816 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
1817 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
1818 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
1819 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
1820 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
1821 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
1822 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
1823 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
1824 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
1825 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
df694daa
KY
1826 /* TCL S700 */
1827 { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 },
1da177e4
LT
1828
1829 /* Back 3 jack, front 2 jack (Internal add Aux-In) */
7291548d 1830 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
16ded525 1831 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST },
0ca21611 1832 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
1da177e4
LT
1833
1834 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
1835 { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
7291548d 1836 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
5a47fe3c 1837 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG },
df694daa
KY
1838 /* Clevo m520G NB */
1839 { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, .config = ALC880_CLEVO },
1da177e4
LT
1840
1841 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
7291548d
TI
1842 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
1843 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
1844 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
1da177e4
LT
1845
1846 /* Back 5 jack, front 2 jack */
1847 { .modelname = "5stack", .config = ALC880_5ST },
7291548d
TI
1848 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
1849 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
1850 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
1851 { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
16ded525 1852 { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
1da177e4
LT
1853
1854 /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
1855 { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
7291548d
TI
1856 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
1857 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
1858 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
1859 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
1860 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
1861 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
1862 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1863 { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
16ded525 1864 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
7a318a70 1865 /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
16ded525 1866 { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
b0af0de5
TI
1867 /* note subvendor = 0 below */
1868 /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
1da177e4
LT
1869
1870 { .modelname = "w810", .config = ALC880_W810 },
7291548d 1871 { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
1da177e4 1872
dfc0ff62 1873 { .modelname = "z71v", .config = ALC880_Z71V },
7291548d 1874 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
dfc0ff62 1875
b6482d48 1876 { .modelname = "6stack", .config = ALC880_6ST },
7632c7b4 1877 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
df694daa 1878 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
7a318a70 1879 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
bae2bdb3 1880 { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */
b6482d48
TI
1881
1882 { .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
16ded525
TI
1883 { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
1884 { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
1885 { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
1886 { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
df694daa
KY
1887 { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG },
1888 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG },
1889 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG },
1890 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
041dec01 1891 { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
16ded525 1892
e9edcee0 1893 { .modelname = "asus", .config = ALC880_ASUS },
16ded525
TI
1894 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
1895 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
1896 { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
1897 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
8648811f 1898 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
16ded525
TI
1899 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
1900 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
1901 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
1902 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
1903 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
1904 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
df694daa 1905 { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
16ded525
TI
1906
1907 { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
1908 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
1909
1910 { .modelname = "F1734", .config = ALC880_F1734 },
1911 { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
df694daa 1912 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 },
16ded525 1913
2fa522be
TI
1914#ifdef CONFIG_SND_DEBUG
1915 { .modelname = "test", .config = ALC880_TEST },
1916#endif
df694daa 1917 { .modelname = "auto", .config = ALC880_AUTO },
2fa522be 1918
1da177e4
LT
1919 {}
1920};
1921
16ded525 1922/*
df694daa 1923 * ALC880 codec presets
16ded525 1924 */
16ded525
TI
1925static struct alc_config_preset alc880_presets[] = {
1926 [ALC880_3ST] = {
e9edcee0
TI
1927 .mixers = { alc880_three_stack_mixer },
1928 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
16ded525 1929 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 1930 .dac_nids = alc880_dac_nids,
16ded525
TI
1931 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1932 .channel_mode = alc880_threestack_modes,
1933 .input_mux = &alc880_capture_source,
1934 },
1935 [ALC880_3ST_DIG] = {
e9edcee0
TI
1936 .mixers = { alc880_three_stack_mixer },
1937 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
16ded525 1938 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
1939 .dac_nids = alc880_dac_nids,
1940 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
1941 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1942 .channel_mode = alc880_threestack_modes,
1943 .input_mux = &alc880_capture_source,
1944 },
df694daa
KY
1945 [ALC880_TCL_S700] = {
1946 .mixers = { alc880_tcl_s700_mixer },
1947 .init_verbs = { alc880_volume_init_verbs,
1948 alc880_pin_tcl_S700_init_verbs,
1949 alc880_gpio2_init_verbs },
1950 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1951 .dac_nids = alc880_dac_nids,
1952 .hp_nid = 0x03,
1953 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1954 .channel_mode = alc880_2_jack_modes,
1955 .input_mux = &alc880_capture_source,
1956 },
16ded525 1957 [ALC880_5ST] = {
e9edcee0
TI
1958 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
1959 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
16ded525
TI
1960 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1961 .dac_nids = alc880_dac_nids,
16ded525
TI
1962 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1963 .channel_mode = alc880_fivestack_modes,
1964 .input_mux = &alc880_capture_source,
1965 },
1966 [ALC880_5ST_DIG] = {
e9edcee0
TI
1967 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
1968 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
16ded525
TI
1969 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1970 .dac_nids = alc880_dac_nids,
1971 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
1972 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1973 .channel_mode = alc880_fivestack_modes,
1974 .input_mux = &alc880_capture_source,
1975 },
b6482d48
TI
1976 [ALC880_6ST] = {
1977 .mixers = { alc880_six_stack_mixer },
1978 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
1979 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1980 .dac_nids = alc880_6st_dac_nids,
1981 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1982 .channel_mode = alc880_sixstack_modes,
1983 .input_mux = &alc880_6stack_capture_source,
1984 },
16ded525 1985 [ALC880_6ST_DIG] = {
e9edcee0
TI
1986 .mixers = { alc880_six_stack_mixer },
1987 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
16ded525
TI
1988 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1989 .dac_nids = alc880_6st_dac_nids,
1990 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
1991 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1992 .channel_mode = alc880_sixstack_modes,
1993 .input_mux = &alc880_6stack_capture_source,
1994 },
1995 [ALC880_W810] = {
e9edcee0 1996 .mixers = { alc880_w810_base_mixer },
b0af0de5
TI
1997 .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
1998 alc880_gpio2_init_verbs },
16ded525
TI
1999 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2000 .dac_nids = alc880_w810_dac_nids,
2001 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2002 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2003 .channel_mode = alc880_w810_modes,
2004 .input_mux = &alc880_capture_source,
2005 },
2006 [ALC880_Z71V] = {
e9edcee0 2007 .mixers = { alc880_z71v_mixer },
b0af0de5 2008 .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
16ded525
TI
2009 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2010 .dac_nids = alc880_z71v_dac_nids,
2011 .dig_out_nid = ALC880_DIGOUT_NID,
2012 .hp_nid = 0x03,
e9edcee0
TI
2013 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2014 .channel_mode = alc880_2_jack_modes,
16ded525
TI
2015 .input_mux = &alc880_capture_source,
2016 },
2017 [ALC880_F1734] = {
e9edcee0
TI
2018 .mixers = { alc880_f1734_mixer },
2019 .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
2020 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2021 .dac_nids = alc880_f1734_dac_nids,
2022 .hp_nid = 0x02,
2023 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2024 .channel_mode = alc880_2_jack_modes,
16ded525
TI
2025 .input_mux = &alc880_capture_source,
2026 },
2027 [ALC880_ASUS] = {
e9edcee0
TI
2028 .mixers = { alc880_asus_mixer },
2029 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2030 alc880_gpio1_init_verbs },
2031 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2032 .dac_nids = alc880_asus_dac_nids,
2033 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2034 .channel_mode = alc880_asus_modes,
16ded525
TI
2035 .input_mux = &alc880_capture_source,
2036 },
2037 [ALC880_ASUS_DIG] = {
e9edcee0
TI
2038 .mixers = { alc880_asus_mixer },
2039 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2040 alc880_gpio1_init_verbs },
2041 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2042 .dac_nids = alc880_asus_dac_nids,
16ded525 2043 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
2044 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2045 .channel_mode = alc880_asus_modes,
16ded525
TI
2046 .input_mux = &alc880_capture_source,
2047 },
df694daa
KY
2048 [ALC880_ASUS_DIG2] = {
2049 .mixers = { alc880_asus_mixer },
2050 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2051 alc880_gpio2_init_verbs }, /* use GPIO2 */
2052 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2053 .dac_nids = alc880_asus_dac_nids,
2054 .dig_out_nid = ALC880_DIGOUT_NID,
2055 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2056 .channel_mode = alc880_asus_modes,
2057 .input_mux = &alc880_capture_source,
2058 },
16ded525 2059 [ALC880_ASUS_W1V] = {
e9edcee0
TI
2060 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2061 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2062 alc880_gpio1_init_verbs },
2063 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2064 .dac_nids = alc880_asus_dac_nids,
16ded525 2065 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
2066 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2067 .channel_mode = alc880_asus_modes,
16ded525
TI
2068 .input_mux = &alc880_capture_source,
2069 },
2070 [ALC880_UNIWILL_DIG] = {
3c10a9d9 2071 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
e9edcee0
TI
2072 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs },
2073 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2074 .dac_nids = alc880_asus_dac_nids,
16ded525 2075 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
2076 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2077 .channel_mode = alc880_asus_modes,
16ded525
TI
2078 .input_mux = &alc880_capture_source,
2079 },
df694daa
KY
2080 [ALC880_CLEVO] = {
2081 .mixers = { alc880_three_stack_mixer },
2082 .init_verbs = { alc880_volume_init_verbs,
2083 alc880_pin_clevo_init_verbs },
2084 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2085 .dac_nids = alc880_dac_nids,
2086 .hp_nid = 0x03,
2087 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2088 .channel_mode = alc880_threestack_modes,
2089 .input_mux = &alc880_capture_source,
2090 },
16ded525
TI
2091#ifdef CONFIG_SND_DEBUG
2092 [ALC880_TEST] = {
e9edcee0
TI
2093 .mixers = { alc880_test_mixer },
2094 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
2095 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2096 .dac_nids = alc880_test_dac_nids,
2097 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2098 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2099 .channel_mode = alc880_test_modes,
2100 .input_mux = &alc880_test_capture_source,
2101 },
2102#endif
2103};
2104
e9edcee0
TI
2105/*
2106 * Automatic parse of I/O pins from the BIOS configuration
2107 */
2108
2109#define NUM_CONTROL_ALLOC 32
2110#define NUM_VERB_ALLOC 32
2111
2112enum {
2113 ALC_CTL_WIDGET_VOL,
2114 ALC_CTL_WIDGET_MUTE,
2115 ALC_CTL_BIND_MUTE,
2116};
c8b6bf9b 2117static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
2118 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2119 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 2120 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
2121};
2122
2123/* add dynamic controls */
2124static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
2125{
c8b6bf9b 2126 struct snd_kcontrol_new *knew;
e9edcee0
TI
2127
2128 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2129 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2130
2131 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2132 if (! knew)
2133 return -ENOMEM;
2134 if (spec->kctl_alloc) {
2135 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2136 kfree(spec->kctl_alloc);
2137 }
2138 spec->kctl_alloc = knew;
2139 spec->num_kctl_alloc = num;
2140 }
2141
2142 knew = &spec->kctl_alloc[spec->num_kctl_used];
2143 *knew = alc880_control_templates[type];
543537bd 2144 knew->name = kstrdup(name, GFP_KERNEL);
e9edcee0
TI
2145 if (! knew->name)
2146 return -ENOMEM;
2147 knew->private_value = val;
2148 spec->num_kctl_used++;
2149 return 0;
2150}
2151
2152#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
2153#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
2154#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
2155#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
2156#define alc880_is_input_pin(nid) ((nid) >= 0x18)
2157#define alc880_input_pin_idx(nid) ((nid) - 0x18)
2158#define alc880_idx_to_dac(nid) ((nid) + 0x02)
2159#define alc880_dac_to_idx(nid) ((nid) - 0x02)
2160#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
2161#define alc880_idx_to_selector(nid) ((nid) + 0x10)
2162#define ALC880_PIN_CD_NID 0x1c
2163
2164/* fill in the dac_nids table from the parsed pin configuration */
2165static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
2166{
2167 hda_nid_t nid;
2168 int assigned[4];
2169 int i, j;
2170
2171 memset(assigned, 0, sizeof(assigned));
b0af0de5 2172 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
2173
2174 /* check the pins hardwired to audio widget */
2175 for (i = 0; i < cfg->line_outs; i++) {
2176 nid = cfg->line_out_pins[i];
2177 if (alc880_is_fixed_pin(nid)) {
2178 int idx = alc880_fixed_pin_idx(nid);
5014f193 2179 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
2180 assigned[idx] = 1;
2181 }
2182 }
2183 /* left pins can be connect to any audio widget */
2184 for (i = 0; i < cfg->line_outs; i++) {
2185 nid = cfg->line_out_pins[i];
2186 if (alc880_is_fixed_pin(nid))
2187 continue;
2188 /* search for an empty channel */
2189 for (j = 0; j < cfg->line_outs; j++) {
2190 if (! assigned[j]) {
2191 spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
2192 assigned[j] = 1;
2193 break;
2194 }
2195 }
2196 }
2197 spec->multiout.num_dacs = cfg->line_outs;
2198 return 0;
2199}
2200
2201/* add playback controls from the parsed DAC table */
df694daa
KY
2202static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2203 const struct auto_pin_cfg *cfg)
e9edcee0
TI
2204{
2205 char name[32];
2206 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2207 hda_nid_t nid;
2208 int i, err;
2209
2210 for (i = 0; i < cfg->line_outs; i++) {
2211 if (! spec->multiout.dac_nids[i])
2212 continue;
2213 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
2214 if (i == 2) {
2215 /* Center/LFE */
2216 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
2217 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
2218 return err;
2219 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
2220 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
2221 return err;
2222 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
2223 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
2224 return err;
2225 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
2226 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
2227 return err;
2228 } else {
2229 sprintf(name, "%s Playback Volume", chname[i]);
2230 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2231 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2232 return err;
2233 sprintf(name, "%s Playback Switch", chname[i]);
2234 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2235 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2236 return err;
2237 }
2238 }
e9edcee0
TI
2239 return 0;
2240}
2241
8d88bc3d
TI
2242/* add playback controls for speaker and HP outputs */
2243static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2244 const char *pfx)
e9edcee0
TI
2245{
2246 hda_nid_t nid;
2247 int err;
8d88bc3d 2248 char name[32];
e9edcee0
TI
2249
2250 if (! pin)
2251 return 0;
2252
2253 if (alc880_is_fixed_pin(pin)) {
2254 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
2255 if (! spec->multiout.dac_nids[0]) {
2256 /* use this as the primary output */
2257 spec->multiout.dac_nids[0] = nid;
2258 if (! spec->multiout.num_dacs)
2259 spec->multiout.num_dacs = 1;
2260 } else
8d88bc3d 2261 /* specify the DAC as the extra output */
e9edcee0
TI
2262 spec->multiout.hp_nid = nid;
2263 /* control HP volume/switch on the output mixer amp */
2264 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d
TI
2265 sprintf(name, "%s Playback Volume", pfx);
2266 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
e9edcee0
TI
2267 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2268 return err;
8d88bc3d
TI
2269 sprintf(name, "%s Playback Switch", pfx);
2270 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
e9edcee0
TI
2271 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2272 return err;
2273 } else if (alc880_is_multi_pin(pin)) {
2274 /* set manual connection */
2275 if (! spec->multiout.dac_nids[0]) {
2276 /* use this as the primary output */
2277 spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin));
2278 if (! spec->multiout.num_dacs)
2279 spec->multiout.num_dacs = 1;
2280 }
2281 /* we have only a switch on HP-out PIN */
8d88bc3d
TI
2282 sprintf(name, "%s Playback Switch", pfx);
2283 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
e9edcee0
TI
2284 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
2285 return err;
2286 }
2287 return 0;
2288}
2289
2290/* create input playback/capture controls for the given pin */
df694daa
KY
2291static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
2292 int idx, hda_nid_t mix_nid)
e9edcee0
TI
2293{
2294 char name[32];
df694daa 2295 int err;
e9edcee0
TI
2296
2297 sprintf(name, "%s Playback Volume", ctlname);
e9edcee0 2298 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
df694daa 2299 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
e9edcee0
TI
2300 return err;
2301 sprintf(name, "%s Playback Switch", ctlname);
2302 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
df694daa 2303 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
e9edcee0
TI
2304 return err;
2305 return 0;
2306}
2307
2308/* create playback/capture controls for input pins */
df694daa
KY
2309static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
2310 const struct auto_pin_cfg *cfg)
e9edcee0 2311{
e9edcee0 2312 struct hda_input_mux *imux = &spec->private_imux;
df694daa 2313 int i, err, idx;
e9edcee0
TI
2314
2315 for (i = 0; i < AUTO_PIN_LAST; i++) {
2316 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 2317 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
2318 err = new_analog_input(spec, cfg->input_pins[i],
2319 auto_pin_cfg_labels[i],
df694daa 2320 idx, 0x0b);
e9edcee0
TI
2321 if (err < 0)
2322 return err;
4a471b7d 2323 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
e9edcee0
TI
2324 imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
2325 imux->num_items++;
2326 }
2327 }
2328 return 0;
2329}
2330
df694daa
KY
2331static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
2332 hda_nid_t nid, int pin_type,
e9edcee0
TI
2333 int dac_idx)
2334{
2335 /* set as output */
2336 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2337 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2338 /* need the manual connection? */
2339 if (alc880_is_multi_pin(nid)) {
2340 struct alc_spec *spec = codec->spec;
2341 int idx = alc880_multi_pin_idx(nid);
2342 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
2343 AC_VERB_SET_CONNECT_SEL,
2344 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
2345 }
2346}
2347
2348static void alc880_auto_init_multi_out(struct hda_codec *codec)
2349{
2350 struct alc_spec *spec = codec->spec;
2351 int i;
2352
2353 for (i = 0; i < spec->autocfg.line_outs; i++) {
2354 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2355 alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2356 }
2357}
2358
8d88bc3d 2359static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
2360{
2361 struct alc_spec *spec = codec->spec;
2362 hda_nid_t pin;
2363
8d88bc3d
TI
2364 pin = spec->autocfg.speaker_pin;
2365 if (pin) /* connect to front */
2366 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
e9edcee0
TI
2367 pin = spec->autocfg.hp_pin;
2368 if (pin) /* connect to front */
2369 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2370}
2371
2372static void alc880_auto_init_analog_input(struct hda_codec *codec)
2373{
2374 struct alc_spec *spec = codec->spec;
2375 int i;
2376
2377 for (i = 0; i < AUTO_PIN_LAST; i++) {
2378 hda_nid_t nid = spec->autocfg.input_pins[i];
2379 if (alc880_is_input_pin(nid)) {
2380 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2381 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2382 if (nid != ALC880_PIN_CD_NID)
2383 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2384 AMP_OUT_MUTE);
2385 }
2386 }
2387}
2388
2389/* parse the BIOS configuration and set up the alc_spec */
2390/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2391static int alc880_parse_auto_config(struct hda_codec *codec)
2392{
2393 struct alc_spec *spec = codec->spec;
2394 int err;
df694daa 2395 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 2396
df694daa
KY
2397 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2398 alc880_ignore)) < 0)
e9edcee0 2399 return err;
8d88bc3d
TI
2400 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
2401 ! spec->autocfg.hp_pin)
e9edcee0 2402 return 0; /* can't find valid BIOS pin config */
df694daa
KY
2403
2404 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
2405 (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
8d88bc3d
TI
2406 (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
2407 "Speaker")) < 0 ||
2408 (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
2409 "Headphone")) < 0 ||
e9edcee0
TI
2410 (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2411 return err;
2412
2413 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2414
2415 if (spec->autocfg.dig_out_pin)
2416 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
2417 if (spec->autocfg.dig_in_pin)
2418 spec->dig_in_nid = ALC880_DIGIN_NID;
2419
2420 if (spec->kctl_alloc)
2421 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2422
2423 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
2424
2425 spec->input_mux = &spec->private_imux;
2426
2427 return 1;
2428}
2429
2430/* init callback for auto-configuration model -- overriding the default init */
2431static int alc880_auto_init(struct hda_codec *codec)
2432{
2433 alc_init(codec);
2434 alc880_auto_init_multi_out(codec);
8d88bc3d 2435 alc880_auto_init_extra_out(codec);
e9edcee0
TI
2436 alc880_auto_init_analog_input(codec);
2437 return 0;
2438}
2439
2440/*
2441 * OK, here we have finally the patch for ALC880
2442 */
2443
1da177e4
LT
2444static int patch_alc880(struct hda_codec *codec)
2445{
2446 struct alc_spec *spec;
2447 int board_config;
df694daa 2448 int err;
1da177e4 2449
e560d8d8 2450 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
2451 if (spec == NULL)
2452 return -ENOMEM;
2453
2454 codec->spec = spec;
2455
2456 board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
16ded525 2457 if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
e9edcee0
TI
2458 printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n");
2459 board_config = ALC880_AUTO;
1da177e4 2460 }
1da177e4 2461
e9edcee0
TI
2462 if (board_config == ALC880_AUTO) {
2463 /* automatic parse from the BIOS config */
2464 err = alc880_parse_auto_config(codec);
2465 if (err < 0) {
2466 alc_free(codec);
2467 return err;
2468 } else if (! err) {
2469 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 3-stack mode...\n");
2470 board_config = ALC880_3ST;
2471 }
1da177e4
LT
2472 }
2473
df694daa
KY
2474 if (board_config != ALC880_AUTO)
2475 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
2476
2477 spec->stream_name_analog = "ALC880 Analog";
2478 spec->stream_analog_playback = &alc880_pcm_analog_playback;
2479 spec->stream_analog_capture = &alc880_pcm_analog_capture;
2480
2481 spec->stream_name_digital = "ALC880 Digital";
2482 spec->stream_digital_playback = &alc880_pcm_digital_playback;
2483 spec->stream_digital_capture = &alc880_pcm_digital_capture;
2484
e9edcee0
TI
2485 if (! spec->adc_nids && spec->input_mux) {
2486 /* check whether NID 0x07 is valid */
54d17403 2487 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
e9edcee0
TI
2488 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
2489 if (wcap != AC_WID_AUD_IN) {
2490 spec->adc_nids = alc880_adc_nids_alt;
2491 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
2492 spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
2493 spec->num_mixers++;
2494 } else {
2495 spec->adc_nids = alc880_adc_nids;
2496 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
2497 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
2498 spec->num_mixers++;
2499 }
2500 }
1da177e4
LT
2501
2502 codec->patch_ops = alc_patch_ops;
e9edcee0
TI
2503 if (board_config == ALC880_AUTO)
2504 codec->patch_ops.init = alc880_auto_init;
1da177e4
LT
2505
2506 return 0;
2507}
2508
e9edcee0 2509
1da177e4
LT
2510/*
2511 * ALC260 support
2512 */
2513
e9edcee0
TI
2514static hda_nid_t alc260_dac_nids[1] = {
2515 /* front */
2516 0x02,
2517};
2518
2519static hda_nid_t alc260_adc_nids[1] = {
2520 /* ADC0 */
2521 0x04,
2522};
2523
df694daa 2524static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
2525 /* ADC1 */
2526 0x05,
2527};
2528
df694daa
KY
2529static hda_nid_t alc260_hp_adc_nids[2] = {
2530 /* ADC1, 0 */
2531 0x05, 0x04
2532};
2533
d57fdac0
JW
2534/* NIDs used when simultaneous access to both ADCs makes sense. Note that
2535 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
2536 */
2537static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
2538 /* ADC0, ADC1 */
2539 0x04, 0x05
2540};
2541
e9edcee0
TI
2542#define ALC260_DIGOUT_NID 0x03
2543#define ALC260_DIGIN_NID 0x06
2544
2545static struct hda_input_mux alc260_capture_source = {
2546 .num_items = 4,
2547 .items = {
2548 { "Mic", 0x0 },
2549 { "Front Mic", 0x1 },
2550 { "Line", 0x2 },
2551 { "CD", 0x4 },
2552 },
2553};
2554
17e7aec6
JW
2555/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
2556 * headphone jack and the internal CD lines.
a9430dd8
JW
2557 */
2558static struct hda_input_mux alc260_fujitsu_capture_source = {
4c5186ed 2559 .num_items = 3,
a9430dd8
JW
2560 .items = {
2561 { "Mic/Line", 0x0 },
2562 { "CD", 0x4 },
4c5186ed 2563 { "Headphone", 0x2 },
a9430dd8
JW
2564 },
2565};
2566
0bfc90e9
JW
2567/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configutation to
2568 * the Fujitsu S702x, but jacks are marked differently. We won't allow
2569 * retasking the Headphone jack, so it won't be available here.
2570 */
2571static struct hda_input_mux alc260_acer_capture_source = {
2572 .num_items = 3,
2573 .items = {
2574 { "Mic", 0x0 },
2575 { "Line", 0x2 },
2576 { "CD", 0x4 },
2577 },
2578};
2579
1da177e4
LT
2580/*
2581 * This is just place-holder, so there's something for alc_build_pcms to look
2582 * at when it calculates the maximum number of channels. ALC260 has no mixer
2583 * element which allows changing the channel mode, so the verb list is
2584 * never used.
2585 */
d2a6d7dc 2586static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
2587 { 2, NULL },
2588};
2589
df694daa
KY
2590
2591/* Mixer combinations
2592 *
2593 * basic: base_output + input + pc_beep + capture
2594 * HP: base_output + input + capture_alt
2595 * HP_3013: hp_3013 + input + capture
2596 * fujitsu: fujitsu + capture
0bfc90e9 2597 * acer: acer + capture
df694daa
KY
2598 */
2599
2600static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 2601 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 2602 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 2603 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 2604 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 2605 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 2606 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 2607 { } /* end */
df694daa 2608};
1da177e4 2609
df694daa 2610static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
2611 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2612 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2613 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2614 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2616 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2617 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
2618 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
2619 { } /* end */
2620};
2621
2622static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
2623 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
2624 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
2625 { } /* end */
2626};
2627
2628static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
2629 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2630 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2631 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
2632 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
2633 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2635 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2636 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
2637 { } /* end */
2638};
2639
c8b6bf9b 2640static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 2641 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 2642 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 2643 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
2644 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2645 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2646 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
2647 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 2648 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
2649 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
2650 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
2651 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 2652 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
2653 { } /* end */
2654};
2655
0bfc90e9
JW
2656static struct snd_kcontrol_new alc260_acer_mixer[] = {
2657 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2658 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2660 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2662 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2663 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
2664 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2665 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2666 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
2667 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
2668 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
2669 { } /* end */
2670};
2671
df694daa
KY
2672/* capture mixer elements */
2673static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
2674 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
2675 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
2676 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
2677 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
2678 {
2679 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
2680 /* The multiple "Capture Source" controls confuse alsamixer
2681 * So call somewhat different..
2682 * FIXME: the controls appear in the "playback" view!
2683 */
2684 /* .name = "Capture Source", */
2685 .name = "Input Source",
2686 .count = 2,
2687 .info = alc_mux_enum_info,
2688 .get = alc_mux_enum_get,
2689 .put = alc_mux_enum_put,
2690 },
2691 { } /* end */
2692};
2693
2694static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
2695 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
2696 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
2697 {
2698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2699 /* The multiple "Capture Source" controls confuse alsamixer
2700 * So call somewhat different..
2701 * FIXME: the controls appear in the "playback" view!
2702 */
2703 /* .name = "Capture Source", */
2704 .name = "Input Source",
2705 .count = 1,
a9430dd8
JW
2706 .info = alc_mux_enum_info,
2707 .get = alc_mux_enum_get,
2708 .put = alc_mux_enum_put,
2709 },
2710 { } /* end */
2711};
2712
df694daa
KY
2713/*
2714 * initialization verbs
2715 */
1da177e4
LT
2716static struct hda_verb alc260_init_verbs[] = {
2717 /* Line In pin widget for input */
05acb863 2718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2719 /* CD pin widget for input */
05acb863 2720 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2721 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 2722 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 2723 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 2724 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 2725 /* LINE-2 is used for line-out in rear */
05acb863 2726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 2727 /* select line-out */
fd56f2db 2728 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 2729 /* LINE-OUT pin */
05acb863 2730 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 2731 /* enable HP */
05acb863 2732 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 2733 /* enable Mono */
05acb863
TI
2734 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2735 /* mute capture amp left and right */
16ded525 2736 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
2737 /* set connection select to line in (default select for this ADC) */
2738 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
2739 /* mute capture amp left and right */
2740 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2741 /* set connection select to line in (default select for this ADC) */
2742 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
2743 /* set vol=0 Line-Out mixer amp left and right */
2744 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2745 /* unmute pin widget amp left and right (no gain on this amp) */
2746 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2747 /* set vol=0 HP mixer amp left and right */
2748 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2749 /* unmute pin widget amp left and right (no gain on this amp) */
2750 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2751 /* set vol=0 Mono mixer amp left and right */
2752 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2753 /* unmute pin widget amp left and right (no gain on this amp) */
2754 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2755 /* unmute LINE-2 out pin */
2756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2757 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
05acb863 2758 /* mute CD */
16ded525 2759 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
05acb863 2760 /* mute Line In */
16ded525 2761 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
05acb863 2762 /* mute Mic */
16ded525 2763 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2764 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
2765 /* mute Front out path */
2766 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2767 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2768 /* mute Headphone out path */
2769 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2770 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2771 /* mute Mono out path */
2772 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2773 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2774 { }
2775};
2776
df694daa
KY
2777static struct hda_verb alc260_hp_init_verbs[] = {
2778 /* Headphone and output */
2779 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
2780 /* mono output */
2781 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2782 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2783 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
2784 /* Mic2 (front panel) pin widget for input and vref at 80% */
2785 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
2786 /* Line In pin widget for input */
2787 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2788 /* Line-2 pin widget for output */
2789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2790 /* CD pin widget for input */
2791 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2792 /* unmute amp left and right */
2793 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
2794 /* set connection select to line in (default select for this ADC) */
2795 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
2796 /* unmute Line-Out mixer amp left and right (volume = 0) */
2797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
2798 /* mute pin widget amp left and right (no gain on this amp) */
2799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
2800 /* unmute HP mixer amp left and right (volume = 0) */
2801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
2802 /* mute pin widget amp left and right (no gain on this amp) */
2803 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
2804 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
2805 /* unmute CD */
2806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
2807 /* unmute Line In */
2808 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
2809 /* unmute Mic */
2810 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2811 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
2812 /* Unmute Front out path */
2813 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2814 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2815 /* Unmute Headphone out path */
2816 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2817 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2818 /* Unmute Mono out path */
2819 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2820 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2821 { }
2822};
2823
2824static struct hda_verb alc260_hp_3013_init_verbs[] = {
2825 /* Line out and output */
2826 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2827 /* mono output */
2828 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2829 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2830 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
2831 /* Mic2 (front panel) pin widget for input and vref at 80% */
2832 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
2833 /* Line In pin widget for input */
2834 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2835 /* Headphone pin widget for output */
2836 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
2837 /* CD pin widget for input */
2838 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2839 /* unmute amp left and right */
2840 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
2841 /* set connection select to line in (default select for this ADC) */
2842 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
2843 /* unmute Line-Out mixer amp left and right (volume = 0) */
2844 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
2845 /* mute pin widget amp left and right (no gain on this amp) */
2846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
2847 /* unmute HP mixer amp left and right (volume = 0) */
2848 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
2849 /* mute pin widget amp left and right (no gain on this amp) */
2850 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
2851 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
2852 /* unmute CD */
2853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
2854 /* unmute Line In */
2855 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
2856 /* unmute Mic */
2857 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2858 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
2859 /* Unmute Front out path */
2860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2861 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2862 /* Unmute Headphone out path */
2863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2864 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2865 /* Unmute Mono out path */
2866 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2867 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2868 { }
2869};
2870
a9430dd8
JW
2871/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
2872 * laptops.
2873 */
2874static struct hda_verb alc260_fujitsu_init_verbs[] = {
2875 /* Disable all GPIOs */
2876 {0x01, AC_VERB_SET_GPIO_MASK, 0},
2877 /* Internal speaker is connected to headphone pin */
2878 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2879 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
2880 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
2881 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
2882 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2883 /* Ensure all other unused pins are disabled and muted. */
2884 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2885 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 2886 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 2887 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 2888 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
2889 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2890 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2891 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2892
2893 /* Disable digital (SPDIF) pins */
2894 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
2895 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 2896
f7ace40d
JW
2897 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
2898 * when acting as an output.
2899 */
2900 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 2901
f7ace40d 2902 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
2903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2904 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2905 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2906 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2908 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2909 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2910 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2911 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 2912
f7ace40d
JW
2913 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
2914 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2915 /* Unmute Line1 pin widget output buffer since it starts as an output.
2916 * If the pin mode is changed by the user the pin mode control will
2917 * take care of enabling the pin's input/output buffers as needed.
2918 * Therefore there's no need to enable the input buffer at this
2919 * stage.
cdcd9268 2920 */
f7ace40d 2921 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
2922 /* Unmute input buffer of pin widget used for Line-in (no equiv
2923 * mixer ctrl)
2924 */
f7ace40d
JW
2925 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2926
2927 /* Mute capture amp left and right */
2928 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2929 /* Set ADC connection select to match default mixer setting - line
2930 * in (on mic1 pin)
2931 */
2932 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
2933
2934 /* Do the same for the second ADC: mute capture input amp and
2935 * set ADC connection to line in (on mic1 pin)
2936 */
2937 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2938 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
2939
2940 /* Mute all inputs to mixer widget (even unconnected ones) */
2941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
2942 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
2943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
2944 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
2945 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
2946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
2947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
2948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
2949
2950 { }
a9430dd8
JW
2951};
2952
0bfc90e9
JW
2953/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
2954 * similar laptops (adapted from Fujitsu init verbs).
2955 */
2956static struct hda_verb alc260_acer_init_verbs[] = {
2957 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
2958 * the headphone jack. Turn this on and rely on the standard mute
2959 * methods whenever the user wants to turn these outputs off.
2960 */
2961 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
2962 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
2963 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
2964 /* Internal speaker/Headphone jack is connected to Line-out pin */
2965 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2966 /* Internal microphone/Mic jack is connected to Mic1 pin */
2967 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2968 /* Line In jack is connected to Line1 pin */
2969 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2970 /* Ensure all other unused pins are disabled and muted. */
2971 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2972 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2973 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2974 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2975 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2976 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2979 /* Disable digital (SPDIF) pins */
2980 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
2981 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
2982
2983 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
2984 * bus when acting as outputs.
2985 */
2986 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
2987 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
2988
2989 /* Start with output sum widgets muted and their output gains at min */
2990 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2991 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2992 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2993 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2994 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2995 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2996 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2997 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2998 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2999
3000 /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
3001 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3002 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3003 * inputs. If the pin mode is changed by the user the pin mode control
3004 * will take care of enabling the pin's input/output buffers as needed.
3005 * Therefore there's no need to enable the input buffer at this
3006 * stage.
3007 */
3008 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3010
3011 /* Mute capture amp left and right */
3012 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3013 /* Set ADC connection select to match default mixer setting - mic
3014 * (on mic1 pin)
3015 */
3016 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3017
3018 /* Do similar with the second ADC: mute capture input amp and
3019 * set ADC connection to line (on line1 pin)
3020 */
3021 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3022 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3023
3024 /* Mute all inputs to mixer widget (even unconnected ones) */
3025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3026 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3028 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3029 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3030 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3031 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3032 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3033
3034 { }
3035};
3036
7cf51e48
JW
3037/* Test configuration for debugging, modelled after the ALC880 test
3038 * configuration.
3039 */
3040#ifdef CONFIG_SND_DEBUG
3041static hda_nid_t alc260_test_dac_nids[1] = {
3042 0x02,
3043};
3044static hda_nid_t alc260_test_adc_nids[2] = {
3045 0x04, 0x05,
3046};
17e7aec6
JW
3047/* This is a bit messy since the two input muxes in the ALC260 have slight
3048 * variations in their signal assignments. The ideal way to deal with this
3049 * is to extend alc_spec.input_mux to allow a different input MUX for each
3050 * ADC. For the purposes of the test model it's sufficient to just list
3051 * both options for affected signal indices. The separate input mux
3052 * functionality only needs to be considered if a model comes along which
3053 * actually uses signals 0x5, 0x6 and 0x7 for something which makes sense to
3054 * record.
3055 */
7cf51e48 3056static struct hda_input_mux alc260_test_capture_source = {
17e7aec6 3057 .num_items = 8,
7cf51e48
JW
3058 .items = {
3059 { "MIC1 pin", 0x0 },
3060 { "MIC2 pin", 0x1 },
3061 { "LINE1 pin", 0x2 },
3062 { "LINE2 pin", 0x3 },
3063 { "CD pin", 0x4 },
17e7aec6
JW
3064 { "LINE-OUT pin (cap1), Mixer (cap2)", 0x5 },
3065 { "HP-OUT pin (cap1), LINE-OUT pin (cap2)", 0x6 },
3066 { "HP-OUT pin (cap2 only)", 0x7 },
7cf51e48
JW
3067 },
3068};
3069static struct snd_kcontrol_new alc260_test_mixer[] = {
3070 /* Output driver widgets */
3071 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3072 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3073 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3074 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
3075 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3076 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3077
3078 /* Modes for retasking pin widgets */
3079 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
3080 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
3081 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
3082 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
3083 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
3084 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
3085
3086 /* Loopback mixer controls */
3087 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
3088 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
3089 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
3090 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
3091 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
3092 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
3093 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
3094 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
3095 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3096 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3097 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3098 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3099 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
3100 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
3101 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
3102 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
3103
3104 /* Controls for GPIO pins, assuming they are configured as outputs */
3105 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
3106 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
3107 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
3108 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
3109
92621f13
JW
3110 /* Switches to allow the digital IO pins to be enabled. The datasheet
3111 * is ambigious as to which NID is which; testing on laptops which
3112 * make this output available should provide clarification.
3113 */
3114 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
3115 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
3116
7cf51e48
JW
3117 { } /* end */
3118};
3119static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
3120 /* Enable all GPIOs as outputs with an initial value of 0 */
3121 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
3122 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
3123 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
3124
7cf51e48
JW
3125 /* Enable retasking pins as output, initially without power amp */
3126 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3127 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3128 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3129 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3130 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3132
92621f13
JW
3133 /* Disable digital (SPDIF) pins initially, but users can enable
3134 * them via a mixer switch. In the case of SPDIF-out, this initverb
3135 * payload also sets the generation to 0, output to be in "consumer"
3136 * PCM format, copyright asserted, no pre-emphasis and no validity
3137 * control.
3138 */
7cf51e48
JW
3139 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3140 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3141
f7ace40d 3142 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
3143 * OUT1 sum bus when acting as an output.
3144 */
3145 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3146 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
3147 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3148 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
3149
3150 /* Start with output sum widgets muted and their output gains at min */
3151 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3153 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3154 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3155 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3156 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3157 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3158 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3159 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3160
cdcd9268
JW
3161 /* Unmute retasking pin widget output buffers since the default
3162 * state appears to be output. As the pin mode is changed by the
3163 * user the pin mode control will take care of enabling the pin's
3164 * input/output buffers as needed.
3165 */
7cf51e48
JW
3166 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3168 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3170 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3171 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3172 /* Also unmute the mono-out pin widget */
3173 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3174
7cf51e48
JW
3175 /* Mute capture amp left and right */
3176 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
3177 /* Set ADC connection select to match default mixer setting (mic1
3178 * pin)
7cf51e48
JW
3179 */
3180 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3181
3182 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 3183 * set ADC connection to mic1 pin
7cf51e48
JW
3184 */
3185 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3186 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3187
3188 /* Mute all inputs to mixer widget (even unconnected ones) */
3189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3197
3198 { }
3199};
3200#endif
3201
1da177e4
LT
3202static struct hda_pcm_stream alc260_pcm_analog_playback = {
3203 .substreams = 1,
3204 .channels_min = 2,
3205 .channels_max = 2,
1da177e4
LT
3206};
3207
3208static struct hda_pcm_stream alc260_pcm_analog_capture = {
3209 .substreams = 1,
3210 .channels_min = 2,
3211 .channels_max = 2,
1da177e4
LT
3212};
3213
a3bcba38
TI
3214#define alc260_pcm_digital_playback alc880_pcm_digital_playback
3215#define alc260_pcm_digital_capture alc880_pcm_digital_capture
3216
df694daa
KY
3217/*
3218 * for BIOS auto-configuration
3219 */
16ded525 3220
df694daa
KY
3221static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
3222 const char *pfx)
3223{
3224 hda_nid_t nid_vol;
3225 unsigned long vol_val, sw_val;
3226 char name[32];
3227 int err;
3228
3229 if (nid >= 0x0f && nid < 0x11) {
3230 nid_vol = nid - 0x7;
3231 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3232 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3233 } else if (nid == 0x11) {
3234 nid_vol = nid - 0x7;
3235 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
3236 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
3237 } else if (nid >= 0x12 && nid <= 0x15) {
3238 nid_vol = 0x08;
3239 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3240 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3241 } else
3242 return 0; /* N/A */
3243
3244 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3245 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
3246 return err;
3247 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
3248 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
3249 return err;
3250 return 1;
3251}
3252
3253/* add playback controls from the parsed DAC table */
3254static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
3255 const struct auto_pin_cfg *cfg)
3256{
3257 hda_nid_t nid;
3258 int err;
3259
3260 spec->multiout.num_dacs = 1;
3261 spec->multiout.dac_nids = spec->private_dac_nids;
3262 spec->multiout.dac_nids[0] = 0x02;
3263
3264 nid = cfg->line_out_pins[0];
3265 if (nid) {
3266 err = alc260_add_playback_controls(spec, nid, "Front");
3267 if (err < 0)
3268 return err;
3269 }
3270
3271 nid = cfg->speaker_pin;
3272 if (nid) {
3273 err = alc260_add_playback_controls(spec, nid, "Speaker");
3274 if (err < 0)
3275 return err;
3276 }
3277
3278 nid = cfg->hp_pin;
3279 if (nid) {
3280 err = alc260_add_playback_controls(spec, nid, "Headphone");
3281 if (err < 0)
3282 return err;
3283 }
3284 return 0;
3285}
3286
3287/* create playback/capture controls for input pins */
3288static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
3289 const struct auto_pin_cfg *cfg)
3290{
df694daa
KY
3291 struct hda_input_mux *imux = &spec->private_imux;
3292 int i, err, idx;
3293
3294 for (i = 0; i < AUTO_PIN_LAST; i++) {
3295 if (cfg->input_pins[i] >= 0x12) {
3296 idx = cfg->input_pins[i] - 0x12;
4a471b7d
TI
3297 err = new_analog_input(spec, cfg->input_pins[i],
3298 auto_pin_cfg_labels[i], idx, 0x07);
df694daa
KY
3299 if (err < 0)
3300 return err;
4a471b7d 3301 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa
KY
3302 imux->items[imux->num_items].index = idx;
3303 imux->num_items++;
3304 }
3305 if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
3306 idx = cfg->input_pins[i] - 0x09;
4a471b7d
TI
3307 err = new_analog_input(spec, cfg->input_pins[i],
3308 auto_pin_cfg_labels[i], idx, 0x07);
df694daa
KY
3309 if (err < 0)
3310 return err;
4a471b7d 3311 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa
KY
3312 imux->items[imux->num_items].index = idx;
3313 imux->num_items++;
3314 }
3315 }
3316 return 0;
3317}
3318
3319static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
3320 hda_nid_t nid, int pin_type,
3321 int sel_idx)
3322{
3323 /* set as output */
3324 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
3325 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3326 /* need the manual connection? */
3327 if (nid >= 0x12) {
3328 int idx = nid - 0x12;
3329 snd_hda_codec_write(codec, idx + 0x0b, 0,
3330 AC_VERB_SET_CONNECT_SEL, sel_idx);
3331
3332 }
3333}
3334
3335static void alc260_auto_init_multi_out(struct hda_codec *codec)
3336{
3337 struct alc_spec *spec = codec->spec;
3338 hda_nid_t nid;
3339
3340 nid = spec->autocfg.line_out_pins[0];
3341 if (nid)
3342 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3343
3344 nid = spec->autocfg.speaker_pin;
3345 if (nid)
3346 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3347
3348 nid = spec->autocfg.hp_pin;
3349 if (nid)
3350 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3351}
3352
3353#define ALC260_PIN_CD_NID 0x16
3354static void alc260_auto_init_analog_input(struct hda_codec *codec)
3355{
3356 struct alc_spec *spec = codec->spec;
3357 int i;
3358
3359 for (i = 0; i < AUTO_PIN_LAST; i++) {
3360 hda_nid_t nid = spec->autocfg.input_pins[i];
3361 if (nid >= 0x12) {
3362 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3363 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
3364 if (nid != ALC260_PIN_CD_NID)
3365 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3366 AMP_OUT_MUTE);
3367 }
3368 }
3369}
3370
3371/*
3372 * generic initialization of ADC, input mixers and output mixers
3373 */
3374static struct hda_verb alc260_volume_init_verbs[] = {
3375 /*
3376 * Unmute ADC0-1 and set the default input to mic-in
3377 */
3378 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3379 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3380 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3381 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3382
3383 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3384 * mixer widget
3385 * Note: PASD motherboards uses the Line In 2 as the input for front panel
3386 * mic (mic 2)
3387 */
3388 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3391 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3393 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3394
3395 /*
3396 * Set up output mixers (0x08 - 0x0a)
3397 */
3398 /* set vol=0 to output mixers */
3399 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3400 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3401 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3402 /* set up input amps for analog loopback */
3403 /* Amp Indices: DAC = 0, mixer = 1 */
3404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3406 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3408 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3409 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3410
3411 { }
3412};
3413
3414static int alc260_parse_auto_config(struct hda_codec *codec)
3415{
3416 struct alc_spec *spec = codec->spec;
3417 unsigned int wcap;
3418 int err;
3419 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
3420
3421 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3422 alc260_ignore)) < 0)
3423 return err;
4a471b7d
TI
3424 if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
3425 return err;
3426 if (! spec->kctl_alloc)
df694daa 3427 return 0; /* can't find valid BIOS pin config */
4a471b7d 3428 if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
df694daa
KY
3429 return err;
3430
3431 spec->multiout.max_channels = 2;
3432
3433 if (spec->autocfg.dig_out_pin)
3434 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
3435 if (spec->kctl_alloc)
3436 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3437
3438 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
3439
3440 spec->input_mux = &spec->private_imux;
3441
3442 /* check whether NID 0x04 is valid */
4a471b7d 3443 wcap = get_wcaps(codec, 0x04);
df694daa
KY
3444 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3445 if (wcap != AC_WID_AUD_IN) {
3446 spec->adc_nids = alc260_adc_nids_alt;
3447 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
3448 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
3449 } else {
3450 spec->adc_nids = alc260_adc_nids;
3451 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
3452 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 3453 }
4a471b7d 3454 spec->num_mixers++;
df694daa
KY
3455
3456 return 1;
3457}
3458
3459/* init callback for auto-configuration model -- overriding the default init */
3460static int alc260_auto_init(struct hda_codec *codec)
3461{
3462 alc_init(codec);
3463 alc260_auto_init_multi_out(codec);
3464 alc260_auto_init_analog_input(codec);
3465 return 0;
3466}
3467
3468/*
3469 * ALC260 configurations
3470 */
3471static struct hda_board_config alc260_cfg_tbl[] = {
3472 { .modelname = "basic", .config = ALC260_BASIC },
b14e77e6
TI
3473 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
3474 .config = ALC260_BASIC }, /* Sony VAIO */
df694daa
KY
3475 { .modelname = "hp", .config = ALC260_HP },
3476 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
3477 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
3478 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP },
3479 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
3480 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
3481 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
3482 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
3483 { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
3484 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
0bfc90e9
JW
3485 { .modelname = "acer", .config = ALC260_ACER },
3486 { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER },
7cf51e48
JW
3487#ifdef CONFIG_SND_DEBUG
3488 { .modelname = "test", .config = ALC260_TEST },
3489#endif
df694daa
KY
3490 { .modelname = "auto", .config = ALC260_AUTO },
3491 {}
3492};
3493
3494static struct alc_config_preset alc260_presets[] = {
3495 [ALC260_BASIC] = {
3496 .mixers = { alc260_base_output_mixer,
3497 alc260_input_mixer,
3498 alc260_pc_beep_mixer,
3499 alc260_capture_mixer },
3500 .init_verbs = { alc260_init_verbs },
3501 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3502 .dac_nids = alc260_dac_nids,
3503 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
3504 .adc_nids = alc260_adc_nids,
3505 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3506 .channel_mode = alc260_modes,
3507 .input_mux = &alc260_capture_source,
3508 },
3509 [ALC260_HP] = {
3510 .mixers = { alc260_base_output_mixer,
3511 alc260_input_mixer,
3512 alc260_capture_alt_mixer },
3513 .init_verbs = { alc260_hp_init_verbs },
3514 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3515 .dac_nids = alc260_dac_nids,
3516 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
3517 .adc_nids = alc260_hp_adc_nids,
3518 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3519 .channel_mode = alc260_modes,
3520 .input_mux = &alc260_capture_source,
3521 },
3522 [ALC260_HP_3013] = {
3523 .mixers = { alc260_hp_3013_mixer,
3524 alc260_input_mixer,
3525 alc260_capture_alt_mixer },
3526 .init_verbs = { alc260_hp_3013_init_verbs },
3527 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3528 .dac_nids = alc260_dac_nids,
3529 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
3530 .adc_nids = alc260_hp_adc_nids,
3531 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3532 .channel_mode = alc260_modes,
3533 .input_mux = &alc260_capture_source,
3534 },
3535 [ALC260_FUJITSU_S702X] = {
3536 .mixers = { alc260_fujitsu_mixer,
3537 alc260_capture_mixer },
3538 .init_verbs = { alc260_fujitsu_init_verbs },
3539 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3540 .dac_nids = alc260_dac_nids,
d57fdac0
JW
3541 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
3542 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
3543 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3544 .channel_mode = alc260_modes,
3545 .input_mux = &alc260_fujitsu_capture_source,
3546 },
0bfc90e9
JW
3547 [ALC260_ACER] = {
3548 .mixers = { alc260_acer_mixer,
3549 alc260_capture_mixer },
3550 .init_verbs = { alc260_acer_init_verbs },
3551 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3552 .dac_nids = alc260_dac_nids,
3553 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
3554 .adc_nids = alc260_dual_adc_nids,
3555 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3556 .channel_mode = alc260_modes,
3557 .input_mux = &alc260_acer_capture_source,
3558 },
7cf51e48
JW
3559#ifdef CONFIG_SND_DEBUG
3560 [ALC260_TEST] = {
3561 .mixers = { alc260_test_mixer,
3562 alc260_capture_mixer },
3563 .init_verbs = { alc260_test_init_verbs },
3564 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
3565 .dac_nids = alc260_test_dac_nids,
3566 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
3567 .adc_nids = alc260_test_adc_nids,
3568 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3569 .channel_mode = alc260_modes,
3570 .input_mux = &alc260_test_capture_source,
3571 },
3572#endif
df694daa
KY
3573};
3574
3575static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
3576{
3577 struct alc_spec *spec;
df694daa 3578 int err, board_config;
1da177e4 3579
e560d8d8 3580 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3581 if (spec == NULL)
3582 return -ENOMEM;
3583
3584 codec->spec = spec;
3585
16ded525
TI
3586 board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
3587 if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
3588 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
df694daa 3589 board_config = ALC260_AUTO;
16ded525 3590 }
1da177e4 3591
df694daa
KY
3592 if (board_config == ALC260_AUTO) {
3593 /* automatic parse from the BIOS config */
3594 err = alc260_parse_auto_config(codec);
3595 if (err < 0) {
3596 alc_free(codec);
3597 return err;
3598 } else if (! err) {
3599 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n");
3600 board_config = ALC260_BASIC;
3601 }
a9430dd8 3602 }
e9edcee0 3603
df694daa
KY
3604 if (board_config != ALC260_AUTO)
3605 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
3606
3607 spec->stream_name_analog = "ALC260 Analog";
3608 spec->stream_analog_playback = &alc260_pcm_analog_playback;
3609 spec->stream_analog_capture = &alc260_pcm_analog_capture;
3610
a3bcba38
TI
3611 spec->stream_name_digital = "ALC260 Digital";
3612 spec->stream_digital_playback = &alc260_pcm_digital_playback;
3613 spec->stream_digital_capture = &alc260_pcm_digital_capture;
3614
1da177e4 3615 codec->patch_ops = alc_patch_ops;
df694daa
KY
3616 if (board_config == ALC260_AUTO)
3617 codec->patch_ops.init = alc260_auto_init;
1da177e4
LT
3618
3619 return 0;
3620}
3621
e9edcee0 3622
1da177e4
LT
3623/*
3624 * ALC882 support
3625 *
3626 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
3627 * configuration. Each pin widget can choose any input DACs and a mixer.
3628 * Each ADC is connected from a mixer of all inputs. This makes possible
3629 * 6-channel independent captures.
3630 *
3631 * In addition, an independent DAC for the multi-playback (not used in this
3632 * driver yet).
3633 */
df694daa
KY
3634#define ALC882_DIGOUT_NID 0x06
3635#define ALC882_DIGIN_NID 0x0a
1da177e4 3636
d2a6d7dc 3637static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
3638 { 8, NULL }
3639};
3640
3641static hda_nid_t alc882_dac_nids[4] = {
3642 /* front, rear, clfe, rear_surr */
3643 0x02, 0x03, 0x04, 0x05
3644};
3645
df694daa
KY
3646/* identical with ALC880 */
3647#define alc882_adc_nids alc880_adc_nids
3648#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4
LT
3649
3650/* input MUX */
3651/* FIXME: should be a matrix-type input source selection */
3652
3653static struct hda_input_mux alc882_capture_source = {
3654 .num_items = 4,
3655 .items = {
3656 { "Mic", 0x0 },
3657 { "Front Mic", 0x1 },
3658 { "Line", 0x2 },
3659 { "CD", 0x4 },
3660 },
3661};
3662
3663#define alc882_mux_enum_info alc_mux_enum_info
3664#define alc882_mux_enum_get alc_mux_enum_get
3665
c8b6bf9b 3666static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
3667{
3668 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3669 struct alc_spec *spec = codec->spec;
3670 const struct hda_input_mux *imux = spec->input_mux;
3671 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
3672 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
3673 hda_nid_t nid = capture_mixers[adc_idx];
3674 unsigned int *cur_val = &spec->cur_mux[adc_idx];
3675 unsigned int i, idx;
3676
3677 idx = ucontrol->value.enumerated.item[0];
3678 if (idx >= imux->num_items)
3679 idx = imux->num_items - 1;
3680 if (*cur_val == idx && ! codec->in_resume)
3681 return 0;
3682 for (i = 0; i < imux->num_items; i++) {
3683 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
3684 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3685 v | (imux->items[i].index << 8));
3686 }
3687 *cur_val = idx;
3688 return 1;
3689}
3690
df694daa
KY
3691/*
3692 * 6ch mode
3693 */
3694static struct hda_verb alc882_sixstack_ch6_init[] = {
3695 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
3696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3697 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3698 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3699 { } /* end */
3700};
3701
3702/*
3703 * 8ch mode
3704 */
3705static struct hda_verb alc882_sixstack_ch8_init[] = {
3706 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3707 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3708 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3709 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3710 { } /* end */
3711};
3712
3713static struct hda_channel_mode alc882_sixstack_modes[2] = {
3714 { 6, alc882_sixstack_ch6_init },
3715 { 8, alc882_sixstack_ch8_init },
3716};
3717
1da177e4
LT
3718/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
3719 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
3720 */
c8b6bf9b 3721static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 3722 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3723 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 3724 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3725 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
3726 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3727 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3728 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3729 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 3730 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 3731 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
3732 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3733 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3734 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3735 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3736 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3738 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3739 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3740 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3741 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
3742 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
3743 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
3744 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
3745 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
3746 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
3747 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
3748 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
3749 {
3750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3751 /* .name = "Capture Source", */
3752 .name = "Input Source",
3753 .count = 3,
3754 .info = alc882_mux_enum_info,
3755 .get = alc882_mux_enum_get,
3756 .put = alc882_mux_enum_put,
3757 },
3758 { } /* end */
3759};
3760
df694daa
KY
3761static struct snd_kcontrol_new alc882_chmode_mixer[] = {
3762 {
3763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3764 .name = "Channel Mode",
3765 .info = alc_ch_mode_info,
3766 .get = alc_ch_mode_get,
3767 .put = alc_ch_mode_put,
3768 },
3769 { } /* end */
3770};
3771
1da177e4
LT
3772static struct hda_verb alc882_init_verbs[] = {
3773 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
3774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 3777 /* Rear mixer */
05acb863
TI
3778 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3780 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 3781 /* CLFE mixer */
05acb863
TI
3782 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3783 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 3785 /* Side mixer */
05acb863
TI
3786 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3787 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3788 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 3789
e9edcee0 3790 /* Front Pin: output 0 (0x0c) */
05acb863 3791 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 3792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3793 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3794 /* Rear Pin: output 1 (0x0d) */
05acb863 3795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 3796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 3798 /* CLFE Pin: output 2 (0x0e) */
05acb863 3799 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 3800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3801 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 3802 /* Side Pin: output 3 (0x0f) */
05acb863 3803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 3804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3805 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 3806 /* Mic (rear) pin: input vref at 80% */
16ded525 3807 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
3808 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3809 /* Front Mic pin: input vref at 80% */
16ded525 3810 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
3811 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3812 /* Line In pin: input */
05acb863 3813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3815 /* Line-2 In: Headphone output (output 0 - 0x0c) */
3816 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3817 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 3819 /* CD pin widget for input */
05acb863 3820 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3821
3822 /* FIXME: use matrix-type input source selection */
3823 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
3824 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
3825 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3826 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3827 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3828 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 3829 /* Input mixer2 */
05acb863
TI
3830 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3831 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3832 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3833 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 3834 /* Input mixer3 */
05acb863
TI
3835 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3836 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3837 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3839 /* ADC1: mute amp left and right */
3840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3841 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3842 /* ADC2: mute amp left and right */
3843 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3844 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3845 /* ADC3: mute amp left and right */
3846 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3847 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
3848
3849 { }
3850};
3851
df694daa
KY
3852/*
3853 * generic initialization of ADC, input mixers and output mixers
3854 */
3855static struct hda_verb alc882_auto_init_verbs[] = {
3856 /*
3857 * Unmute ADC0-2 and set the default input to mic-in
3858 */
3859 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3861 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3862 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3863 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3864 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3865
df694daa
KY
3866 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3867 * mixer widget
3868 * Note: PASD motherboards uses the Line In 2 as the input for front panel
3869 * mic (mic 2)
3870 */
3871 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3873 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3874 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3875 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3876 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
e9edcee0 3877
df694daa
KY
3878 /*
3879 * Set up output mixers (0x0c - 0x0f)
3880 */
3881 /* set vol=0 to output mixers */
3882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3883 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3884 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3885 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3886 /* set up input amps for analog loopback */
3887 /* Amp Indices: DAC = 0, mixer = 1 */
3888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3890 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3891 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3893 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3895 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3896 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3897 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3898
3899 /* FIXME: use matrix-type input source selection */
3900 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
3901 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
3902 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3903 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3904 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3905 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3906 /* Input mixer2 */
3907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3908 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3909 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3910 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3911 /* Input mixer3 */
3912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3916
3917 { }
3918};
3919
3920/* capture mixer elements */
3921static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
3922 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3923 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3924 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
3925 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
3926 {
3927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3928 /* The multiple "Capture Source" controls confuse alsamixer
3929 * So call somewhat different..
3930 * FIXME: the controls appear in the "playback" view!
3931 */
3932 /* .name = "Capture Source", */
3933 .name = "Input Source",
3934 .count = 2,
3935 .info = alc882_mux_enum_info,
3936 .get = alc882_mux_enum_get,
3937 .put = alc882_mux_enum_put,
3938 },
3939 { } /* end */
3940};
3941
3942static struct snd_kcontrol_new alc882_capture_mixer[] = {
3943 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
3944 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
3945 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
3946 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
3947 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
3948 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
3949 {
3950 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3951 /* The multiple "Capture Source" controls confuse alsamixer
3952 * So call somewhat different..
3953 * FIXME: the controls appear in the "playback" view!
3954 */
3955 /* .name = "Capture Source", */
3956 .name = "Input Source",
3957 .count = 3,
3958 .info = alc882_mux_enum_info,
3959 .get = alc882_mux_enum_get,
3960 .put = alc882_mux_enum_put,
3961 },
3962 { } /* end */
3963};
3964
3965/* pcm configuration: identiacal with ALC880 */
3966#define alc882_pcm_analog_playback alc880_pcm_analog_playback
3967#define alc882_pcm_analog_capture alc880_pcm_analog_capture
3968#define alc882_pcm_digital_playback alc880_pcm_digital_playback
3969#define alc882_pcm_digital_capture alc880_pcm_digital_capture
3970
3971/*
3972 * configuration and preset
3973 */
3974static struct hda_board_config alc882_cfg_tbl[] = {
1494a92f
TI
3975 { .modelname = "3stack-dig", .config = ALC882_3ST_DIG },
3976 { .modelname = "6stack-dig", .config = ALC882_6ST_DIG },
df694daa
KY
3977 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI */
3978 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */
3979 { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */
1494a92f 3980 { .modelname = "auto", .config = ALC882_AUTO },
df694daa
KY
3981 {}
3982};
3983
3984static struct alc_config_preset alc882_presets[] = {
3985 [ALC882_3ST_DIG] = {
3986 .mixers = { alc882_base_mixer },
3987 .init_verbs = { alc882_init_verbs },
3988 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3989 .dac_nids = alc882_dac_nids,
3990 .dig_out_nid = ALC882_DIGOUT_NID,
3991 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3992 .adc_nids = alc882_adc_nids,
3993 .dig_in_nid = ALC882_DIGIN_NID,
3994 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3995 .channel_mode = alc882_ch_modes,
3996 .input_mux = &alc882_capture_source,
3997 },
3998 [ALC882_6ST_DIG] = {
3999 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
4000 .init_verbs = { alc882_init_verbs },
4001 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4002 .dac_nids = alc882_dac_nids,
4003 .dig_out_nid = ALC882_DIGOUT_NID,
4004 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4005 .adc_nids = alc882_adc_nids,
4006 .dig_in_nid = ALC882_DIGIN_NID,
4007 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4008 .channel_mode = alc882_sixstack_modes,
4009 .input_mux = &alc882_capture_source,
4010 },
4011};
4012
4013
4014/*
4015 * BIOS auto configuration
4016 */
4017static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
4018 hda_nid_t nid, int pin_type,
4019 int dac_idx)
4020{
4021 /* set as output */
4022 struct alc_spec *spec = codec->spec;
4023 int idx;
4024
4025 if (spec->multiout.dac_nids[dac_idx] == 0x25)
4026 idx = 4;
4027 else
4028 idx = spec->multiout.dac_nids[dac_idx] - 2;
4029
4030 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4031 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4032 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
4033
4034}
4035
4036static void alc882_auto_init_multi_out(struct hda_codec *codec)
4037{
4038 struct alc_spec *spec = codec->spec;
4039 int i;
4040
4041 for (i = 0; i <= HDA_SIDE; i++) {
4042 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4043 if (nid)
4044 alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
4045 }
4046}
4047
4048static void alc882_auto_init_hp_out(struct hda_codec *codec)
4049{
4050 struct alc_spec *spec = codec->spec;
4051 hda_nid_t pin;
4052
4053 pin = spec->autocfg.hp_pin;
4054 if (pin) /* connect to front */
4055 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
4056}
4057
4058#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
4059#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
4060
4061static void alc882_auto_init_analog_input(struct hda_codec *codec)
4062{
4063 struct alc_spec *spec = codec->spec;
4064 int i;
4065
4066 for (i = 0; i < AUTO_PIN_LAST; i++) {
4067 hda_nid_t nid = spec->autocfg.input_pins[i];
4068 if (alc882_is_input_pin(nid)) {
4069 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4070 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4071 if (nid != ALC882_PIN_CD_NID)
4072 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4073 AMP_OUT_MUTE);
4074 }
4075 }
4076}
4077
4078/* almost identical with ALC880 parser... */
4079static int alc882_parse_auto_config(struct hda_codec *codec)
4080{
4081 struct alc_spec *spec = codec->spec;
4082 int err = alc880_parse_auto_config(codec);
4083
4084 if (err < 0)
4085 return err;
c5f2ea08
TI
4086 else if (err > 0)
4087 /* hack - override the init verbs */
4088 spec->init_verbs[0] = alc882_auto_init_verbs;
4089 return err;
df694daa
KY
4090}
4091
4092/* init callback for auto-configuration model -- overriding the default init */
4093static int alc882_auto_init(struct hda_codec *codec)
4094{
4095 alc_init(codec);
4096 alc882_auto_init_multi_out(codec);
4097 alc882_auto_init_hp_out(codec);
4098 alc882_auto_init_analog_input(codec);
4099 return 0;
4100}
4101
4102/*
4103 * ALC882 Headphone poll in 3.5.1a or 3.5.2
4104 */
4105
4106static int patch_alc882(struct hda_codec *codec)
4107{
4108 struct alc_spec *spec;
4109 int err, board_config;
4110
4111 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4112 if (spec == NULL)
4113 return -ENOMEM;
4114
4115 codec->spec = spec;
4116
4117 board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl);
4118
4119 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
4120 printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n");
4121 board_config = ALC882_AUTO;
4122 }
4123
4124 if (board_config == ALC882_AUTO) {
4125 /* automatic parse from the BIOS config */
4126 err = alc882_parse_auto_config(codec);
4127 if (err < 0) {
4128 alc_free(codec);
4129 return err;
4130 } else if (! err) {
4131 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n");
4132 board_config = ALC882_3ST_DIG;
4133 }
4134 }
4135
4136 if (board_config != ALC882_AUTO)
4137 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
4138
4139 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
4140 spec->stream_analog_playback = &alc882_pcm_analog_playback;
4141 spec->stream_analog_capture = &alc882_pcm_analog_capture;
1da177e4
LT
4142
4143 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
4144 spec->stream_digital_playback = &alc882_pcm_digital_playback;
4145 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 4146
df694daa
KY
4147 if (! spec->adc_nids && spec->input_mux) {
4148 /* check whether NID 0x07 is valid */
4a471b7d 4149 unsigned int wcap = get_wcaps(codec, 0x07);
df694daa
KY
4150 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4151 if (wcap != AC_WID_AUD_IN) {
4152 spec->adc_nids = alc882_adc_nids_alt;
4153 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
4154 spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
4155 spec->num_mixers++;
4156 } else {
4157 spec->adc_nids = alc882_adc_nids;
4158 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
4159 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
4160 spec->num_mixers++;
4161 }
4162 }
1da177e4
LT
4163
4164 codec->patch_ops = alc_patch_ops;
df694daa
KY
4165 if (board_config == ALC882_AUTO)
4166 codec->patch_ops.init = alc882_auto_init;
4167
4168 return 0;
4169}
4170
4171/*
4172 * ALC262 support
4173 */
4174
4175#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
4176#define ALC262_DIGIN_NID ALC880_DIGIN_NID
4177
4178#define alc262_dac_nids alc260_dac_nids
4179#define alc262_adc_nids alc882_adc_nids
4180#define alc262_adc_nids_alt alc882_adc_nids_alt
4181
4182#define alc262_modes alc260_modes
c5f2ea08 4183#define alc262_capture_source alc882_capture_source
df694daa
KY
4184
4185static struct snd_kcontrol_new alc262_base_mixer[] = {
4186 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4187 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4188 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4189 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4190 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4191 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4193 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4196 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
4197 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
4198 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
4199 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4200 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4201 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
df694daa 4202 { } /* end */
834be88d
TI
4203};
4204
df694daa
KY
4205#define alc262_capture_mixer alc882_capture_mixer
4206#define alc262_capture_alt_mixer alc882_capture_alt_mixer
4207
4208/*
4209 * generic initialization of ADC, input mixers and output mixers
4210 */
4211static struct hda_verb alc262_init_verbs[] = {
4212 /*
4213 * Unmute ADC0-2 and set the default input to mic-in
4214 */
4215 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4217 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4219 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4220 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4221
4222 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4223 * mixer widget
4224 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4225 * mic (mic 2)
4226 */
4227 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4228 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4229 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4230 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4231 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4232 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4233
4234 /*
4235 * Set up output mixers (0x0c - 0x0e)
4236 */
4237 /* set vol=0 to output mixers */
4238 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4239 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4240 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4241 /* set up input amps for analog loopback */
4242 /* Amp Indices: DAC = 0, mixer = 1 */
4243 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4245 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4247 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4249
4250 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4251 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4252 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4253 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4254 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4255 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4256
4257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4260 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4261 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4262
4263 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4264 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4265
4266 /* FIXME: use matrix-type input source selection */
4267 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4268 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4269 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4270 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4271 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4272 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4273 /* Input mixer2 */
4274 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4275 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4276 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4277 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4278 /* Input mixer3 */
4279 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4280 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4281 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4282 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4283
4284 { }
4285};
1da177e4 4286
834be88d
TI
4287/*
4288 * fujitsu model
4289 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
4290 */
4291
4292#define ALC_HP_EVENT 0x37
4293
4294static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
4295 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
4296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4297 {}
4298};
4299
4300static struct hda_input_mux alc262_fujitsu_capture_source = {
4301 .num_items = 2,
4302 .items = {
4303 { "Mic", 0x0 },
4304 { "CD", 0x4 },
4305 },
4306};
4307
4308/* mute/unmute internal speaker according to the hp jack and mute state */
4309static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
4310{
4311 struct alc_spec *spec = codec->spec;
4312 unsigned int mute;
4313
4314 if (force || ! spec->sense_updated) {
4315 unsigned int present;
4316 /* need to execute and sync at first */
4317 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
4318 present = snd_hda_codec_read(codec, 0x14, 0,
4319 AC_VERB_GET_PIN_SENSE, 0);
4320 spec->jack_present = (present & 0x80000000) != 0;
4321 spec->sense_updated = 1;
4322 }
4323 if (spec->jack_present) {
4324 /* mute internal speaker */
4325 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
4326 0x80, 0x80);
4327 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
4328 0x80, 0x80);
4329 } else {
4330 /* unmute internal speaker if necessary */
4331 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
4332 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
4333 0x80, mute & 0x80);
4334 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
4335 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
4336 0x80, mute & 0x80);
4337 }
4338}
4339
4340/* unsolicited event for HP jack sensing */
4341static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
4342 unsigned int res)
4343{
4344 if ((res >> 26) != ALC_HP_EVENT)
4345 return;
4346 alc262_fujitsu_automute(codec, 1);
4347}
4348
4349/* bind volumes of both NID 0x0c and 0x0d */
4350static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
4351 struct snd_ctl_elem_value *ucontrol)
4352{
4353 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4354 long *valp = ucontrol->value.integer.value;
4355 int change;
4356
4357 change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
4358 0x7f, valp[0] & 0x7f);
4359 change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
4360 0x7f, valp[1] & 0x7f);
4361 snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
4362 0x7f, valp[0] & 0x7f);
4363 snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
4364 0x7f, valp[1] & 0x7f);
4365 return change;
4366}
4367
4368/* bind hp and internal speaker mute (with plug check) */
4369static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
4370 struct snd_ctl_elem_value *ucontrol)
4371{
4372 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4373 long *valp = ucontrol->value.integer.value;
4374 int change;
4375
4376 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
4377 0x80, valp[0] ? 0 : 0x80);
4378 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
4379 0x80, valp[1] ? 0 : 0x80);
4380 if (change || codec->in_resume)
4381 alc262_fujitsu_automute(codec, codec->in_resume);
4382 return change;
4383}
4384
4385static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
4386 {
4387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4388 .name = "Master Playback Volume",
4389 .info = snd_hda_mixer_amp_volume_info,
4390 .get = snd_hda_mixer_amp_volume_get,
4391 .put = alc262_fujitsu_master_vol_put,
4392 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
4393 },
4394 {
4395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4396 .name = "Master Playback Switch",
4397 .info = snd_hda_mixer_amp_switch_info,
4398 .get = snd_hda_mixer_amp_switch_get,
4399 .put = alc262_fujitsu_master_sw_put,
4400 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
4401 },
4402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4407 { } /* end */
4408};
4409
df694daa
KY
4410/* add playback controls from the parsed DAC table */
4411static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
4412{
4413 hda_nid_t nid;
4414 int err;
4415
4416 spec->multiout.num_dacs = 1; /* only use one dac */
4417 spec->multiout.dac_nids = spec->private_dac_nids;
4418 spec->multiout.dac_nids[0] = 2;
4419
4420 nid = cfg->line_out_pins[0];
4421 if (nid) {
4422 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
4423 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
4424 return err;
4425 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
4426 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4427 return err;
4428 }
4429
4430 nid = cfg->speaker_pin;
4431 if (nid) {
4432 if (nid == 0x16) {
4433 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
4434 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
4435 return err;
4436 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
4437 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4438 return err;
4439 } else {
4440 if (! cfg->line_out_pins[0])
4441 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
4442 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
4443 return err;
4444 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
4445 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4446 return err;
4447 }
4448 }
4449 nid = cfg->hp_pin;
4450 if (nid) {
4451 /* spec->multiout.hp_nid = 2; */
4452 if (nid == 0x16) {
4453 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
4454 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
4455 return err;
4456 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
4457 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4458 return err;
4459 } else {
4460 if (! cfg->line_out_pins[0])
4461 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
4462 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
4463 return err;
4464 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
4465 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4466 return err;
4467 }
4468 }
4469 return 0;
4470}
4471
4472/* identical with ALC880 */
4473#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
4474
4475/*
4476 * generic initialization of ADC, input mixers and output mixers
4477 */
4478static struct hda_verb alc262_volume_init_verbs[] = {
4479 /*
4480 * Unmute ADC0-2 and set the default input to mic-in
4481 */
4482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4484 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4486 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4488
4489 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4490 * mixer widget
4491 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4492 * mic (mic 2)
4493 */
4494 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4500
4501 /*
4502 * Set up output mixers (0x0c - 0x0f)
4503 */
4504 /* set vol=0 to output mixers */
4505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4508
4509 /* set up input amps for analog loopback */
4510 /* Amp Indices: DAC = 0, mixer = 1 */
4511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4517
4518 /* FIXME: use matrix-type input source selection */
4519 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4520 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4525 /* Input mixer2 */
4526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4530 /* Input mixer3 */
4531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4535
4536 { }
4537};
4538
4539/* pcm configuration: identiacal with ALC880 */
4540#define alc262_pcm_analog_playback alc880_pcm_analog_playback
4541#define alc262_pcm_analog_capture alc880_pcm_analog_capture
4542#define alc262_pcm_digital_playback alc880_pcm_digital_playback
4543#define alc262_pcm_digital_capture alc880_pcm_digital_capture
4544
4545/*
4546 * BIOS auto configuration
4547 */
4548static int alc262_parse_auto_config(struct hda_codec *codec)
4549{
4550 struct alc_spec *spec = codec->spec;
4551 int err;
4552 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
4553
4554 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4555 alc262_ignore)) < 0)
4556 return err;
4557 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
4558 ! spec->autocfg.hp_pin)
4559 return 0; /* can't find valid BIOS pin config */
4560 if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
4561 (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
4562 return err;
4563
4564 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4565
4566 if (spec->autocfg.dig_out_pin)
4567 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
4568 if (spec->autocfg.dig_in_pin)
4569 spec->dig_in_nid = ALC262_DIGIN_NID;
4570
4571 if (spec->kctl_alloc)
4572 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4573
4574 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
4575 spec->input_mux = &spec->private_imux;
4576
4577 return 1;
4578}
4579
4580#define alc262_auto_init_multi_out alc882_auto_init_multi_out
4581#define alc262_auto_init_hp_out alc882_auto_init_hp_out
4582#define alc262_auto_init_analog_input alc882_auto_init_analog_input
4583
4584
4585/* init callback for auto-configuration model -- overriding the default init */
4586static int alc262_auto_init(struct hda_codec *codec)
4587{
4588 alc_init(codec);
4589 alc262_auto_init_multi_out(codec);
4590 alc262_auto_init_hp_out(codec);
4591 alc262_auto_init_analog_input(codec);
4592 return 0;
4593}
4594
4595/*
4596 * configuration and preset
4597 */
4598static struct hda_board_config alc262_cfg_tbl[] = {
4599 { .modelname = "basic", .config = ALC262_BASIC },
834be88d
TI
4600 { .modelname = "fujitsu", .config = ALC262_FUJITSU },
4601 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU },
df694daa
KY
4602 { .modelname = "auto", .config = ALC262_AUTO },
4603 {}
4604};
4605
4606static struct alc_config_preset alc262_presets[] = {
4607 [ALC262_BASIC] = {
4608 .mixers = { alc262_base_mixer },
4609 .init_verbs = { alc262_init_verbs },
4610 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
4611 .dac_nids = alc262_dac_nids,
4612 .hp_nid = 0x03,
4613 .num_channel_mode = ARRAY_SIZE(alc262_modes),
4614 .channel_mode = alc262_modes,
a3bcba38 4615 .input_mux = &alc262_capture_source,
df694daa 4616 },
834be88d
TI
4617 [ALC262_FUJITSU] = {
4618 .mixers = { alc262_fujitsu_mixer },
4619 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
4620 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
4621 .dac_nids = alc262_dac_nids,
4622 .hp_nid = 0x03,
4623 .dig_out_nid = ALC262_DIGOUT_NID,
4624 .num_channel_mode = ARRAY_SIZE(alc262_modes),
4625 .channel_mode = alc262_modes,
4626 .input_mux = &alc262_fujitsu_capture_source,
4627 },
df694daa
KY
4628};
4629
4630static int patch_alc262(struct hda_codec *codec)
4631{
4632 struct alc_spec *spec;
4633 int board_config;
4634 int err;
4635
4636 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
4637 if (spec == NULL)
4638 return -ENOMEM;
4639
4640 codec->spec = spec;
4641#if 0
4642 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */
4643 {
4644 int tmp;
4645 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
4646 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
4647 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
4648 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
4649 }
4650#endif
4651
4652 board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl);
4653 if (board_config < 0 || board_config >= ALC262_MODEL_LAST) {
4654 printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n");
4655 board_config = ALC262_AUTO;
4656 }
4657
4658 if (board_config == ALC262_AUTO) {
4659 /* automatic parse from the BIOS config */
4660 err = alc262_parse_auto_config(codec);
4661 if (err < 0) {
4662 alc_free(codec);
4663 return err;
4664 } else if (! err) {
4665 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n");
4666 board_config = ALC262_BASIC;
4667 }
4668 }
4669
4670 if (board_config != ALC262_AUTO)
4671 setup_preset(spec, &alc262_presets[board_config]);
4672
4673 spec->stream_name_analog = "ALC262 Analog";
4674 spec->stream_analog_playback = &alc262_pcm_analog_playback;
4675 spec->stream_analog_capture = &alc262_pcm_analog_capture;
4676
4677 spec->stream_name_digital = "ALC262 Digital";
4678 spec->stream_digital_playback = &alc262_pcm_digital_playback;
4679 spec->stream_digital_capture = &alc262_pcm_digital_capture;
4680
4681 if (! spec->adc_nids && spec->input_mux) {
4682 /* check whether NID 0x07 is valid */
4a471b7d
TI
4683 unsigned int wcap = get_wcaps(codec, 0x07);
4684
df694daa
KY
4685 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4686 if (wcap != AC_WID_AUD_IN) {
4687 spec->adc_nids = alc262_adc_nids_alt;
4688 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
4689 spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
4690 spec->num_mixers++;
4691 } else {
4692 spec->adc_nids = alc262_adc_nids;
4693 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
4694 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
4695 spec->num_mixers++;
4696 }
4697 }
4698
4699 codec->patch_ops = alc_patch_ops;
4700 if (board_config == ALC262_AUTO)
4701 codec->patch_ops.init = alc262_auto_init;
834be88d
TI
4702 if (board_config == ALC262_FUJITSU)
4703 codec->patch_ops.unsol_event = alc262_fujitsu_unsol_event;
4704
df694daa
KY
4705 return 0;
4706}
4707
4708
4709/*
4710 * ALC861 channel source setting (2/6 channel selection for 3-stack)
4711 */
4712
4713/*
4714 * set the path ways for 2 channel output
4715 * need to set the codec line out and mic 1 pin widgets to inputs
4716 */
4717static struct hda_verb alc861_threestack_ch2_init[] = {
4718 /* set pin widget 1Ah (line in) for input */
4719 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4720 /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
4721 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4722
4723 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
4724 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic
4725 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in
4726 { } /* end */
4727};
4728/*
4729 * 6ch mode
4730 * need to set the codec line out and mic 1 pin widgets to outputs
4731 */
4732static struct hda_verb alc861_threestack_ch6_init[] = {
4733 /* set pin widget 1Ah (line in) for output (Back Surround)*/
4734 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4735 /* set pin widget 18h (mic1) for output (CLFE)*/
4736 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4737
4738 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
4739 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
4740
4741 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
4742 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic
4743 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in
4744 { } /* end */
4745};
4746
4747static struct hda_channel_mode alc861_threestack_modes[2] = {
4748 { 2, alc861_threestack_ch2_init },
4749 { 6, alc861_threestack_ch6_init },
4750};
4751
4752/* patch-ALC861 */
4753
4754static struct snd_kcontrol_new alc861_base_mixer[] = {
4755 /* output mixer control */
4756 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
4757 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
4758 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
4759 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
4760 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
4761
4762 /*Input mixer control */
4763 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
4764 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
4765 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
4766 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
4767 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
4768 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
4769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
4770 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
4771 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
4772 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
4773
4774 /* Capture mixer control */
4775 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4776 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4777 {
4778 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4779 .name = "Capture Source",
4780 .count = 1,
4781 .info = alc_mux_enum_info,
4782 .get = alc_mux_enum_get,
4783 .put = alc_mux_enum_put,
4784 },
4785 { } /* end */
4786};
4787
4788static struct snd_kcontrol_new alc861_3ST_mixer[] = {
4789 /* output mixer control */
4790 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
4791 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
4792 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
4793 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
4794 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
4795
4796 /* Input mixer control */
4797 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
4798 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
4799 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
4800 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
4801 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
4802 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
4803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
4804 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
4805 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
4806 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
4807
4808 /* Capture mixer control */
4809 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4810 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4811 {
4812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4813 .name = "Capture Source",
4814 .count = 1,
4815 .info = alc_mux_enum_info,
4816 .get = alc_mux_enum_get,
4817 .put = alc_mux_enum_put,
4818 },
4819 {
4820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4821 .name = "Channel Mode",
4822 .info = alc_ch_mode_info,
4823 .get = alc_ch_mode_get,
4824 .put = alc_ch_mode_put,
4825 .private_value = ARRAY_SIZE(alc861_threestack_modes),
4826 },
4827 { } /* end */
4828};
4829
4830/*
4831 * generic initialization of ADC, input mixers and output mixers
4832 */
4833static struct hda_verb alc861_base_init_verbs[] = {
4834 /*
4835 * Unmute ADC0 and set the default input to mic-in
4836 */
4837 /* port-A for surround (rear panel) */
4838 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4839 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
4840 /* port-B for mic-in (rear panel) with vref */
4841 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4842 /* port-C for line-in (rear panel) */
4843 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4844 /* port-D for Front */
4845 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4846 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
4847 /* port-E for HP out (front panel) */
4848 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
4849 /* route front PCM to HP */
4850 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
4851 /* port-F for mic-in (front panel) with vref */
4852 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4853 /* port-G for CLFE (rear panel) */
4854 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4855 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
4856 /* port-H for side (rear panel) */
4857 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4858 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
4859 /* CD-in */
4860 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4861 /* route front mic to ADC1*/
4862 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4863 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4864
4865 /* Unmute DAC0~3 & spdif out*/
4866 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4867 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4868 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4869 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4871
4872 /* Unmute Mixer 14 (mic) 1c (Line in)*/
4873 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4874 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4875 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4876 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4877
4878 /* Unmute Stereo Mixer 15 */
4879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4880 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4881 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4882 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step
4883
4884 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4885 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4886 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4887 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4888 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4889 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4890 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4891 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
4893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4894
4895 { }
4896};
4897
4898static struct hda_verb alc861_threestack_init_verbs[] = {
4899 /*
4900 * Unmute ADC0 and set the default input to mic-in
4901 */
4902 /* port-A for surround (rear panel) */
4903 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4904 /* port-B for mic-in (rear panel) with vref */
4905 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4906 /* port-C for line-in (rear panel) */
4907 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4908 /* port-D for Front */
4909 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4910 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
4911 /* port-E for HP out (front panel) */
4912 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
4913 /* route front PCM to HP */
4914 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
4915 /* port-F for mic-in (front panel) with vref */
4916 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4917 /* port-G for CLFE (rear panel) */
4918 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4919 /* port-H for side (rear panel) */
4920 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4921 /* CD-in */
4922 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4923 /* route front mic to ADC1*/
4924 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4925 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4926 /* Unmute DAC0~3 & spdif out*/
4927 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4928 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4929 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4930 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4931 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4932
4933 /* Unmute Mixer 14 (mic) 1c (Line in)*/
4934 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4935 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4936 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4937 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4938
4939 /* Unmute Stereo Mixer 15 */
4940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4941 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4942 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4943 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step
4944
4945 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4946 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4947 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4949 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4950 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4951 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4952 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4953 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
4954 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4955 { }
4956};
4957/*
4958 * generic initialization of ADC, input mixers and output mixers
4959 */
4960static struct hda_verb alc861_auto_init_verbs[] = {
4961 /*
4962 * Unmute ADC0 and set the default input to mic-in
4963 */
4964// {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4965 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4966
4967 /* Unmute DAC0~3 & spdif out*/
4968 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4969 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4970 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4971 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4973
4974 /* Unmute Mixer 14 (mic) 1c (Line in)*/
4975 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4976 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4977 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4978 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4979
4980 /* Unmute Stereo Mixer 15 */
4981 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
4985
4986 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4987 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4988 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4989 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4990 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4991 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4992 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4993 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4994
4995 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4996 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4997 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4998 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4999 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5000 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5001 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5003
5004 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1
5005
5006 { }
5007};
5008
5009/* pcm configuration: identiacal with ALC880 */
5010#define alc861_pcm_analog_playback alc880_pcm_analog_playback
5011#define alc861_pcm_analog_capture alc880_pcm_analog_capture
5012#define alc861_pcm_digital_playback alc880_pcm_digital_playback
5013#define alc861_pcm_digital_capture alc880_pcm_digital_capture
5014
5015
5016#define ALC861_DIGOUT_NID 0x07
5017
5018static struct hda_channel_mode alc861_8ch_modes[1] = {
5019 { 8, NULL }
5020};
5021
5022static hda_nid_t alc861_dac_nids[4] = {
5023 /* front, surround, clfe, side */
5024 0x03, 0x06, 0x05, 0x04
5025};
5026
5027static hda_nid_t alc861_adc_nids[1] = {
5028 /* ADC0-2 */
5029 0x08,
5030};
5031
5032static struct hda_input_mux alc861_capture_source = {
5033 .num_items = 5,
5034 .items = {
5035 { "Mic", 0x0 },
5036 { "Front Mic", 0x3 },
5037 { "Line", 0x1 },
5038 { "CD", 0x4 },
5039 { "Mixer", 0x5 },
5040 },
5041};
5042
5043/* fill in the dac_nids table from the parsed pin configuration */
5044static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
5045{
5046 int i;
5047 hda_nid_t nid;
5048
5049 spec->multiout.dac_nids = spec->private_dac_nids;
5050 for (i = 0; i < cfg->line_outs; i++) {
5051 nid = cfg->line_out_pins[i];
5052 if (nid) {
5053 if (i >= ARRAY_SIZE(alc861_dac_nids))
5054 continue;
5055 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
5056 }
5057 }
5058 spec->multiout.num_dacs = cfg->line_outs;
5059 return 0;
5060}
5061
5062/* add playback controls from the parsed DAC table */
5063static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
5064 const struct auto_pin_cfg *cfg)
5065{
5066 char name[32];
5067 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
5068 hda_nid_t nid;
5069 int i, idx, err;
5070
5071 for (i = 0; i < cfg->line_outs; i++) {
5072 nid = spec->multiout.dac_nids[i];
5073 if (! nid)
5074 continue;
5075 if (nid == 0x05) {
5076 /* Center/LFE */
5077 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
5078 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
5079 return err;
5080 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
5081 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
5082 return err;
5083 } else {
5084 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
5085 if (nid == alc861_dac_nids[idx])
5086 break;
5087 sprintf(name, "%s Playback Switch", chname[idx]);
5088 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
5089 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
5090 return err;
5091 }
5092 }
5093 return 0;
5094}
5095
5096static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
5097{
5098 int err;
5099 hda_nid_t nid;
5100
5101 if (! pin)
5102 return 0;
5103
5104 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
5105 nid = 0x03;
5106 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
5107 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
5108 return err;
5109 spec->multiout.hp_nid = nid;
5110 }
5111 return 0;
5112}
5113
5114/* create playback/capture controls for input pins */
5115static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
5116{
df694daa
KY
5117 struct hda_input_mux *imux = &spec->private_imux;
5118 int i, err, idx, idx1;
5119
5120 for (i = 0; i < AUTO_PIN_LAST; i++) {
5121 switch(cfg->input_pins[i]) {
5122 case 0x0c:
5123 idx1 = 1;
5124 idx = 2; // Line In
5125 break;
5126 case 0x0f:
5127 idx1 = 2;
5128 idx = 2; // Line In
5129 break;
5130 case 0x0d:
5131 idx1 = 0;
5132 idx = 1; // Mic In
5133 break;
5134 case 0x10:
5135 idx1 = 3;
5136 idx = 1; // Mic In
5137 break;
5138 case 0x11:
5139 idx1 = 4;
5140 idx = 0; // CD
5141 break;
5142 default:
5143 continue;
5144 }
5145
4a471b7d
TI
5146 err = new_analog_input(spec, cfg->input_pins[i],
5147 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
5148 if (err < 0)
5149 return err;
5150
4a471b7d 5151 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa
KY
5152 imux->items[imux->num_items].index = idx1;
5153 imux->num_items++;
5154 }
5155 return 0;
5156}
5157
5158static struct snd_kcontrol_new alc861_capture_mixer[] = {
5159 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5160 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5161
5162 {
5163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5164 /* The multiple "Capture Source" controls confuse alsamixer
5165 * So call somewhat different..
5166 *FIXME: the controls appear in the "playback" view!
5167 */
5168 /* .name = "Capture Source", */
5169 .name = "Input Source",
5170 .count = 1,
5171 .info = alc_mux_enum_info,
5172 .get = alc_mux_enum_get,
5173 .put = alc_mux_enum_put,
5174 },
5175 { } /* end */
5176};
5177
5178static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
5179 int pin_type, int dac_idx)
5180{
5181 /* set as output */
5182
5183 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
5184 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5185
5186}
5187
5188static void alc861_auto_init_multi_out(struct hda_codec *codec)
5189{
5190 struct alc_spec *spec = codec->spec;
5191 int i;
5192
5193 for (i = 0; i < spec->autocfg.line_outs; i++) {
5194 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5195 if (nid)
5196 alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
5197 }
5198}
5199
5200static void alc861_auto_init_hp_out(struct hda_codec *codec)
5201{
5202 struct alc_spec *spec = codec->spec;
5203 hda_nid_t pin;
5204
5205 pin = spec->autocfg.hp_pin;
5206 if (pin) /* connect to front */
5207 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
5208}
5209
5210static void alc861_auto_init_analog_input(struct hda_codec *codec)
5211{
5212 struct alc_spec *spec = codec->spec;
5213 int i;
5214
5215 for (i = 0; i < AUTO_PIN_LAST; i++) {
5216 hda_nid_t nid = spec->autocfg.input_pins[i];
5217 if ((nid>=0x0c) && (nid <=0x11)) {
5218 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5219 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
5220 }
5221 }
5222}
5223
5224/* parse the BIOS configuration and set up the alc_spec */
5225/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
5226static int alc861_parse_auto_config(struct hda_codec *codec)
5227{
5228 struct alc_spec *spec = codec->spec;
5229 int err;
5230 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
5231
5232 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5233 alc861_ignore)) < 0)
5234 return err;
5235 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
5236 ! spec->autocfg.hp_pin)
5237 return 0; /* can't find valid BIOS pin config */
5238
5239 if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
5240 (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
5241 (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
5242 (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
5243 return err;
5244
5245 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5246
5247 if (spec->autocfg.dig_out_pin)
5248 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
5249
5250 if (spec->kctl_alloc)
5251 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5252
5253 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
5254
5255 spec->input_mux = &spec->private_imux;
5256
5257 spec->adc_nids = alc861_adc_nids;
5258 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
5259 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
5260 spec->num_mixers++;
5261
5262 return 1;
5263}
5264
5265/* init callback for auto-configuration model -- overriding the default init */
5266static int alc861_auto_init(struct hda_codec *codec)
5267{
5268 alc_init(codec);
5269 alc861_auto_init_multi_out(codec);
5270 alc861_auto_init_hp_out(codec);
5271 alc861_auto_init_analog_input(codec);
5272
5273 return 0;
5274}
5275
5276
5277/*
5278 * configuration and preset
5279 */
5280static struct hda_board_config alc861_cfg_tbl[] = {
5281 { .modelname = "3stack", .config = ALC861_3ST },
5282 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST },
5283 { .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
5284 { .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
5285 { .modelname = "auto", .config = ALC861_AUTO },
5286 {}
5287};
5288
5289static struct alc_config_preset alc861_presets[] = {
5290 [ALC861_3ST] = {
5291 .mixers = { alc861_3ST_mixer },
5292 .init_verbs = { alc861_threestack_init_verbs },
5293 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
5294 .dac_nids = alc861_dac_nids,
5295 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
5296 .channel_mode = alc861_threestack_modes,
5297 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
5298 .adc_nids = alc861_adc_nids,
5299 .input_mux = &alc861_capture_source,
5300 },
5301 [ALC861_3ST_DIG] = {
5302 .mixers = { alc861_base_mixer },
5303 .init_verbs = { alc861_threestack_init_verbs },
5304 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
5305 .dac_nids = alc861_dac_nids,
5306 .dig_out_nid = ALC861_DIGOUT_NID,
5307 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
5308 .channel_mode = alc861_threestack_modes,
5309 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
5310 .adc_nids = alc861_adc_nids,
5311 .input_mux = &alc861_capture_source,
5312 },
5313 [ALC861_6ST_DIG] = {
5314 .mixers = { alc861_base_mixer },
5315 .init_verbs = { alc861_base_init_verbs },
5316 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
5317 .dac_nids = alc861_dac_nids,
5318 .dig_out_nid = ALC861_DIGOUT_NID,
5319 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
5320 .channel_mode = alc861_8ch_modes,
5321 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
5322 .adc_nids = alc861_adc_nids,
5323 .input_mux = &alc861_capture_source,
5324 },
5325};
5326
5327
5328static int patch_alc861(struct hda_codec *codec)
5329{
5330 struct alc_spec *spec;
5331 int board_config;
5332 int err;
5333
5334 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
5335 if (spec == NULL)
5336 return -ENOMEM;
5337
5338 codec->spec = spec;
5339
5340 board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);
5341 if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {
5342 printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n");
5343 board_config = ALC861_AUTO;
5344 }
5345
5346 if (board_config == ALC861_AUTO) {
5347 /* automatic parse from the BIOS config */
5348 err = alc861_parse_auto_config(codec);
5349 if (err < 0) {
5350 alc_free(codec);
5351 return err;
5352 } else if (! err) {
5353 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n");
5354 board_config = ALC861_3ST_DIG;
5355 }
5356 }
5357
5358 if (board_config != ALC861_AUTO)
5359 setup_preset(spec, &alc861_presets[board_config]);
5360
5361 spec->stream_name_analog = "ALC861 Analog";
5362 spec->stream_analog_playback = &alc861_pcm_analog_playback;
5363 spec->stream_analog_capture = &alc861_pcm_analog_capture;
5364
5365 spec->stream_name_digital = "ALC861 Digital";
5366 spec->stream_digital_playback = &alc861_pcm_digital_playback;
5367 spec->stream_digital_capture = &alc861_pcm_digital_capture;
5368
5369 codec->patch_ops = alc_patch_ops;
5370 if (board_config == ALC861_AUTO)
5371 codec->patch_ops.init = alc861_auto_init;
5372
1da177e4
LT
5373 return 0;
5374}
5375
5376/*
5377 * patch entries
5378 */
5379struct hda_codec_preset snd_hda_preset_realtek[] = {
5380 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 5381 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
1da177e4
LT
5382 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
5383 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
df694daa
KY
5384 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
5385 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
5386 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
1da177e4
LT
5387 {} /* terminator */
5388};