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