2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
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.
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.
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
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_patch.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
81 #ifdef CONFIG_SND_DEBUG
85 ALC260_MODEL_LAST /* last tag */
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
107 ALC262_MODEL_LAST /* last tag */
116 ALC268_ACER_ASPIRE_ONE,
119 #ifdef CONFIG_SND_DEBUG
123 ALC268_MODEL_LAST /* last tag */
130 ALC269_ASUS_EEEPC_P703,
131 ALC269_ASUS_EEEPC_P901,
133 ALC269_MODEL_LAST /* last tag */
150 /* ALC861-VD models */
171 ALC662_ASUS_EEEPC_P701,
172 ALC662_ASUS_EEEPC_EP20,
204 ALC883_TARGA_2ch_DIG,
210 ALC883_LENOVO_101E_2ch,
211 ALC883_LENOVO_NB0763,
212 ALC888_LENOVO_MS7195_DIG,
219 ALC883_FUJITSU_PI2515,
220 ALC883_3ST_6ch_INTEL,
228 #define GPIO_MASK 0x03
231 /* codec parameterization */
232 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
233 unsigned int num_mixers;
235 const struct hda_verb *init_verbs[5]; /* initialization verbs
239 unsigned int num_init_verbs;
241 char *stream_name_analog; /* analog PCM stream */
242 struct hda_pcm_stream *stream_analog_playback;
243 struct hda_pcm_stream *stream_analog_capture;
244 struct hda_pcm_stream *stream_analog_alt_playback;
245 struct hda_pcm_stream *stream_analog_alt_capture;
247 char *stream_name_digital; /* digital PCM stream */
248 struct hda_pcm_stream *stream_digital_playback;
249 struct hda_pcm_stream *stream_digital_capture;
252 struct hda_multi_out multiout; /* playback set-up
253 * max_channels, dacs must be set
254 * dig_out_nid and hp_nid are optional
256 hda_nid_t alt_dac_nid;
259 unsigned int num_adc_nids;
261 hda_nid_t *capsrc_nids;
262 hda_nid_t dig_in_nid; /* digital-in NID; optional */
265 unsigned int num_mux_defs;
266 const struct hda_input_mux *input_mux;
267 unsigned int cur_mux[3];
270 const struct hda_channel_mode *channel_mode;
271 int num_channel_mode;
274 /* PCM information */
275 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
277 /* dynamic controls, init_verbs and input_mux */
278 struct auto_pin_cfg autocfg;
279 unsigned int num_kctl_alloc, num_kctl_used;
280 struct snd_kcontrol_new *kctl_alloc;
281 struct hda_input_mux private_imux;
282 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
285 void (*init_hook)(struct hda_codec *codec);
286 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
288 /* for pin sensing */
289 unsigned int sense_updated: 1;
290 unsigned int jack_present: 1;
291 unsigned int master_sw: 1;
293 /* for virtual master */
294 hda_nid_t vmaster_nid;
295 #ifdef CONFIG_SND_HDA_POWER_SAVE
296 struct hda_loopback_check loopback;
301 unsigned int pll_coef_idx, pll_coef_bit;
305 * configuration template - to be copied to the spec instance
307 struct alc_config_preset {
308 struct snd_kcontrol_new *mixers[5]; /* should be identical size
311 const struct hda_verb *init_verbs[5];
312 unsigned int num_dacs;
314 hda_nid_t dig_out_nid; /* optional */
315 hda_nid_t hp_nid; /* optional */
316 unsigned int num_adc_nids;
318 hda_nid_t *capsrc_nids;
319 hda_nid_t dig_in_nid;
320 unsigned int num_channel_mode;
321 const struct hda_channel_mode *channel_mode;
323 unsigned int num_mux_defs;
324 const struct hda_input_mux *input_mux;
325 void (*unsol_event)(struct hda_codec *, unsigned int);
326 void (*init_hook)(struct hda_codec *);
327 #ifdef CONFIG_SND_HDA_POWER_SAVE
328 struct hda_amp_list *loopbacks;
336 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_info *uinfo)
339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
340 struct alc_spec *spec = codec->spec;
341 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
342 if (mux_idx >= spec->num_mux_defs)
344 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
347 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
348 struct snd_ctl_elem_value *ucontrol)
350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
351 struct alc_spec *spec = codec->spec;
352 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
354 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
358 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
361 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362 struct alc_spec *spec = codec->spec;
363 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
364 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
365 hda_nid_t nid = spec->capsrc_nids ?
366 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
367 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
368 nid, &spec->cur_mux[adc_idx]);
373 * channel mode setting
375 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_info *uinfo)
378 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
379 struct alc_spec *spec = codec->spec;
380 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
381 spec->num_channel_mode);
384 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
385 struct snd_ctl_elem_value *ucontrol)
387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
388 struct alc_spec *spec = codec->spec;
389 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
390 spec->num_channel_mode,
391 spec->multiout.max_channels);
394 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
398 struct alc_spec *spec = codec->spec;
399 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
400 spec->num_channel_mode,
401 &spec->multiout.max_channels);
402 if (err >= 0 && spec->need_dac_fix)
403 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
408 * Control the mode of pin widget settings via the mixer. "pc" is used
409 * instead of "%" to avoid consequences of accidently treating the % as
410 * being part of a format specifier. Maximum allowed length of a value is
411 * 63 characters plus NULL terminator.
413 * Note: some retasking pin complexes seem to ignore requests for input
414 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
415 * are requested. Therefore order this list so that this behaviour will not
416 * cause problems when mixer clients move through the enum sequentially.
417 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
420 static char *alc_pin_mode_names[] = {
421 "Mic 50pc bias", "Mic 80pc bias",
422 "Line in", "Line out", "Headphone out",
424 static unsigned char alc_pin_mode_values[] = {
425 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
427 /* The control can present all 5 options, or it can limit the options based
428 * in the pin being assumed to be exclusively an input or an output pin. In
429 * addition, "input" pins may or may not process the mic bias option
430 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
431 * accept requests for bias as of chip versions up to March 2006) and/or
432 * wiring in the computer.
434 #define ALC_PIN_DIR_IN 0x00
435 #define ALC_PIN_DIR_OUT 0x01
436 #define ALC_PIN_DIR_INOUT 0x02
437 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
438 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
440 /* Info about the pin modes supported by the different pin direction modes.
441 * For each direction the minimum and maximum values are given.
443 static signed char alc_pin_mode_dir_info[5][2] = {
444 { 0, 2 }, /* ALC_PIN_DIR_IN */
445 { 3, 4 }, /* ALC_PIN_DIR_OUT */
446 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
447 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
448 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
450 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
451 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
452 #define alc_pin_mode_n_items(_dir) \
453 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
455 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_info *uinfo)
458 unsigned int item_num = uinfo->value.enumerated.item;
459 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
461 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
463 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
465 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
466 item_num = alc_pin_mode_min(dir);
467 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
471 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_value *ucontrol)
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 hda_nid_t nid = kcontrol->private_value & 0xffff;
477 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
478 long *valp = ucontrol->value.integer.value;
479 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
480 AC_VERB_GET_PIN_WIDGET_CONTROL,
483 /* Find enumerated value for current pinctl setting */
484 i = alc_pin_mode_min(dir);
485 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
487 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
491 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
495 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
496 hda_nid_t nid = kcontrol->private_value & 0xffff;
497 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
498 long val = *ucontrol->value.integer.value;
499 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
500 AC_VERB_GET_PIN_WIDGET_CONTROL,
503 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
504 val = alc_pin_mode_min(dir);
506 change = pinctl != alc_pin_mode_values[val];
508 /* Set pin mode to that requested */
509 snd_hda_codec_write_cache(codec, nid, 0,
510 AC_VERB_SET_PIN_WIDGET_CONTROL,
511 alc_pin_mode_values[val]);
513 /* Also enable the retasking pin's input/output as required
514 * for the requested pin mode. Enum values of 2 or less are
517 * Dynamically switching the input/output buffers probably
518 * reduces noise slightly (particularly on input) so we'll
519 * do it. However, having both input and output buffers
520 * enabled simultaneously doesn't seem to be problematic if
521 * this turns out to be necessary in the future.
524 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
525 HDA_AMP_MUTE, HDA_AMP_MUTE);
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
529 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
530 HDA_AMP_MUTE, HDA_AMP_MUTE);
531 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
538 #define ALC_PIN_MODE(xname, nid, dir) \
539 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
540 .info = alc_pin_mode_info, \
541 .get = alc_pin_mode_get, \
542 .put = alc_pin_mode_put, \
543 .private_value = nid | (dir<<16) }
545 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
546 * together using a mask with more than one bit set. This control is
547 * currently used only by the ALC260 test model. At this stage they are not
548 * needed for any "production" models.
550 #ifdef CONFIG_SND_DEBUG
551 #define alc_gpio_data_info snd_ctl_boolean_mono_info
553 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_value *ucontrol)
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 hda_nid_t nid = kcontrol->private_value & 0xffff;
558 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
559 long *valp = ucontrol->value.integer.value;
560 unsigned int val = snd_hda_codec_read(codec, nid, 0,
561 AC_VERB_GET_GPIO_DATA, 0x00);
563 *valp = (val & mask) != 0;
566 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
567 struct snd_ctl_elem_value *ucontrol)
570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571 hda_nid_t nid = kcontrol->private_value & 0xffff;
572 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573 long val = *ucontrol->value.integer.value;
574 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
575 AC_VERB_GET_GPIO_DATA,
578 /* Set/unset the masked GPIO bit(s) as needed */
579 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
584 snd_hda_codec_write_cache(codec, nid, 0,
585 AC_VERB_SET_GPIO_DATA, gpio_data);
589 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
590 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
591 .info = alc_gpio_data_info, \
592 .get = alc_gpio_data_get, \
593 .put = alc_gpio_data_put, \
594 .private_value = nid | (mask<<16) }
595 #endif /* CONFIG_SND_DEBUG */
597 /* A switch control to allow the enabling of the digital IO pins on the
598 * ALC260. This is incredibly simplistic; the intention of this control is
599 * to provide something in the test model allowing digital outputs to be
600 * identified if present. If models are found which can utilise these
601 * outputs a more complete mixer control can be devised for those models if
604 #ifdef CONFIG_SND_DEBUG
605 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
607 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
608 struct snd_ctl_elem_value *ucontrol)
610 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
611 hda_nid_t nid = kcontrol->private_value & 0xffff;
612 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
613 long *valp = ucontrol->value.integer.value;
614 unsigned int val = snd_hda_codec_read(codec, nid, 0,
615 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
617 *valp = (val & mask) != 0;
620 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
621 struct snd_ctl_elem_value *ucontrol)
624 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
625 hda_nid_t nid = kcontrol->private_value & 0xffff;
626 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
627 long val = *ucontrol->value.integer.value;
628 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
629 AC_VERB_GET_DIGI_CONVERT_1,
632 /* Set/unset the masked control bit(s) as needed */
633 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
638 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
643 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
645 .info = alc_spdif_ctrl_info, \
646 .get = alc_spdif_ctrl_get, \
647 .put = alc_spdif_ctrl_put, \
648 .private_value = nid | (mask<<16) }
649 #endif /* CONFIG_SND_DEBUG */
651 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
652 * Again, this is only used in the ALC26x test models to help identify when
653 * the EAPD line must be asserted for features to work.
655 #ifdef CONFIG_SND_DEBUG
656 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
658 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
659 struct snd_ctl_elem_value *ucontrol)
661 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
662 hda_nid_t nid = kcontrol->private_value & 0xffff;
663 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
664 long *valp = ucontrol->value.integer.value;
665 unsigned int val = snd_hda_codec_read(codec, nid, 0,
666 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
668 *valp = (val & mask) != 0;
672 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
677 hda_nid_t nid = kcontrol->private_value & 0xffff;
678 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
679 long val = *ucontrol->value.integer.value;
680 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
681 AC_VERB_GET_EAPD_BTLENABLE,
684 /* Set/unset the masked control bit(s) as needed */
685 change = (!val ? 0 : mask) != (ctrl_data & mask);
690 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
696 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
697 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
698 .info = alc_eapd_ctrl_info, \
699 .get = alc_eapd_ctrl_get, \
700 .put = alc_eapd_ctrl_put, \
701 .private_value = nid | (mask<<16) }
702 #endif /* CONFIG_SND_DEBUG */
705 * set up from the preset table
707 static void setup_preset(struct alc_spec *spec,
708 const struct alc_config_preset *preset)
712 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
713 spec->mixers[spec->num_mixers++] = preset->mixers[i];
714 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
716 spec->init_verbs[spec->num_init_verbs++] =
717 preset->init_verbs[i];
719 spec->channel_mode = preset->channel_mode;
720 spec->num_channel_mode = preset->num_channel_mode;
721 spec->need_dac_fix = preset->need_dac_fix;
723 spec->multiout.max_channels = spec->channel_mode[0].channels;
725 spec->multiout.num_dacs = preset->num_dacs;
726 spec->multiout.dac_nids = preset->dac_nids;
727 spec->multiout.dig_out_nid = preset->dig_out_nid;
728 spec->multiout.hp_nid = preset->hp_nid;
730 spec->num_mux_defs = preset->num_mux_defs;
731 if (!spec->num_mux_defs)
732 spec->num_mux_defs = 1;
733 spec->input_mux = preset->input_mux;
735 spec->num_adc_nids = preset->num_adc_nids;
736 spec->adc_nids = preset->adc_nids;
737 spec->capsrc_nids = preset->capsrc_nids;
738 spec->dig_in_nid = preset->dig_in_nid;
740 spec->unsol_event = preset->unsol_event;
741 spec->init_hook = preset->init_hook;
742 #ifdef CONFIG_SND_HDA_POWER_SAVE
743 spec->loopback.amplist = preset->loopbacks;
747 /* Enable GPIO mask and set output */
748 static struct hda_verb alc_gpio1_init_verbs[] = {
749 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
750 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
751 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
755 static struct hda_verb alc_gpio2_init_verbs[] = {
756 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
757 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
758 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
762 static struct hda_verb alc_gpio3_init_verbs[] = {
763 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
764 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
765 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
770 * Fix hardware PLL issue
771 * On some codecs, the analog PLL gating control must be off while
772 * the default value is 1.
774 static void alc_fix_pll(struct hda_codec *codec)
776 struct alc_spec *spec = codec->spec;
781 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
783 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
784 AC_VERB_GET_PROC_COEF, 0);
785 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
787 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
788 val & ~(1 << spec->pll_coef_bit));
791 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
792 unsigned int coef_idx, unsigned int coef_bit)
794 struct alc_spec *spec = codec->spec;
796 spec->pll_coef_idx = coef_idx;
797 spec->pll_coef_bit = coef_bit;
801 static void alc_sku_automute(struct hda_codec *codec)
803 struct alc_spec *spec = codec->spec;
804 unsigned int present;
805 unsigned int hp_nid = spec->autocfg.hp_pins[0];
806 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
808 /* need to execute and sync at first */
809 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
810 present = snd_hda_codec_read(codec, hp_nid, 0,
811 AC_VERB_GET_PIN_SENSE, 0);
812 spec->jack_present = (present & 0x80000000) != 0;
813 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
814 spec->jack_present ? 0 : PIN_OUT);
817 /* unsolicited event for HP jack sensing */
818 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
820 if (codec->vendor_id == 0x10ec0880)
824 if (res != ALC880_HP_EVENT)
827 alc_sku_automute(codec);
830 /* additional initialization for ALC888 variants */
831 static void alc888_coef_init(struct hda_codec *codec)
835 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
836 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
837 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
838 if ((tmp & 0xf0) == 2)
840 snd_hda_codec_read(codec, 0x20, 0,
841 AC_VERB_SET_PROC_COEF, 0x830);
844 snd_hda_codec_read(codec, 0x20, 0,
845 AC_VERB_SET_PROC_COEF, 0x3030);
848 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
849 * 31 ~ 16 : Manufacture ID
851 * 7 ~ 0 : Assembly ID
852 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
854 static void alc_subsystem_id(struct hda_codec *codec,
855 unsigned int porta, unsigned int porte,
858 unsigned int ass, tmp, i;
860 struct alc_spec *spec = codec->spec;
862 ass = codec->subsystem_id & 0xffff;
863 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
867 * 31~30 : port conetcivity
870 * 19~16 : Check sum (15:1)
875 if (codec->vendor_id == 0x10ec0260)
877 ass = snd_hda_codec_read(codec, nid, 0,
878 AC_VERB_GET_CONFIG_DEFAULT, 0);
879 if (!(ass & 1) && !(ass & 0x100000))
881 if ((ass >> 30) != 1) /* no physical connection */
886 for (i = 1; i < 16; i++) {
890 if (((ass >> 16) & 0xf) != tmp)
896 * 2 : 0 --> Desktop, 1 --> Laptop
897 * 3~5 : External Amplifier control
900 tmp = (ass & 0x38) >> 3; /* external Amp control */
903 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
906 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
909 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
911 case 5: /* set EAPD output high */
912 switch (codec->vendor_id) {
914 snd_hda_codec_write(codec, 0x0f, 0,
915 AC_VERB_SET_EAPD_BTLENABLE, 2);
916 snd_hda_codec_write(codec, 0x10, 0,
917 AC_VERB_SET_EAPD_BTLENABLE, 2);
928 snd_hda_codec_write(codec, 0x14, 0,
929 AC_VERB_SET_EAPD_BTLENABLE, 2);
930 snd_hda_codec_write(codec, 0x15, 0,
931 AC_VERB_SET_EAPD_BTLENABLE, 2);
934 switch (codec->vendor_id) {
936 snd_hda_codec_write(codec, 0x1a, 0,
937 AC_VERB_SET_COEF_INDEX, 7);
938 tmp = snd_hda_codec_read(codec, 0x1a, 0,
939 AC_VERB_GET_PROC_COEF, 0);
940 snd_hda_codec_write(codec, 0x1a, 0,
941 AC_VERB_SET_COEF_INDEX, 7);
942 snd_hda_codec_write(codec, 0x1a, 0,
943 AC_VERB_SET_PROC_COEF,
952 snd_hda_codec_write(codec, 0x20, 0,
953 AC_VERB_SET_COEF_INDEX, 7);
954 tmp = snd_hda_codec_read(codec, 0x20, 0,
955 AC_VERB_GET_PROC_COEF, 0);
956 snd_hda_codec_write(codec, 0x20, 0,
957 AC_VERB_SET_COEF_INDEX, 7);
958 snd_hda_codec_write(codec, 0x20, 0,
959 AC_VERB_SET_PROC_COEF,
963 /*alc888_coef_init(codec);*/ /* called in alc_init() */
967 snd_hda_codec_write(codec, 0x20, 0,
968 AC_VERB_SET_COEF_INDEX, 7);
969 tmp = snd_hda_codec_read(codec, 0x20, 0,
970 AC_VERB_GET_PROC_COEF, 0);
971 snd_hda_codec_write(codec, 0x20, 0,
972 AC_VERB_SET_COEF_INDEX, 7);
973 snd_hda_codec_write(codec, 0x20, 0,
974 AC_VERB_SET_PROC_COEF,
982 /* is laptop or Desktop and enable the function "Mute internal speaker
983 * when the external headphone out jack is plugged"
988 * 10~8 : Jack location
989 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
991 * 15 : 1 --> enable the function "Mute internal speaker
992 * when the external headphone out jack is plugged"
994 if (!spec->autocfg.speaker_pins[0]) {
995 if (spec->autocfg.line_out_pins[0])
996 spec->autocfg.speaker_pins[0] =
997 spec->autocfg.line_out_pins[0];
1002 if (!spec->autocfg.hp_pins[0]) {
1003 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1005 spec->autocfg.hp_pins[0] = porta;
1007 spec->autocfg.hp_pins[0] = porte;
1009 spec->autocfg.hp_pins[0] = portd;
1014 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1015 AC_VERB_SET_UNSOLICITED_ENABLE,
1016 AC_USRSP_EN | ALC880_HP_EVENT);
1018 spec->unsol_event = alc_sku_unsol_event;
1022 * Fix-up pin default configurations
1030 static void alc_fix_pincfg(struct hda_codec *codec,
1031 const struct snd_pci_quirk *quirk,
1032 const struct alc_pincfg **pinfix)
1034 const struct alc_pincfg *cfg;
1036 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1040 cfg = pinfix[quirk->value];
1041 for (; cfg->nid; cfg++) {
1044 for (i = 0; i < 4; i++) {
1045 snd_hda_codec_write(codec, cfg->nid, 0,
1046 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1054 * ALC880 3-stack model
1056 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1057 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1058 * F-Mic = 0x1b, HP = 0x19
1061 static hda_nid_t alc880_dac_nids[4] = {
1062 /* front, rear, clfe, rear_surr */
1063 0x02, 0x05, 0x04, 0x03
1066 static hda_nid_t alc880_adc_nids[3] = {
1071 /* The datasheet says the node 0x07 is connected from inputs,
1072 * but it shows zero connection in the real implementation on some devices.
1073 * Note: this is a 915GAV bug, fixed on 915GLV
1075 static hda_nid_t alc880_adc_nids_alt[2] = {
1080 #define ALC880_DIGOUT_NID 0x06
1081 #define ALC880_DIGIN_NID 0x0a
1083 static struct hda_input_mux alc880_capture_source = {
1087 { "Front Mic", 0x3 },
1093 /* channel source setting (2/6 channel selection for 3-stack) */
1095 static struct hda_verb alc880_threestack_ch2_init[] = {
1096 /* set line-in to input, mute it */
1097 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1098 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1099 /* set mic-in to input vref 80%, mute it */
1100 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1101 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1106 static struct hda_verb alc880_threestack_ch6_init[] = {
1107 /* set line-in to output, unmute it */
1108 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1109 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1110 /* set mic-in to output, unmute it */
1111 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1112 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1116 static struct hda_channel_mode alc880_threestack_modes[2] = {
1117 { 2, alc880_threestack_ch2_init },
1118 { 6, alc880_threestack_ch6_init },
1121 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1122 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1123 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1124 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1125 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1126 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1127 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1128 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1129 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1130 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1131 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1132 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1133 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1135 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1136 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1137 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1138 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1139 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1143 .name = "Channel Mode",
1144 .info = alc_ch_mode_info,
1145 .get = alc_ch_mode_get,
1146 .put = alc_ch_mode_put,
1151 /* capture mixer elements */
1152 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1153 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1154 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1155 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1156 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1157 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1158 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1160 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1161 /* The multiple "Capture Source" controls confuse alsamixer
1162 * So call somewhat different..
1164 /* .name = "Capture Source", */
1165 .name = "Input Source",
1167 .info = alc_mux_enum_info,
1168 .get = alc_mux_enum_get,
1169 .put = alc_mux_enum_put,
1174 /* capture mixer elements (in case NID 0x07 not available) */
1175 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1176 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1177 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1178 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1179 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1182 /* The multiple "Capture Source" controls confuse alsamixer
1183 * So call somewhat different..
1185 /* .name = "Capture Source", */
1186 .name = "Input Source",
1188 .info = alc_mux_enum_info,
1189 .get = alc_mux_enum_get,
1190 .put = alc_mux_enum_put,
1198 * ALC880 5-stack model
1200 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1202 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1203 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1206 /* additional mixers to alc880_three_stack_mixer */
1207 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1208 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1209 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1213 /* channel source setting (6/8 channel selection for 5-stack) */
1215 static struct hda_verb alc880_fivestack_ch6_init[] = {
1216 /* set line-in to input, mute it */
1217 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1218 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1223 static struct hda_verb alc880_fivestack_ch8_init[] = {
1224 /* set line-in to output, unmute it */
1225 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1226 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1230 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1231 { 6, alc880_fivestack_ch6_init },
1232 { 8, alc880_fivestack_ch8_init },
1237 * ALC880 6-stack model
1239 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1240 * Side = 0x05 (0x0f)
1241 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1242 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1245 static hda_nid_t alc880_6st_dac_nids[4] = {
1246 /* front, rear, clfe, rear_surr */
1247 0x02, 0x03, 0x04, 0x05
1250 static struct hda_input_mux alc880_6stack_capture_source = {
1254 { "Front Mic", 0x1 },
1260 /* fixed 8-channels */
1261 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1265 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1266 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1267 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1268 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1269 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1270 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1271 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1272 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1273 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1274 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1275 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1284 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1285 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1288 .name = "Channel Mode",
1289 .info = alc_ch_mode_info,
1290 .get = alc_ch_mode_get,
1291 .put = alc_ch_mode_put,
1300 * W810 has rear IO for:
1303 * Center/LFE (DAC 04)
1306 * The system also has a pair of internal speakers, and a headphone jack.
1307 * These are both connected to Line2 on the codec, hence to DAC 02.
1309 * There is a variable resistor to control the speaker or headphone
1310 * volume. This is a hardware-only device without a software API.
1312 * Plugging headphones in will disable the internal speakers. This is
1313 * implemented in hardware, not via the driver using jack sense. In
1314 * a similar fashion, plugging into the rear socket marked "front" will
1315 * disable both the speakers and headphones.
1317 * For input, there's a microphone jack, and an "audio in" jack.
1318 * These may not do anything useful with this driver yet, because I
1319 * haven't setup any initialization verbs for these yet...
1322 static hda_nid_t alc880_w810_dac_nids[3] = {
1323 /* front, rear/surround, clfe */
1327 /* fixed 6 channels */
1328 static struct hda_channel_mode alc880_w810_modes[1] = {
1332 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1333 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1334 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1335 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1336 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1337 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1338 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1339 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1340 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1341 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1342 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1350 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1351 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1355 static hda_nid_t alc880_z71v_dac_nids[1] = {
1358 #define ALC880_Z71V_HP_DAC 0x03
1360 /* fixed 2 channels */
1361 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1365 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1366 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1367 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1368 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1369 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1373 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1379 * ALC880 F1734 model
1381 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1382 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1385 static hda_nid_t alc880_f1734_dac_nids[1] = {
1388 #define ALC880_F1734_HP_DAC 0x02
1390 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1391 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1392 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1393 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1394 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1395 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1396 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1402 static struct hda_input_mux alc880_f1734_capture_source = {
1414 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1415 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1416 * Mic = 0x18, Line = 0x1a
1419 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1420 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1422 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1423 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1424 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1425 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1426 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1427 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1428 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1429 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1430 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1431 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1432 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1433 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1434 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1435 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1436 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1439 .name = "Channel Mode",
1440 .info = alc_ch_mode_info,
1441 .get = alc_ch_mode_get,
1442 .put = alc_ch_mode_put,
1448 * ALC880 ASUS W1V model
1450 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1451 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1452 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1455 /* additional mixers to alc880_asus_mixer */
1456 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1457 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1458 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1462 /* additional mixers to alc880_asus_mixer */
1463 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1464 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1465 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1470 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1471 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1472 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1474 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1475 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1477 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1478 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1479 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1482 /* The multiple "Capture Source" controls confuse alsamixer
1483 * So call somewhat different..
1485 /* .name = "Capture Source", */
1486 .name = "Input Source",
1488 .info = alc_mux_enum_info,
1489 .get = alc_mux_enum_get,
1490 .put = alc_mux_enum_put,
1496 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1497 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1498 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1499 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1500 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1501 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1502 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1503 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1504 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1505 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1506 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1511 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1513 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1514 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1517 .name = "Channel Mode",
1518 .info = alc_ch_mode_info,
1519 .get = alc_ch_mode_get,
1520 .put = alc_ch_mode_put,
1525 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1526 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1527 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1528 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1529 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1532 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1533 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1534 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1535 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1539 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1540 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1541 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1542 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1543 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1550 * virtual master controls
1554 * slave controls for virtual master
1556 static const char *alc_slave_vols[] = {
1557 "Front Playback Volume",
1558 "Surround Playback Volume",
1559 "Center Playback Volume",
1560 "LFE Playback Volume",
1561 "Side Playback Volume",
1562 "Headphone Playback Volume",
1563 "Speaker Playback Volume",
1564 "Mono Playback Volume",
1565 "Line-Out Playback Volume",
1569 static const char *alc_slave_sws[] = {
1570 "Front Playback Switch",
1571 "Surround Playback Switch",
1572 "Center Playback Switch",
1573 "LFE Playback Switch",
1574 "Side Playback Switch",
1575 "Headphone Playback Switch",
1576 "Speaker Playback Switch",
1577 "Mono Playback Switch",
1578 "IEC958 Playback Switch",
1583 * build control elements
1585 static int alc_build_controls(struct hda_codec *codec)
1587 struct alc_spec *spec = codec->spec;
1591 for (i = 0; i < spec->num_mixers; i++) {
1592 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1597 if (spec->multiout.dig_out_nid) {
1598 err = snd_hda_create_spdif_out_ctls(codec,
1599 spec->multiout.dig_out_nid);
1602 err = snd_hda_create_spdif_share_sw(codec,
1606 spec->multiout.share_spdif = 1;
1608 if (spec->dig_in_nid) {
1609 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1614 /* if we have no master control, let's create it */
1615 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1616 unsigned int vmaster_tlv[4];
1617 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1618 HDA_OUTPUT, vmaster_tlv);
1619 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1620 vmaster_tlv, alc_slave_vols);
1624 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1625 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1626 NULL, alc_slave_sws);
1636 * initialize the codec volumes, etc
1640 * generic initialization of ADC, input mixers and output mixers
1642 static struct hda_verb alc880_volume_init_verbs[] = {
1644 * Unmute ADC0-2 and set the default input to mic-in
1646 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1647 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1648 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1650 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1651 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1653 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1655 * Note: PASD motherboards uses the Line In 2 as the input for front
1658 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1659 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1660 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1661 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1662 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1663 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1664 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1665 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1668 * Set up output mixers (0x0c - 0x0f)
1670 /* set vol=0 to output mixers */
1671 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1672 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1673 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1674 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1675 /* set up input amps for analog loopback */
1676 /* Amp Indices: DAC = 0, mixer = 1 */
1677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1680 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1690 * 3-stack pin configuration:
1691 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1693 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1695 * preset connection lists of input pins
1696 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1698 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1699 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1700 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1703 * Set pin mode and muting
1705 /* set front pin widgets 0x14 for output */
1706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1709 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1710 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1711 /* Mic2 (as headphone out) for HP output */
1712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1714 /* Line In pin widget for input */
1715 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1716 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1717 /* Line2 (as front mic) pin widget for input and vref at 80% */
1718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1719 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1720 /* CD pin widget for input */
1721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1727 * 5-stack pin configuration:
1728 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1729 * line-in/side = 0x1a, f-mic = 0x1b
1731 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1733 * preset connection lists of input pins
1734 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1736 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1737 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1740 * Set pin mode and muting
1742 /* set pin widgets 0x14-0x17 for output */
1743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1745 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1746 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1747 /* unmute pins for output (no gain on this amp) */
1748 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1750 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1751 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1753 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1754 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1755 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1756 /* Mic2 (as headphone out) for HP output */
1757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1759 /* Line In pin widget for input */
1760 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1762 /* Line2 (as front mic) pin widget for input and vref at 80% */
1763 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1764 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1765 /* CD pin widget for input */
1766 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1772 * W810 pin configuration:
1773 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1775 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1776 /* hphone/speaker input selector: front DAC */
1777 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1782 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1783 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1784 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1787 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1793 * Z71V pin configuration:
1794 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1796 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1797 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1802 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1803 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1804 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1805 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1811 * 6-stack pin configuration:
1812 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1813 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1815 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1816 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1822 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1823 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1825 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1830 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1832 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1833 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1834 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1835 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1841 * Uniwill pin configuration:
1842 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1845 static struct hda_verb alc880_uniwill_init_verbs[] = {
1846 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1852 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1853 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1854 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1857 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1859 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1861 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1863 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1864 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1865 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1866 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1869 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1870 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1871 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1873 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1874 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1881 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1883 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1884 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1887 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1890 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1893 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1894 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1897 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1901 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1902 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1904 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1906 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1907 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1912 static struct hda_verb alc880_beep_init_verbs[] = {
1913 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1917 /* toggle speaker-output according to the hp-jack state */
1918 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1920 unsigned int present;
1923 present = snd_hda_codec_read(codec, 0x14, 0,
1924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1925 bits = present ? HDA_AMP_MUTE : 0;
1926 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1927 HDA_AMP_MUTE, bits);
1928 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1929 HDA_AMP_MUTE, bits);
1932 /* auto-toggle front mic */
1933 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1935 unsigned int present;
1938 present = snd_hda_codec_read(codec, 0x18, 0,
1939 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1940 bits = present ? HDA_AMP_MUTE : 0;
1941 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1944 static void alc880_uniwill_automute(struct hda_codec *codec)
1946 alc880_uniwill_hp_automute(codec);
1947 alc880_uniwill_mic_automute(codec);
1950 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1953 /* Looks like the unsol event is incompatible with the standard
1954 * definition. 4bit tag is placed at 28 bit!
1956 switch (res >> 28) {
1957 case ALC880_HP_EVENT:
1958 alc880_uniwill_hp_automute(codec);
1960 case ALC880_MIC_EVENT:
1961 alc880_uniwill_mic_automute(codec);
1966 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1968 unsigned int present;
1971 present = snd_hda_codec_read(codec, 0x14, 0,
1972 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1973 bits = present ? HDA_AMP_MUTE : 0;
1974 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1977 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1979 unsigned int present;
1981 present = snd_hda_codec_read(codec, 0x21, 0,
1982 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1983 present &= HDA_AMP_VOLMASK;
1984 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1985 HDA_AMP_VOLMASK, present);
1986 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1987 HDA_AMP_VOLMASK, present);
1990 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1993 /* Looks like the unsol event is incompatible with the standard
1994 * definition. 4bit tag is placed at 28 bit!
1996 if ((res >> 28) == ALC880_HP_EVENT)
1997 alc880_uniwill_p53_hp_automute(codec);
1998 if ((res >> 28) == ALC880_DCVOL_EVENT)
1999 alc880_uniwill_p53_dcvol_automute(codec);
2003 * F1734 pin configuration:
2004 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2006 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2007 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2008 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2009 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2010 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2011 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2013 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2014 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2018 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2019 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2020 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2021 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2022 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2023 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2024 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2025 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2026 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2029 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2035 * ASUS pin configuration:
2036 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2038 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2039 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2040 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2041 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2042 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2045 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2047 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2049 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2050 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2053 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2055 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2057 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2059 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2066 /* Enable GPIO mask and set output */
2067 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2068 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2070 /* Clevo m520g init */
2071 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2072 /* headphone output */
2073 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2075 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2076 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2078 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2079 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2081 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2082 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2083 /* Mic1 (rear panel) */
2084 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2085 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2086 /* Mic2 (front panel) */
2087 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2088 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2092 /* change to EAPD mode */
2093 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2094 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2099 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2100 /* change to EAPD mode */
2101 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2102 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2104 /* Headphone output */
2105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2108 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2110 /* Line In pin widget for input */
2111 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2112 /* CD pin widget for input */
2113 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2114 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2115 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2117 /* change to EAPD mode */
2118 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2119 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2125 * LG m1 express dual
2128 * Rear Line-In/Out (blue): 0x14
2129 * Build-in Mic-In: 0x15
2131 * HP-Out (green): 0x1b
2132 * Mic-In/Out (red): 0x19
2136 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2137 static hda_nid_t alc880_lg_dac_nids[3] = {
2141 /* seems analog CD is not working */
2142 static struct hda_input_mux alc880_lg_capture_source = {
2147 { "Internal Mic", 0x6 },
2151 /* 2,4,6 channel modes */
2152 static struct hda_verb alc880_lg_ch2_init[] = {
2153 /* set line-in and mic-in to input */
2154 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2155 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2159 static struct hda_verb alc880_lg_ch4_init[] = {
2160 /* set line-in to out and mic-in to input */
2161 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2162 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2166 static struct hda_verb alc880_lg_ch6_init[] = {
2167 /* set line-in and mic-in to output */
2168 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2169 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2173 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2174 { 2, alc880_lg_ch2_init },
2175 { 4, alc880_lg_ch4_init },
2176 { 6, alc880_lg_ch6_init },
2179 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2180 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2181 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2182 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2183 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2184 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2185 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2186 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2187 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2190 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2191 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2192 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2193 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2195 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2196 .name = "Channel Mode",
2197 .info = alc_ch_mode_info,
2198 .get = alc_ch_mode_get,
2199 .put = alc_ch_mode_put,
2204 static struct hda_verb alc880_lg_init_verbs[] = {
2205 /* set capture source to mic-in */
2206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2207 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2208 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2209 /* mute all amp mixer inputs */
2210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2213 /* line-in to input */
2214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2218 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2221 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2222 /* mic-in to input */
2223 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2224 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2225 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2229 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2235 /* toggle speaker-output according to the hp-jack state */
2236 static void alc880_lg_automute(struct hda_codec *codec)
2238 unsigned int present;
2241 present = snd_hda_codec_read(codec, 0x1b, 0,
2242 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2243 bits = present ? HDA_AMP_MUTE : 0;
2244 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2245 HDA_AMP_MUTE, bits);
2248 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2250 /* Looks like the unsol event is incompatible with the standard
2251 * definition. 4bit tag is placed at 28 bit!
2253 if ((res >> 28) == 0x01)
2254 alc880_lg_automute(codec);
2263 * Built-in Mic-In: 0x19
2269 static struct hda_input_mux alc880_lg_lw_capture_source = {
2273 { "Internal Mic", 0x1 },
2278 #define alc880_lg_lw_modes alc880_threestack_modes
2280 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2282 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2283 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2284 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2285 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2286 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2287 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2288 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2289 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2290 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2292 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2293 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2294 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2297 .name = "Channel Mode",
2298 .info = alc_ch_mode_info,
2299 .get = alc_ch_mode_get,
2300 .put = alc_ch_mode_put,
2305 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2306 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2307 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2308 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2310 /* set capture source to mic-in */
2311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2313 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2314 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2317 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2320 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2321 /* mic-in to input */
2322 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2323 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2325 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2326 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2332 /* toggle speaker-output according to the hp-jack state */
2333 static void alc880_lg_lw_automute(struct hda_codec *codec)
2335 unsigned int present;
2338 present = snd_hda_codec_read(codec, 0x1b, 0,
2339 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2340 bits = present ? HDA_AMP_MUTE : 0;
2341 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2342 HDA_AMP_MUTE, bits);
2345 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2347 /* Looks like the unsol event is incompatible with the standard
2348 * definition. 4bit tag is placed at 28 bit!
2350 if ((res >> 28) == 0x01)
2351 alc880_lg_lw_automute(codec);
2354 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2355 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2356 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2357 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2358 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2359 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2360 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2364 static struct hda_input_mux alc880_medion_rim_capture_source = {
2368 { "Internal Mic", 0x1 },
2372 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2373 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2375 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2376 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2378 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2379 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2381 /* Mic2 (as headphone out) for HP output */
2382 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2384 /* Internal Speaker */
2385 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2388 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2389 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2391 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2395 /* toggle speaker-output according to the hp-jack state */
2396 static void alc880_medion_rim_automute(struct hda_codec *codec)
2398 unsigned int present;
2401 present = snd_hda_codec_read(codec, 0x14, 0,
2402 AC_VERB_GET_PIN_SENSE, 0)
2403 & AC_PINSENSE_PRESENCE;
2404 bits = present ? HDA_AMP_MUTE : 0;
2405 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2406 HDA_AMP_MUTE, bits);
2408 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2410 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2413 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2416 /* Looks like the unsol event is incompatible with the standard
2417 * definition. 4bit tag is placed at 28 bit!
2419 if ((res >> 28) == ALC880_HP_EVENT)
2420 alc880_medion_rim_automute(codec);
2423 #ifdef CONFIG_SND_HDA_POWER_SAVE
2424 static struct hda_amp_list alc880_loopbacks[] = {
2425 { 0x0b, HDA_INPUT, 0 },
2426 { 0x0b, HDA_INPUT, 1 },
2427 { 0x0b, HDA_INPUT, 2 },
2428 { 0x0b, HDA_INPUT, 3 },
2429 { 0x0b, HDA_INPUT, 4 },
2433 static struct hda_amp_list alc880_lg_loopbacks[] = {
2434 { 0x0b, HDA_INPUT, 1 },
2435 { 0x0b, HDA_INPUT, 6 },
2436 { 0x0b, HDA_INPUT, 7 },
2445 static int alc_init(struct hda_codec *codec)
2447 struct alc_spec *spec = codec->spec;
2451 if (codec->vendor_id == 0x10ec0888)
2452 alc888_coef_init(codec);
2454 for (i = 0; i < spec->num_init_verbs; i++)
2455 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2457 if (spec->init_hook)
2458 spec->init_hook(codec);
2463 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2465 struct alc_spec *spec = codec->spec;
2467 if (spec->unsol_event)
2468 spec->unsol_event(codec, res);
2471 #ifdef CONFIG_SND_HDA_POWER_SAVE
2472 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2474 struct alc_spec *spec = codec->spec;
2475 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2480 * Analog playback callbacks
2482 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2483 struct hda_codec *codec,
2484 struct snd_pcm_substream *substream)
2486 struct alc_spec *spec = codec->spec;
2487 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2491 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2492 struct hda_codec *codec,
2493 unsigned int stream_tag,
2494 unsigned int format,
2495 struct snd_pcm_substream *substream)
2497 struct alc_spec *spec = codec->spec;
2498 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2499 stream_tag, format, substream);
2502 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2503 struct hda_codec *codec,
2504 struct snd_pcm_substream *substream)
2506 struct alc_spec *spec = codec->spec;
2507 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2513 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2514 struct hda_codec *codec,
2515 struct snd_pcm_substream *substream)
2517 struct alc_spec *spec = codec->spec;
2518 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2521 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2522 struct hda_codec *codec,
2523 unsigned int stream_tag,
2524 unsigned int format,
2525 struct snd_pcm_substream *substream)
2527 struct alc_spec *spec = codec->spec;
2528 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2529 stream_tag, format, substream);
2532 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2533 struct hda_codec *codec,
2534 struct snd_pcm_substream *substream)
2536 struct alc_spec *spec = codec->spec;
2537 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2543 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2544 struct hda_codec *codec,
2545 unsigned int stream_tag,
2546 unsigned int format,
2547 struct snd_pcm_substream *substream)
2549 struct alc_spec *spec = codec->spec;
2551 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2552 stream_tag, 0, format);
2556 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2557 struct hda_codec *codec,
2558 struct snd_pcm_substream *substream)
2560 struct alc_spec *spec = codec->spec;
2562 snd_hda_codec_cleanup_stream(codec,
2563 spec->adc_nids[substream->number + 1]);
2570 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2574 /* NID is set in alc_build_pcms */
2576 .open = alc880_playback_pcm_open,
2577 .prepare = alc880_playback_pcm_prepare,
2578 .cleanup = alc880_playback_pcm_cleanup
2582 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2586 /* NID is set in alc_build_pcms */
2589 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2593 /* NID is set in alc_build_pcms */
2596 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2597 .substreams = 2, /* can be overridden */
2600 /* NID is set in alc_build_pcms */
2602 .prepare = alc880_alt_capture_pcm_prepare,
2603 .cleanup = alc880_alt_capture_pcm_cleanup
2607 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2611 /* NID is set in alc_build_pcms */
2613 .open = alc880_dig_playback_pcm_open,
2614 .close = alc880_dig_playback_pcm_close,
2615 .prepare = alc880_dig_playback_pcm_prepare
2619 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2623 /* NID is set in alc_build_pcms */
2626 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2627 static struct hda_pcm_stream alc_pcm_null_stream = {
2633 static int alc_build_pcms(struct hda_codec *codec)
2635 struct alc_spec *spec = codec->spec;
2636 struct hda_pcm *info = spec->pcm_rec;
2639 codec->num_pcms = 1;
2640 codec->pcm_info = info;
2642 info->name = spec->stream_name_analog;
2643 if (spec->stream_analog_playback) {
2644 if (snd_BUG_ON(!spec->multiout.dac_nids))
2646 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2647 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2649 if (spec->stream_analog_capture) {
2650 if (snd_BUG_ON(!spec->adc_nids))
2652 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2653 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2656 if (spec->channel_mode) {
2657 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2658 for (i = 0; i < spec->num_channel_mode; i++) {
2659 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2660 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2665 /* SPDIF for stream index #1 */
2666 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2667 codec->num_pcms = 2;
2668 info = spec->pcm_rec + 1;
2669 info->name = spec->stream_name_digital;
2670 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2671 if (spec->multiout.dig_out_nid &&
2672 spec->stream_digital_playback) {
2673 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2674 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2676 if (spec->dig_in_nid &&
2677 spec->stream_digital_capture) {
2678 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2679 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2681 /* FIXME: do we need this for all Realtek codec models? */
2682 codec->spdif_status_reset = 1;
2685 /* If the use of more than one ADC is requested for the current
2686 * model, configure a second analog capture-only PCM.
2688 /* Additional Analaog capture for index #2 */
2689 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2690 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2691 codec->num_pcms = 3;
2692 info = spec->pcm_rec + 2;
2693 info->name = spec->stream_name_analog;
2694 if (spec->alt_dac_nid) {
2695 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2696 *spec->stream_analog_alt_playback;
2697 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2700 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2701 alc_pcm_null_stream;
2702 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2704 if (spec->num_adc_nids > 1) {
2705 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2706 *spec->stream_analog_alt_capture;
2707 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2709 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2710 spec->num_adc_nids - 1;
2712 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2713 alc_pcm_null_stream;
2714 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2721 static void alc_free(struct hda_codec *codec)
2723 struct alc_spec *spec = codec->spec;
2729 if (spec->kctl_alloc) {
2730 for (i = 0; i < spec->num_kctl_used; i++)
2731 kfree(spec->kctl_alloc[i].name);
2732 kfree(spec->kctl_alloc);
2735 codec->spec = NULL; /* to be sure */
2740 static struct hda_codec_ops alc_patch_ops = {
2741 .build_controls = alc_build_controls,
2742 .build_pcms = alc_build_pcms,
2745 .unsol_event = alc_unsol_event,
2746 #ifdef CONFIG_SND_HDA_POWER_SAVE
2747 .check_power_status = alc_check_power_status,
2753 * Test configuration for debugging
2755 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2758 #ifdef CONFIG_SND_DEBUG
2759 static hda_nid_t alc880_test_dac_nids[4] = {
2760 0x02, 0x03, 0x04, 0x05
2763 static struct hda_input_mux alc880_test_capture_source = {
2772 { "Surround", 0x6 },
2776 static struct hda_channel_mode alc880_test_modes[4] = {
2783 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2784 struct snd_ctl_elem_info *uinfo)
2786 static char *texts[] = {
2787 "N/A", "Line Out", "HP Out",
2788 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2790 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2792 uinfo->value.enumerated.items = 8;
2793 if (uinfo->value.enumerated.item >= 8)
2794 uinfo->value.enumerated.item = 7;
2795 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2799 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2800 struct snd_ctl_elem_value *ucontrol)
2802 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2803 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2804 unsigned int pin_ctl, item = 0;
2806 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2807 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2808 if (pin_ctl & AC_PINCTL_OUT_EN) {
2809 if (pin_ctl & AC_PINCTL_HP_EN)
2813 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2814 switch (pin_ctl & AC_PINCTL_VREFEN) {
2815 case AC_PINCTL_VREF_HIZ: item = 3; break;
2816 case AC_PINCTL_VREF_50: item = 4; break;
2817 case AC_PINCTL_VREF_GRD: item = 5; break;
2818 case AC_PINCTL_VREF_80: item = 6; break;
2819 case AC_PINCTL_VREF_100: item = 7; break;
2822 ucontrol->value.enumerated.item[0] = item;
2826 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2827 struct snd_ctl_elem_value *ucontrol)
2829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2830 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2831 static unsigned int ctls[] = {
2832 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2833 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2834 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2835 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2836 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2837 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2839 unsigned int old_ctl, new_ctl;
2841 old_ctl = snd_hda_codec_read(codec, nid, 0,
2842 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2843 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2844 if (old_ctl != new_ctl) {
2846 snd_hda_codec_write_cache(codec, nid, 0,
2847 AC_VERB_SET_PIN_WIDGET_CONTROL,
2849 val = ucontrol->value.enumerated.item[0] >= 3 ?
2851 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2858 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2859 struct snd_ctl_elem_info *uinfo)
2861 static char *texts[] = {
2862 "Front", "Surround", "CLFE", "Side"
2864 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2866 uinfo->value.enumerated.items = 4;
2867 if (uinfo->value.enumerated.item >= 4)
2868 uinfo->value.enumerated.item = 3;
2869 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2873 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2874 struct snd_ctl_elem_value *ucontrol)
2876 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2877 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2880 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2881 ucontrol->value.enumerated.item[0] = sel & 3;
2885 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2886 struct snd_ctl_elem_value *ucontrol)
2888 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2889 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2892 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2893 if (ucontrol->value.enumerated.item[0] != sel) {
2894 sel = ucontrol->value.enumerated.item[0] & 3;
2895 snd_hda_codec_write_cache(codec, nid, 0,
2896 AC_VERB_SET_CONNECT_SEL, sel);
2902 #define PIN_CTL_TEST(xname,nid) { \
2903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2905 .info = alc_test_pin_ctl_info, \
2906 .get = alc_test_pin_ctl_get, \
2907 .put = alc_test_pin_ctl_put, \
2908 .private_value = nid \
2911 #define PIN_SRC_TEST(xname,nid) { \
2912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2914 .info = alc_test_pin_src_info, \
2915 .get = alc_test_pin_src_get, \
2916 .put = alc_test_pin_src_put, \
2917 .private_value = nid \
2920 static struct snd_kcontrol_new alc880_test_mixer[] = {
2921 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2922 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2923 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2924 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2925 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2926 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2927 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2928 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2929 PIN_CTL_TEST("Front Pin Mode", 0x14),
2930 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2931 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2932 PIN_CTL_TEST("Side Pin Mode", 0x17),
2933 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2934 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2935 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2936 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2937 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2938 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2939 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2940 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2941 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2942 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2943 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2944 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2945 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2946 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2947 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2948 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2949 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2950 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2952 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2953 .name = "Channel Mode",
2954 .info = alc_ch_mode_info,
2955 .get = alc_ch_mode_get,
2956 .put = alc_ch_mode_put,
2961 static struct hda_verb alc880_test_init_verbs[] = {
2962 /* Unmute inputs of 0x0c - 0x0f */
2963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2964 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2969 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2970 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2971 /* Vol output for 0x0c-0x0f */
2972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2974 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2975 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2976 /* Set output pins 0x14-0x17 */
2977 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2979 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2980 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2981 /* Unmute output pins 0x14-0x17 */
2982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2984 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2985 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2986 /* Set input pins 0x18-0x1c */
2987 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2988 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2989 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2990 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2991 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2992 /* Mute input pins 0x18-0x1b */
2993 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2994 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2995 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2996 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2999 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3000 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3001 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3003 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3004 /* Analog input/passthru */
3005 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3017 static const char *alc880_models[ALC880_MODEL_LAST] = {
3018 [ALC880_3ST] = "3stack",
3019 [ALC880_TCL_S700] = "tcl",
3020 [ALC880_3ST_DIG] = "3stack-digout",
3021 [ALC880_CLEVO] = "clevo",
3022 [ALC880_5ST] = "5stack",
3023 [ALC880_5ST_DIG] = "5stack-digout",
3024 [ALC880_W810] = "w810",
3025 [ALC880_Z71V] = "z71v",
3026 [ALC880_6ST] = "6stack",
3027 [ALC880_6ST_DIG] = "6stack-digout",
3028 [ALC880_ASUS] = "asus",
3029 [ALC880_ASUS_W1V] = "asus-w1v",
3030 [ALC880_ASUS_DIG] = "asus-dig",
3031 [ALC880_ASUS_DIG2] = "asus-dig2",
3032 [ALC880_UNIWILL_DIG] = "uniwill",
3033 [ALC880_UNIWILL_P53] = "uniwill-p53",
3034 [ALC880_FUJITSU] = "fujitsu",
3035 [ALC880_F1734] = "F1734",
3037 [ALC880_LG_LW] = "lg-lw",
3038 [ALC880_MEDION_RIM] = "medion",
3039 #ifdef CONFIG_SND_DEBUG
3040 [ALC880_TEST] = "test",
3042 [ALC880_AUTO] = "auto",
3045 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3046 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3047 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3048 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3049 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3050 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3051 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3052 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3053 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3054 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3055 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3056 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3057 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3058 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3059 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3060 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3061 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3062 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3063 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3064 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3065 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3066 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3067 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3068 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3069 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3070 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3071 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3072 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3073 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3074 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3075 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3076 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3077 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3078 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3079 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3080 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3081 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3082 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3083 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3084 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3085 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3086 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3087 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3088 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3089 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3090 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3091 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3092 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3093 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3094 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3095 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3096 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3097 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3098 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3099 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3100 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3101 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3102 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3103 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3104 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3105 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3106 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3107 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3108 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3109 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3110 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3111 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3112 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3113 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3114 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3115 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3116 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3121 * ALC880 codec presets
3123 static struct alc_config_preset alc880_presets[] = {
3125 .mixers = { alc880_three_stack_mixer },
3126 .init_verbs = { alc880_volume_init_verbs,
3127 alc880_pin_3stack_init_verbs },
3128 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3129 .dac_nids = alc880_dac_nids,
3130 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3131 .channel_mode = alc880_threestack_modes,
3133 .input_mux = &alc880_capture_source,
3135 [ALC880_3ST_DIG] = {
3136 .mixers = { alc880_three_stack_mixer },
3137 .init_verbs = { alc880_volume_init_verbs,
3138 alc880_pin_3stack_init_verbs },
3139 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3140 .dac_nids = alc880_dac_nids,
3141 .dig_out_nid = ALC880_DIGOUT_NID,
3142 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3143 .channel_mode = alc880_threestack_modes,
3145 .input_mux = &alc880_capture_source,
3147 [ALC880_TCL_S700] = {
3148 .mixers = { alc880_tcl_s700_mixer },
3149 .init_verbs = { alc880_volume_init_verbs,
3150 alc880_pin_tcl_S700_init_verbs,
3151 alc880_gpio2_init_verbs },
3152 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3153 .dac_nids = alc880_dac_nids,
3155 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3156 .channel_mode = alc880_2_jack_modes,
3157 .input_mux = &alc880_capture_source,
3160 .mixers = { alc880_three_stack_mixer,
3161 alc880_five_stack_mixer},
3162 .init_verbs = { alc880_volume_init_verbs,
3163 alc880_pin_5stack_init_verbs },
3164 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3165 .dac_nids = alc880_dac_nids,
3166 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3167 .channel_mode = alc880_fivestack_modes,
3168 .input_mux = &alc880_capture_source,
3170 [ALC880_5ST_DIG] = {
3171 .mixers = { alc880_three_stack_mixer,
3172 alc880_five_stack_mixer },
3173 .init_verbs = { alc880_volume_init_verbs,
3174 alc880_pin_5stack_init_verbs },
3175 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3176 .dac_nids = alc880_dac_nids,
3177 .dig_out_nid = ALC880_DIGOUT_NID,
3178 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3179 .channel_mode = alc880_fivestack_modes,
3180 .input_mux = &alc880_capture_source,
3183 .mixers = { alc880_six_stack_mixer },
3184 .init_verbs = { alc880_volume_init_verbs,
3185 alc880_pin_6stack_init_verbs },
3186 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3187 .dac_nids = alc880_6st_dac_nids,
3188 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3189 .channel_mode = alc880_sixstack_modes,
3190 .input_mux = &alc880_6stack_capture_source,
3192 [ALC880_6ST_DIG] = {
3193 .mixers = { alc880_six_stack_mixer },
3194 .init_verbs = { alc880_volume_init_verbs,
3195 alc880_pin_6stack_init_verbs },
3196 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3197 .dac_nids = alc880_6st_dac_nids,
3198 .dig_out_nid = ALC880_DIGOUT_NID,
3199 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3200 .channel_mode = alc880_sixstack_modes,
3201 .input_mux = &alc880_6stack_capture_source,
3204 .mixers = { alc880_w810_base_mixer },
3205 .init_verbs = { alc880_volume_init_verbs,
3206 alc880_pin_w810_init_verbs,
3207 alc880_gpio2_init_verbs },
3208 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3209 .dac_nids = alc880_w810_dac_nids,
3210 .dig_out_nid = ALC880_DIGOUT_NID,
3211 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3212 .channel_mode = alc880_w810_modes,
3213 .input_mux = &alc880_capture_source,
3216 .mixers = { alc880_z71v_mixer },
3217 .init_verbs = { alc880_volume_init_verbs,
3218 alc880_pin_z71v_init_verbs },
3219 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3220 .dac_nids = alc880_z71v_dac_nids,
3221 .dig_out_nid = ALC880_DIGOUT_NID,
3223 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3224 .channel_mode = alc880_2_jack_modes,
3225 .input_mux = &alc880_capture_source,
3228 .mixers = { alc880_f1734_mixer },
3229 .init_verbs = { alc880_volume_init_verbs,
3230 alc880_pin_f1734_init_verbs },
3231 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3232 .dac_nids = alc880_f1734_dac_nids,
3234 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3235 .channel_mode = alc880_2_jack_modes,
3236 .input_mux = &alc880_f1734_capture_source,
3237 .unsol_event = alc880_uniwill_p53_unsol_event,
3238 .init_hook = alc880_uniwill_p53_hp_automute,
3241 .mixers = { alc880_asus_mixer },
3242 .init_verbs = { alc880_volume_init_verbs,
3243 alc880_pin_asus_init_verbs,
3244 alc880_gpio1_init_verbs },
3245 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3246 .dac_nids = alc880_asus_dac_nids,
3247 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3248 .channel_mode = alc880_asus_modes,
3250 .input_mux = &alc880_capture_source,
3252 [ALC880_ASUS_DIG] = {
3253 .mixers = { alc880_asus_mixer },
3254 .init_verbs = { alc880_volume_init_verbs,
3255 alc880_pin_asus_init_verbs,
3256 alc880_gpio1_init_verbs },
3257 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3258 .dac_nids = alc880_asus_dac_nids,
3259 .dig_out_nid = ALC880_DIGOUT_NID,
3260 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3261 .channel_mode = alc880_asus_modes,
3263 .input_mux = &alc880_capture_source,
3265 [ALC880_ASUS_DIG2] = {
3266 .mixers = { alc880_asus_mixer },
3267 .init_verbs = { alc880_volume_init_verbs,
3268 alc880_pin_asus_init_verbs,
3269 alc880_gpio2_init_verbs }, /* use GPIO2 */
3270 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3271 .dac_nids = alc880_asus_dac_nids,
3272 .dig_out_nid = ALC880_DIGOUT_NID,
3273 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3274 .channel_mode = alc880_asus_modes,
3276 .input_mux = &alc880_capture_source,
3278 [ALC880_ASUS_W1V] = {
3279 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3280 .init_verbs = { alc880_volume_init_verbs,
3281 alc880_pin_asus_init_verbs,
3282 alc880_gpio1_init_verbs },
3283 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3284 .dac_nids = alc880_asus_dac_nids,
3285 .dig_out_nid = ALC880_DIGOUT_NID,
3286 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3287 .channel_mode = alc880_asus_modes,
3289 .input_mux = &alc880_capture_source,
3291 [ALC880_UNIWILL_DIG] = {
3292 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3293 .init_verbs = { alc880_volume_init_verbs,
3294 alc880_pin_asus_init_verbs },
3295 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3296 .dac_nids = alc880_asus_dac_nids,
3297 .dig_out_nid = ALC880_DIGOUT_NID,
3298 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3299 .channel_mode = alc880_asus_modes,
3301 .input_mux = &alc880_capture_source,
3303 [ALC880_UNIWILL] = {
3304 .mixers = { alc880_uniwill_mixer },
3305 .init_verbs = { alc880_volume_init_verbs,
3306 alc880_uniwill_init_verbs },
3307 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3308 .dac_nids = alc880_asus_dac_nids,
3309 .dig_out_nid = ALC880_DIGOUT_NID,
3310 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3311 .channel_mode = alc880_threestack_modes,
3313 .input_mux = &alc880_capture_source,
3314 .unsol_event = alc880_uniwill_unsol_event,
3315 .init_hook = alc880_uniwill_automute,
3317 [ALC880_UNIWILL_P53] = {
3318 .mixers = { alc880_uniwill_p53_mixer },
3319 .init_verbs = { alc880_volume_init_verbs,
3320 alc880_uniwill_p53_init_verbs },
3321 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3322 .dac_nids = alc880_asus_dac_nids,
3323 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3324 .channel_mode = alc880_threestack_modes,
3325 .input_mux = &alc880_capture_source,
3326 .unsol_event = alc880_uniwill_p53_unsol_event,
3327 .init_hook = alc880_uniwill_p53_hp_automute,
3329 [ALC880_FUJITSU] = {
3330 .mixers = { alc880_fujitsu_mixer,
3331 alc880_pcbeep_mixer, },
3332 .init_verbs = { alc880_volume_init_verbs,
3333 alc880_uniwill_p53_init_verbs,
3334 alc880_beep_init_verbs },
3335 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3336 .dac_nids = alc880_dac_nids,
3337 .dig_out_nid = ALC880_DIGOUT_NID,
3338 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3339 .channel_mode = alc880_2_jack_modes,
3340 .input_mux = &alc880_capture_source,
3341 .unsol_event = alc880_uniwill_p53_unsol_event,
3342 .init_hook = alc880_uniwill_p53_hp_automute,
3345 .mixers = { alc880_three_stack_mixer },
3346 .init_verbs = { alc880_volume_init_verbs,
3347 alc880_pin_clevo_init_verbs },
3348 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3349 .dac_nids = alc880_dac_nids,
3351 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3352 .channel_mode = alc880_threestack_modes,
3354 .input_mux = &alc880_capture_source,
3357 .mixers = { alc880_lg_mixer },
3358 .init_verbs = { alc880_volume_init_verbs,
3359 alc880_lg_init_verbs },
3360 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3361 .dac_nids = alc880_lg_dac_nids,
3362 .dig_out_nid = ALC880_DIGOUT_NID,
3363 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3364 .channel_mode = alc880_lg_ch_modes,
3366 .input_mux = &alc880_lg_capture_source,
3367 .unsol_event = alc880_lg_unsol_event,
3368 .init_hook = alc880_lg_automute,
3369 #ifdef CONFIG_SND_HDA_POWER_SAVE
3370 .loopbacks = alc880_lg_loopbacks,
3374 .mixers = { alc880_lg_lw_mixer },
3375 .init_verbs = { alc880_volume_init_verbs,
3376 alc880_lg_lw_init_verbs },
3377 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3378 .dac_nids = alc880_dac_nids,
3379 .dig_out_nid = ALC880_DIGOUT_NID,
3380 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3381 .channel_mode = alc880_lg_lw_modes,
3382 .input_mux = &alc880_lg_lw_capture_source,
3383 .unsol_event = alc880_lg_lw_unsol_event,
3384 .init_hook = alc880_lg_lw_automute,
3386 [ALC880_MEDION_RIM] = {
3387 .mixers = { alc880_medion_rim_mixer },
3388 .init_verbs = { alc880_volume_init_verbs,
3389 alc880_medion_rim_init_verbs,
3390 alc_gpio2_init_verbs },
3391 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3392 .dac_nids = alc880_dac_nids,
3393 .dig_out_nid = ALC880_DIGOUT_NID,
3394 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3395 .channel_mode = alc880_2_jack_modes,
3396 .input_mux = &alc880_medion_rim_capture_source,
3397 .unsol_event = alc880_medion_rim_unsol_event,
3398 .init_hook = alc880_medion_rim_automute,
3400 #ifdef CONFIG_SND_DEBUG
3402 .mixers = { alc880_test_mixer },
3403 .init_verbs = { alc880_test_init_verbs },
3404 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3405 .dac_nids = alc880_test_dac_nids,
3406 .dig_out_nid = ALC880_DIGOUT_NID,
3407 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3408 .channel_mode = alc880_test_modes,
3409 .input_mux = &alc880_test_capture_source,
3415 * Automatic parse of I/O pins from the BIOS configuration
3418 #define NUM_CONTROL_ALLOC 32
3419 #define NUM_VERB_ALLOC 32
3423 ALC_CTL_WIDGET_MUTE,
3426 static struct snd_kcontrol_new alc880_control_templates[] = {
3427 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3428 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3429 HDA_BIND_MUTE(NULL, 0, 0, 0),
3432 /* add dynamic controls */
3433 static int add_control(struct alc_spec *spec, int type, const char *name,
3436 struct snd_kcontrol_new *knew;
3438 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3439 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3441 /* array + terminator */
3442 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3445 if (spec->kctl_alloc) {
3446 memcpy(knew, spec->kctl_alloc,
3447 sizeof(*knew) * spec->num_kctl_alloc);
3448 kfree(spec->kctl_alloc);
3450 spec->kctl_alloc = knew;
3451 spec->num_kctl_alloc = num;
3454 knew = &spec->kctl_alloc[spec->num_kctl_used];
3455 *knew = alc880_control_templates[type];
3456 knew->name = kstrdup(name, GFP_KERNEL);
3459 knew->private_value = val;
3460 spec->num_kctl_used++;
3464 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3465 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3466 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3467 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3468 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3469 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3470 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3471 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3472 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3473 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3474 #define ALC880_PIN_CD_NID 0x1c
3476 /* fill in the dac_nids table from the parsed pin configuration */
3477 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3478 const struct auto_pin_cfg *cfg)
3484 memset(assigned, 0, sizeof(assigned));
3485 spec->multiout.dac_nids = spec->private_dac_nids;
3487 /* check the pins hardwired to audio widget */
3488 for (i = 0; i < cfg->line_outs; i++) {
3489 nid = cfg->line_out_pins[i];
3490 if (alc880_is_fixed_pin(nid)) {
3491 int idx = alc880_fixed_pin_idx(nid);
3492 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3496 /* left pins can be connect to any audio widget */
3497 for (i = 0; i < cfg->line_outs; i++) {
3498 nid = cfg->line_out_pins[i];
3499 if (alc880_is_fixed_pin(nid))
3501 /* search for an empty channel */
3502 for (j = 0; j < cfg->line_outs; j++) {
3504 spec->multiout.dac_nids[i] =
3505 alc880_idx_to_dac(j);
3511 spec->multiout.num_dacs = cfg->line_outs;
3515 /* add playback controls from the parsed DAC table */
3516 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3517 const struct auto_pin_cfg *cfg)
3520 static const char *chname[4] = {
3521 "Front", "Surround", NULL /*CLFE*/, "Side"
3526 for (i = 0; i < cfg->line_outs; i++) {
3527 if (!spec->multiout.dac_nids[i])
3529 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3532 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3533 "Center Playback Volume",
3534 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3538 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3539 "LFE Playback Volume",
3540 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3544 err = add_control(spec, ALC_CTL_BIND_MUTE,
3545 "Center Playback Switch",
3546 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3550 err = add_control(spec, ALC_CTL_BIND_MUTE,
3551 "LFE Playback Switch",
3552 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3557 sprintf(name, "%s Playback Volume", chname[i]);
3558 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3559 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3563 sprintf(name, "%s Playback Switch", chname[i]);
3564 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3565 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3574 /* add playback controls for speaker and HP outputs */
3575 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3585 if (alc880_is_fixed_pin(pin)) {
3586 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3587 /* specify the DAC as the extra output */
3588 if (!spec->multiout.hp_nid)
3589 spec->multiout.hp_nid = nid;
3591 spec->multiout.extra_out_nid[0] = nid;
3592 /* control HP volume/switch on the output mixer amp */
3593 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3594 sprintf(name, "%s Playback Volume", pfx);
3595 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3596 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3599 sprintf(name, "%s Playback Switch", pfx);
3600 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3601 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3604 } else if (alc880_is_multi_pin(pin)) {
3605 /* set manual connection */
3606 /* we have only a switch on HP-out PIN */
3607 sprintf(name, "%s Playback Switch", pfx);
3608 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3609 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3616 /* create input playback/capture controls for the given pin */
3617 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3618 const char *ctlname,
3619 int idx, hda_nid_t mix_nid)
3624 sprintf(name, "%s Playback Volume", ctlname);
3625 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3626 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3629 sprintf(name, "%s Playback Switch", ctlname);
3630 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3631 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3637 /* create playback/capture controls for input pins */
3638 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3639 const struct auto_pin_cfg *cfg)
3641 struct hda_input_mux *imux = &spec->private_imux;
3644 for (i = 0; i < AUTO_PIN_LAST; i++) {
3645 if (alc880_is_input_pin(cfg->input_pins[i])) {
3646 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3647 err = new_analog_input(spec, cfg->input_pins[i],
3648 auto_pin_cfg_labels[i],
3652 imux->items[imux->num_items].label =
3653 auto_pin_cfg_labels[i];
3654 imux->items[imux->num_items].index =
3655 alc880_input_pin_idx(cfg->input_pins[i]);
3662 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3663 unsigned int pin_type)
3665 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3668 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3672 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3673 hda_nid_t nid, int pin_type,
3676 alc_set_pin_output(codec, nid, pin_type);
3677 /* need the manual connection? */
3678 if (alc880_is_multi_pin(nid)) {
3679 struct alc_spec *spec = codec->spec;
3680 int idx = alc880_multi_pin_idx(nid);
3681 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3682 AC_VERB_SET_CONNECT_SEL,
3683 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3687 static int get_pin_type(int line_out_type)
3689 if (line_out_type == AUTO_PIN_HP_OUT)
3695 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3697 struct alc_spec *spec = codec->spec;
3700 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3701 for (i = 0; i < spec->autocfg.line_outs; i++) {
3702 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3703 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3704 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3708 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3710 struct alc_spec *spec = codec->spec;
3713 pin = spec->autocfg.speaker_pins[0];
3714 if (pin) /* connect to front */
3715 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3716 pin = spec->autocfg.hp_pins[0];
3717 if (pin) /* connect to front */
3718 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3721 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3723 struct alc_spec *spec = codec->spec;
3726 for (i = 0; i < AUTO_PIN_LAST; i++) {
3727 hda_nid_t nid = spec->autocfg.input_pins[i];
3728 if (alc880_is_input_pin(nid)) {
3729 snd_hda_codec_write(codec, nid, 0,
3730 AC_VERB_SET_PIN_WIDGET_CONTROL,
3731 i <= AUTO_PIN_FRONT_MIC ?
3732 PIN_VREF80 : PIN_IN);
3733 if (nid != ALC880_PIN_CD_NID)
3734 snd_hda_codec_write(codec, nid, 0,
3735 AC_VERB_SET_AMP_GAIN_MUTE,
3741 /* parse the BIOS configuration and set up the alc_spec */
3742 /* return 1 if successful, 0 if the proper config is not found,
3743 * or a negative error code
3745 static int alc880_parse_auto_config(struct hda_codec *codec)
3747 struct alc_spec *spec = codec->spec;
3749 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3751 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3755 if (!spec->autocfg.line_outs)
3756 return 0; /* can't find valid BIOS pin config */
3758 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3761 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3764 err = alc880_auto_create_extra_out(spec,
3765 spec->autocfg.speaker_pins[0],
3769 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3773 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3777 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3779 if (spec->autocfg.dig_out_pin)
3780 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3781 if (spec->autocfg.dig_in_pin)
3782 spec->dig_in_nid = ALC880_DIGIN_NID;
3784 if (spec->kctl_alloc)
3785 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3787 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3789 spec->num_mux_defs = 1;
3790 spec->input_mux = &spec->private_imux;
3795 /* additional initialization for auto-configuration model */
3796 static void alc880_auto_init(struct hda_codec *codec)
3798 struct alc_spec *spec = codec->spec;
3799 alc880_auto_init_multi_out(codec);
3800 alc880_auto_init_extra_out(codec);
3801 alc880_auto_init_analog_input(codec);
3802 if (spec->unsol_event)
3803 alc_sku_automute(codec);
3807 * OK, here we have finally the patch for ALC880
3810 static int patch_alc880(struct hda_codec *codec)
3812 struct alc_spec *spec;
3816 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3822 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3825 if (board_config < 0) {
3826 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3827 "trying auto-probe from BIOS...\n");
3828 board_config = ALC880_AUTO;
3831 if (board_config == ALC880_AUTO) {
3832 /* automatic parse from the BIOS config */
3833 err = alc880_parse_auto_config(codec);
3839 "hda_codec: Cannot set up configuration "
3840 "from BIOS. Using 3-stack mode...\n");
3841 board_config = ALC880_3ST;
3845 if (board_config != ALC880_AUTO)
3846 setup_preset(spec, &alc880_presets[board_config]);
3848 spec->stream_name_analog = "ALC880 Analog";
3849 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3850 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3851 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3853 spec->stream_name_digital = "ALC880 Digital";
3854 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3855 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3857 if (!spec->adc_nids && spec->input_mux) {
3858 /* check whether NID 0x07 is valid */
3859 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3861 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3862 if (wcap != AC_WID_AUD_IN) {
3863 spec->adc_nids = alc880_adc_nids_alt;
3864 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3865 spec->mixers[spec->num_mixers] =
3866 alc880_capture_alt_mixer;
3869 spec->adc_nids = alc880_adc_nids;
3870 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3871 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3876 spec->vmaster_nid = 0x0c;
3878 codec->patch_ops = alc_patch_ops;
3879 if (board_config == ALC880_AUTO)
3880 spec->init_hook = alc880_auto_init;
3881 #ifdef CONFIG_SND_HDA_POWER_SAVE
3882 if (!spec->loopback.amplist)
3883 spec->loopback.amplist = alc880_loopbacks;
3894 static hda_nid_t alc260_dac_nids[1] = {
3899 static hda_nid_t alc260_adc_nids[1] = {
3904 static hda_nid_t alc260_adc_nids_alt[1] = {
3909 static hda_nid_t alc260_hp_adc_nids[2] = {
3914 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3915 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3917 static hda_nid_t alc260_dual_adc_nids[2] = {
3922 #define ALC260_DIGOUT_NID 0x03
3923 #define ALC260_DIGIN_NID 0x06
3925 static struct hda_input_mux alc260_capture_source = {
3929 { "Front Mic", 0x1 },
3935 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3936 * headphone jack and the internal CD lines since these are the only pins at
3937 * which audio can appear. For flexibility, also allow the option of
3938 * recording the mixer output on the second ADC (ADC0 doesn't have a
3939 * connection to the mixer output).
3941 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3945 { "Mic/Line", 0x0 },
3947 { "Headphone", 0x2 },
3953 { "Mic/Line", 0x0 },
3955 { "Headphone", 0x2 },
3962 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3963 * the Fujitsu S702x, but jacks are marked differently.
3965 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3972 { "Headphone", 0x5 },
3981 { "Headphone", 0x6 },
3987 * This is just place-holder, so there's something for alc_build_pcms to look
3988 * at when it calculates the maximum number of channels. ALC260 has no mixer
3989 * element which allows changing the channel mode, so the verb list is
3992 static struct hda_channel_mode alc260_modes[1] = {
3997 /* Mixer combinations
3999 * basic: base_output + input + pc_beep + capture
4000 * HP: base_output + input + capture_alt
4001 * HP_3013: hp_3013 + input + capture
4002 * fujitsu: fujitsu + capture
4003 * acer: acer + capture
4006 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4007 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4008 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4009 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4010 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4011 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4012 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4016 static struct snd_kcontrol_new alc260_input_mixer[] = {
4017 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4018 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4019 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4020 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4022 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4023 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4024 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4028 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4029 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4030 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4034 /* update HP, line and mono out pins according to the master switch */
4035 static void alc260_hp_master_update(struct hda_codec *codec,
4036 hda_nid_t hp, hda_nid_t line,
4039 struct alc_spec *spec = codec->spec;
4040 unsigned int val = spec->master_sw ? PIN_HP : 0;
4041 /* change HP and line-out pins */
4042 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4044 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4046 /* mono (speaker) depending on the HP jack sense */
4047 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4048 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4052 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4053 struct snd_ctl_elem_value *ucontrol)
4055 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4056 struct alc_spec *spec = codec->spec;
4057 *ucontrol->value.integer.value = spec->master_sw;
4061 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4062 struct snd_ctl_elem_value *ucontrol)
4064 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4065 struct alc_spec *spec = codec->spec;
4066 int val = !!*ucontrol->value.integer.value;
4067 hda_nid_t hp, line, mono;
4069 if (val == spec->master_sw)
4071 spec->master_sw = val;
4072 hp = (kcontrol->private_value >> 16) & 0xff;
4073 line = (kcontrol->private_value >> 8) & 0xff;
4074 mono = kcontrol->private_value & 0xff;
4075 alc260_hp_master_update(codec, hp, line, mono);
4079 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4082 .name = "Master Playback Switch",
4083 .info = snd_ctl_boolean_mono_info,
4084 .get = alc260_hp_master_sw_get,
4085 .put = alc260_hp_master_sw_put,
4086 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4088 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4089 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4090 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4091 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4092 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4094 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4098 static struct hda_verb alc260_hp_unsol_verbs[] = {
4099 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4103 static void alc260_hp_automute(struct hda_codec *codec)
4105 struct alc_spec *spec = codec->spec;
4106 unsigned int present;
4108 present = snd_hda_codec_read(codec, 0x10, 0,
4109 AC_VERB_GET_PIN_SENSE, 0);
4110 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4111 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4114 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4116 if ((res >> 26) == ALC880_HP_EVENT)
4117 alc260_hp_automute(codec);
4120 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4122 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4123 .name = "Master Playback Switch",
4124 .info = snd_ctl_boolean_mono_info,
4125 .get = alc260_hp_master_sw_get,
4126 .put = alc260_hp_master_sw_put,
4127 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4129 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4130 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4131 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4132 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4133 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4135 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4136 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4140 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4141 .ops = &snd_hda_bind_vol,
4143 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4144 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4145 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4150 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4151 .ops = &snd_hda_bind_sw,
4153 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4154 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4159 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4160 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4161 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4162 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4167 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4168 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4172 static void alc260_hp_3013_automute(struct hda_codec *codec)
4174 struct alc_spec *spec = codec->spec;
4175 unsigned int present;
4177 present = snd_hda_codec_read(codec, 0x15, 0,
4178 AC_VERB_GET_PIN_SENSE, 0);
4179 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4180 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4183 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4186 if ((res >> 26) == ALC880_HP_EVENT)
4187 alc260_hp_3013_automute(codec);
4190 static void alc260_hp_3012_automute(struct hda_codec *codec)
4192 unsigned int present, bits;
4194 present = snd_hda_codec_read(codec, 0x10, 0,
4195 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4197 bits = present ? 0 : PIN_OUT;
4198 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4200 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4202 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4206 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4209 if ((res >> 26) == ALC880_HP_EVENT)
4210 alc260_hp_3012_automute(codec);
4213 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4214 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4216 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4217 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4218 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4219 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4220 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4221 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4222 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4223 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4224 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4225 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4226 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4227 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4228 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4232 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4233 * versions of the ALC260 don't act on requests to enable mic bias from NID
4234 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4235 * datasheet doesn't mention this restriction. At this stage it's not clear
4236 * whether this behaviour is intentional or is a hardware bug in chip
4237 * revisions available in early 2006. Therefore for now allow the
4238 * "Headphone Jack Mode" control to span all choices, but if it turns out
4239 * that the lack of mic bias for this NID is intentional we could change the
4240 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4242 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4243 * don't appear to make the mic bias available from the "line" jack, even
4244 * though the NID used for this jack (0x14) can supply it. The theory is
4245 * that perhaps Acer have included blocking capacitors between the ALC260
4246 * and the output jack. If this turns out to be the case for all such
4247 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4248 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4250 * The C20x Tablet series have a mono internal speaker which is controlled
4251 * via the chip's Mono sum widget and pin complex, so include the necessary
4252 * controls for such models. On models without a "mono speaker" the control
4253 * won't do anything.
4255 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4256 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4257 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4258 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4259 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4261 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4263 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4264 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4265 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4266 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4267 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4268 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4269 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4270 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4271 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4272 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4276 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4277 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4279 static struct snd_kcontrol_new alc260_will_mixer[] = {
4280 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4281 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4282 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4283 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4284 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4285 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4286 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4287 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4288 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4289 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4290 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4291 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4295 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4296 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4298 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4299 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4300 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4302 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4303 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4304 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4305 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4306 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4307 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4308 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4312 /* capture mixer elements */
4313 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4314 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4315 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4316 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4317 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4320 /* The multiple "Capture Source" controls confuse alsamixer
4321 * So call somewhat different..
4323 /* .name = "Capture Source", */
4324 .name = "Input Source",
4326 .info = alc_mux_enum_info,
4327 .get = alc_mux_enum_get,
4328 .put = alc_mux_enum_put,
4333 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4334 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4335 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4337 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4338 /* The multiple "Capture Source" controls confuse alsamixer
4339 * So call somewhat different..
4341 /* .name = "Capture Source", */
4342 .name = "Input Source",
4344 .info = alc_mux_enum_info,
4345 .get = alc_mux_enum_get,
4346 .put = alc_mux_enum_put,
4352 * initialization verbs
4354 static struct hda_verb alc260_init_verbs[] = {
4355 /* Line In pin widget for input */
4356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4357 /* CD pin widget for input */
4358 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4359 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4360 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4361 /* Mic2 (front panel) pin widget for input and vref at 80% */
4362 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4363 /* LINE-2 is used for line-out in rear */
4364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4365 /* select line-out */
4366 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4368 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4370 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4372 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4373 /* mute capture amp left and right */
4374 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4375 /* set connection select to line in (default select for this ADC) */
4376 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4377 /* mute capture amp left and right */
4378 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4379 /* set connection select to line in (default select for this ADC) */
4380 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4381 /* set vol=0 Line-Out mixer amp left and right */
4382 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4383 /* unmute pin widget amp left and right (no gain on this amp) */
4384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4385 /* set vol=0 HP mixer amp left and right */
4386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4387 /* unmute pin widget amp left and right (no gain on this amp) */
4388 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4389 /* set vol=0 Mono mixer amp left and right */
4390 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4391 /* unmute pin widget amp left and right (no gain on this amp) */
4392 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4393 /* unmute LINE-2 out pin */
4394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4395 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4398 /* mute analog inputs */
4399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4404 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4405 /* mute Front out path */
4406 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4408 /* mute Headphone out path */
4409 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4410 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4411 /* mute Mono out path */
4412 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4413 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4417 #if 0 /* should be identical with alc260_init_verbs? */
4418 static struct hda_verb alc260_hp_init_verbs[] = {
4419 /* Headphone and output */
4420 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4422 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4423 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4424 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4425 /* Mic2 (front panel) pin widget for input and vref at 80% */
4426 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4427 /* Line In pin widget for input */
4428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4429 /* Line-2 pin widget for output */
4430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4431 /* CD pin widget for input */
4432 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4433 /* unmute amp left and right */
4434 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4435 /* set connection select to line in (default select for this ADC) */
4436 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4437 /* unmute Line-Out mixer amp left and right (volume = 0) */
4438 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4439 /* mute pin widget amp left and right (no gain on this amp) */
4440 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4441 /* unmute HP mixer amp left and right (volume = 0) */
4442 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4443 /* mute pin widget amp left and right (no gain on this amp) */
4444 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4445 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4448 /* mute analog inputs */
4449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4454 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4455 /* Unmute Front out path */
4456 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4457 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4458 /* Unmute Headphone out path */
4459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4460 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4461 /* Unmute Mono out path */
4462 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4463 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4468 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4469 /* Line out and output */
4470 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4472 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4473 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4474 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4475 /* Mic2 (front panel) pin widget for input and vref at 80% */
4476 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4477 /* Line In pin widget for input */
4478 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4479 /* Headphone pin widget for output */
4480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4481 /* CD pin widget for input */
4482 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4483 /* unmute amp left and right */
4484 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4485 /* set connection select to line in (default select for this ADC) */
4486 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4487 /* unmute Line-Out mixer amp left and right (volume = 0) */
4488 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4489 /* mute pin widget amp left and right (no gain on this amp) */
4490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4491 /* unmute HP mixer amp left and right (volume = 0) */
4492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4493 /* mute pin widget amp left and right (no gain on this amp) */
4494 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4495 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4498 /* mute analog inputs */
4499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4504 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4505 /* Unmute Front out path */
4506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4508 /* Unmute Headphone out path */
4509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4511 /* Unmute Mono out path */
4512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4517 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4518 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4519 * audio = 0x16, internal speaker = 0x10.
4521 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4522 /* Disable all GPIOs */
4523 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4524 /* Internal speaker is connected to headphone pin */
4525 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4526 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4527 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4528 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4529 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4530 /* Ensure all other unused pins are disabled and muted. */
4531 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4532 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4533 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4534 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4535 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4536 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4540 /* Disable digital (SPDIF) pins */
4541 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4542 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4544 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4545 * when acting as an output.
4547 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4549 /* Start with output sum widgets muted and their output gains at min */
4550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4553 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4554 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4556 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4557 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4558 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4560 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4561 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4562 /* Unmute Line1 pin widget output buffer since it starts as an output.
4563 * If the pin mode is changed by the user the pin mode control will
4564 * take care of enabling the pin's input/output buffers as needed.
4565 * Therefore there's no need to enable the input buffer at this
4568 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4569 /* Unmute input buffer of pin widget used for Line-in (no equiv
4572 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4574 /* Mute capture amp left and right */
4575 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4576 /* Set ADC connection select to match default mixer setting - line
4579 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4581 /* Do the same for the second ADC: mute capture input amp and
4582 * set ADC connection to line in (on mic1 pin)
4584 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4585 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4587 /* Mute all inputs to mixer widget (even unconnected ones) */
4588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4600 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4601 * similar laptops (adapted from Fujitsu init verbs).
4603 static struct hda_verb alc260_acer_init_verbs[] = {
4604 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4605 * the headphone jack. Turn this on and rely on the standard mute
4606 * methods whenever the user wants to turn these outputs off.
4608 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4609 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4610 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4611 /* Internal speaker/Headphone jack is connected to Line-out pin */
4612 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4613 /* Internal microphone/Mic jack is connected to Mic1 pin */
4614 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4615 /* Line In jack is connected to Line1 pin */
4616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4617 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4618 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4619 /* Ensure all other unused pins are disabled and muted. */
4620 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4621 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4623 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4626 /* Disable digital (SPDIF) pins */
4627 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4628 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4630 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4631 * bus when acting as outputs.
4633 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4634 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4636 /* Start with output sum widgets muted and their output gains at min */
4637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4639 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4640 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4641 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4642 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4643 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4644 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4645 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4647 /* Unmute Line-out pin widget amp left and right
4648 * (no equiv mixer ctrl)
4650 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4651 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4652 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4653 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4654 * inputs. If the pin mode is changed by the user the pin mode control
4655 * will take care of enabling the pin's input/output buffers as needed.
4656 * Therefore there's no need to enable the input buffer at this
4659 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4660 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4662 /* Mute capture amp left and right */
4663 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4664 /* Set ADC connection select to match default mixer setting - mic
4667 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4669 /* Do similar with the second ADC: mute capture input amp and
4670 * set ADC connection to mic to match ALSA's default state.
4672 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4673 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4675 /* Mute all inputs to mixer widget (even unconnected ones) */
4676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4688 static struct hda_verb alc260_will_verbs[] = {
4689 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4690 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4691 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4692 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4693 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4694 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4698 static struct hda_verb alc260_replacer_672v_verbs[] = {
4699 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4700 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4701 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4703 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4704 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4705 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4707 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4711 /* toggle speaker-output according to the hp-jack state */
4712 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4714 unsigned int present;
4716 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4717 present = snd_hda_codec_read(codec, 0x0f, 0,
4718 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4720 snd_hda_codec_write_cache(codec, 0x01, 0,
4721 AC_VERB_SET_GPIO_DATA, 1);
4722 snd_hda_codec_write_cache(codec, 0x0f, 0,
4723 AC_VERB_SET_PIN_WIDGET_CONTROL,
4726 snd_hda_codec_write_cache(codec, 0x01, 0,
4727 AC_VERB_SET_GPIO_DATA, 0);
4728 snd_hda_codec_write_cache(codec, 0x0f, 0,
4729 AC_VERB_SET_PIN_WIDGET_CONTROL,
4734 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4737 if ((res >> 26) == ALC880_HP_EVENT)
4738 alc260_replacer_672v_automute(codec);
4741 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4742 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4744 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4745 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4746 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4748 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4749 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4750 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4751 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4755 /* Test configuration for debugging, modelled after the ALC880 test
4758 #ifdef CONFIG_SND_DEBUG
4759 static hda_nid_t alc260_test_dac_nids[1] = {
4762 static hda_nid_t alc260_test_adc_nids[2] = {
4765 /* For testing the ALC260, each input MUX needs its own definition since
4766 * the signal assignments are different. This assumes that the first ADC
4769 static struct hda_input_mux alc260_test_capture_sources[2] = {
4773 { "MIC1 pin", 0x0 },
4774 { "MIC2 pin", 0x1 },
4775 { "LINE1 pin", 0x2 },
4776 { "LINE2 pin", 0x3 },
4778 { "LINE-OUT pin", 0x5 },
4779 { "HP-OUT pin", 0x6 },
4785 { "MIC1 pin", 0x0 },
4786 { "MIC2 pin", 0x1 },
4787 { "LINE1 pin", 0x2 },
4788 { "LINE2 pin", 0x3 },
4791 { "LINE-OUT pin", 0x6 },
4792 { "HP-OUT pin", 0x7 },
4796 static struct snd_kcontrol_new alc260_test_mixer[] = {
4797 /* Output driver widgets */
4798 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4799 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4800 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4801 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4802 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4803 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4805 /* Modes for retasking pin widgets
4806 * Note: the ALC260 doesn't seem to act on requests to enable mic
4807 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4808 * mention this restriction. At this stage it's not clear whether
4809 * this behaviour is intentional or is a hardware bug in chip
4810 * revisions available at least up until early 2006. Therefore for
4811 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4812 * choices, but if it turns out that the lack of mic bias for these
4813 * NIDs is intentional we could change their modes from
4814 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4816 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4817 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4818 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4819 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4820 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4821 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4823 /* Loopback mixer controls */
4824 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4825 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4826 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4827 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4828 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4829 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4830 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4831 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4832 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4833 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4834 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4835 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4836 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4837 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4838 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4839 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4841 /* Controls for GPIO pins, assuming they are configured as outputs */
4842 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4843 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4844 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4845 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4847 /* Switches to allow the digital IO pins to be enabled. The datasheet
4848 * is ambigious as to which NID is which; testing on laptops which
4849 * make this output available should provide clarification.
4851 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4852 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4854 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4855 * this output to turn on an external amplifier.
4857 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4858 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4862 static struct hda_verb alc260_test_init_verbs[] = {
4863 /* Enable all GPIOs as outputs with an initial value of 0 */
4864 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4865 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4866 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4868 /* Enable retasking pins as output, initially without power amp */
4869 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4870 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4873 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4874 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4876 /* Disable digital (SPDIF) pins initially, but users can enable
4877 * them via a mixer switch. In the case of SPDIF-out, this initverb
4878 * payload also sets the generation to 0, output to be in "consumer"
4879 * PCM format, copyright asserted, no pre-emphasis and no validity
4882 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4883 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4885 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4886 * OUT1 sum bus when acting as an output.
4888 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4889 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4890 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4891 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4893 /* Start with output sum widgets muted and their output gains at min */
4894 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4895 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4896 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4897 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4898 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4899 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4900 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4901 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4902 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904 /* Unmute retasking pin widget output buffers since the default
4905 * state appears to be output. As the pin mode is changed by the
4906 * user the pin mode control will take care of enabling the pin's
4907 * input/output buffers as needed.
4909 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4910 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4913 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4914 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4915 /* Also unmute the mono-out pin widget */
4916 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4918 /* Mute capture amp left and right */
4919 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4920 /* Set ADC connection select to match default mixer setting (mic1
4923 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4925 /* Do the same for the second ADC: mute capture input amp and
4926 * set ADC connection to mic1 pin
4928 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4929 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4931 /* Mute all inputs to mixer widget (even unconnected ones) */
4932 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4933 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4934 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4935 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4937 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4938 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4945 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4946 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4948 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4949 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4952 * for BIOS auto-configuration
4955 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4959 unsigned long vol_val, sw_val;
4963 if (nid >= 0x0f && nid < 0x11) {
4964 nid_vol = nid - 0x7;
4965 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4966 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4967 } else if (nid == 0x11) {
4968 nid_vol = nid - 0x7;
4969 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4970 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4971 } else if (nid >= 0x12 && nid <= 0x15) {
4973 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4974 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4978 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4979 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4982 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4983 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4989 /* add playback controls from the parsed DAC table */
4990 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4991 const struct auto_pin_cfg *cfg)
4996 spec->multiout.num_dacs = 1;
4997 spec->multiout.dac_nids = spec->private_dac_nids;
4998 spec->multiout.dac_nids[0] = 0x02;
5000 nid = cfg->line_out_pins[0];
5002 err = alc260_add_playback_controls(spec, nid, "Front");
5007 nid = cfg->speaker_pins[0];
5009 err = alc260_add_playback_controls(spec, nid, "Speaker");
5014 nid = cfg->hp_pins[0];
5016 err = alc260_add_playback_controls(spec, nid, "Headphone");
5023 /* create playback/capture controls for input pins */
5024 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5025 const struct auto_pin_cfg *cfg)
5027 struct hda_input_mux *imux = &spec->private_imux;
5030 for (i = 0; i < AUTO_PIN_LAST; i++) {
5031 if (cfg->input_pins[i] >= 0x12) {
5032 idx = cfg->input_pins[i] - 0x12;
5033 err = new_analog_input(spec, cfg->input_pins[i],
5034 auto_pin_cfg_labels[i], idx,
5038 imux->items[imux->num_items].label =
5039 auto_pin_cfg_labels[i];
5040 imux->items[imux->num_items].index = idx;
5043 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5044 idx = cfg->input_pins[i] - 0x09;
5045 err = new_analog_input(spec, cfg->input_pins[i],
5046 auto_pin_cfg_labels[i], idx,
5050 imux->items[imux->num_items].label =
5051 auto_pin_cfg_labels[i];
5052 imux->items[imux->num_items].index = idx;
5059 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5060 hda_nid_t nid, int pin_type,
5063 alc_set_pin_output(codec, nid, pin_type);
5064 /* need the manual connection? */
5066 int idx = nid - 0x12;
5067 snd_hda_codec_write(codec, idx + 0x0b, 0,
5068 AC_VERB_SET_CONNECT_SEL, sel_idx);
5072 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5074 struct alc_spec *spec = codec->spec;
5077 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5078 nid = spec->autocfg.line_out_pins[0];
5080 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5081 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5084 nid = spec->autocfg.speaker_pins[0];
5086 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5088 nid = spec->autocfg.hp_pins[0];
5090 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5093 #define ALC260_PIN_CD_NID 0x16
5094 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5096 struct alc_spec *spec = codec->spec;
5099 for (i = 0; i < AUTO_PIN_LAST; i++) {
5100 hda_nid_t nid = spec->autocfg.input_pins[i];
5102 snd_hda_codec_write(codec, nid, 0,
5103 AC_VERB_SET_PIN_WIDGET_CONTROL,
5104 i <= AUTO_PIN_FRONT_MIC ?
5105 PIN_VREF80 : PIN_IN);
5106 if (nid != ALC260_PIN_CD_NID)
5107 snd_hda_codec_write(codec, nid, 0,
5108 AC_VERB_SET_AMP_GAIN_MUTE,
5115 * generic initialization of ADC, input mixers and output mixers
5117 static struct hda_verb alc260_volume_init_verbs[] = {
5119 * Unmute ADC0-1 and set the default input to mic-in
5121 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5122 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5123 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5124 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5126 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5128 * Note: PASD motherboards uses the Line In 2 as the input for
5129 * front panel mic (mic 2)
5131 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5132 /* mute analog inputs */
5133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5134 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5140 * Set up output mixers (0x08 - 0x0a)
5142 /* set vol=0 to output mixers */
5143 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5145 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5146 /* set up input amps for analog loopback */
5147 /* Amp Indices: DAC = 0, mixer = 1 */
5148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5152 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5158 static int alc260_parse_auto_config(struct hda_codec *codec)
5160 struct alc_spec *spec = codec->spec;
5163 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5165 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5169 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5172 if (!spec->kctl_alloc)
5173 return 0; /* can't find valid BIOS pin config */
5174 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5178 spec->multiout.max_channels = 2;
5180 if (spec->autocfg.dig_out_pin)
5181 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5182 if (spec->kctl_alloc)
5183 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5185 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5187 spec->num_mux_defs = 1;
5188 spec->input_mux = &spec->private_imux;
5190 /* check whether NID 0x04 is valid */
5191 wcap = get_wcaps(codec, 0x04);
5192 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5193 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5194 spec->adc_nids = alc260_adc_nids_alt;
5195 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5196 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5198 spec->adc_nids = alc260_adc_nids;
5199 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5200 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5207 /* additional initialization for auto-configuration model */
5208 static void alc260_auto_init(struct hda_codec *codec)
5210 struct alc_spec *spec = codec->spec;
5211 alc260_auto_init_multi_out(codec);
5212 alc260_auto_init_analog_input(codec);
5213 if (spec->unsol_event)
5214 alc_sku_automute(codec);
5217 #ifdef CONFIG_SND_HDA_POWER_SAVE
5218 static struct hda_amp_list alc260_loopbacks[] = {
5219 { 0x07, HDA_INPUT, 0 },
5220 { 0x07, HDA_INPUT, 1 },
5221 { 0x07, HDA_INPUT, 2 },
5222 { 0x07, HDA_INPUT, 3 },
5223 { 0x07, HDA_INPUT, 4 },
5229 * ALC260 configurations
5231 static const char *alc260_models[ALC260_MODEL_LAST] = {
5232 [ALC260_BASIC] = "basic",
5234 [ALC260_HP_3013] = "hp-3013",
5235 [ALC260_FUJITSU_S702X] = "fujitsu",
5236 [ALC260_ACER] = "acer",
5237 [ALC260_WILL] = "will",
5238 [ALC260_REPLACER_672V] = "replacer",
5239 #ifdef CONFIG_SND_DEBUG
5240 [ALC260_TEST] = "test",
5242 [ALC260_AUTO] = "auto",
5245 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5246 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5247 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5248 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5249 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5250 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5251 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5252 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5253 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5254 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5255 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5256 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5257 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5258 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5259 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5260 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5261 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5262 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5263 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5267 static struct alc_config_preset alc260_presets[] = {
5269 .mixers = { alc260_base_output_mixer,
5271 alc260_pc_beep_mixer,
5272 alc260_capture_mixer },
5273 .init_verbs = { alc260_init_verbs },
5274 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5275 .dac_nids = alc260_dac_nids,
5276 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5277 .adc_nids = alc260_adc_nids,
5278 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5279 .channel_mode = alc260_modes,
5280 .input_mux = &alc260_capture_source,
5283 .mixers = { alc260_hp_output_mixer,
5285 alc260_capture_alt_mixer },
5286 .init_verbs = { alc260_init_verbs,
5287 alc260_hp_unsol_verbs },
5288 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5289 .dac_nids = alc260_dac_nids,
5290 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5291 .adc_nids = alc260_hp_adc_nids,
5292 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5293 .channel_mode = alc260_modes,
5294 .input_mux = &alc260_capture_source,
5295 .unsol_event = alc260_hp_unsol_event,
5296 .init_hook = alc260_hp_automute,
5298 [ALC260_HP_DC7600] = {
5299 .mixers = { alc260_hp_dc7600_mixer,
5301 alc260_capture_alt_mixer },
5302 .init_verbs = { alc260_init_verbs,
5303 alc260_hp_dc7600_verbs },
5304 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5305 .dac_nids = alc260_dac_nids,
5306 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5307 .adc_nids = alc260_hp_adc_nids,
5308 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5309 .channel_mode = alc260_modes,
5310 .input_mux = &alc260_capture_source,
5311 .unsol_event = alc260_hp_3012_unsol_event,
5312 .init_hook = alc260_hp_3012_automute,
5314 [ALC260_HP_3013] = {
5315 .mixers = { alc260_hp_3013_mixer,
5317 alc260_capture_alt_mixer },
5318 .init_verbs = { alc260_hp_3013_init_verbs,
5319 alc260_hp_3013_unsol_verbs },
5320 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5321 .dac_nids = alc260_dac_nids,
5322 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5323 .adc_nids = alc260_hp_adc_nids,
5324 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5325 .channel_mode = alc260_modes,
5326 .input_mux = &alc260_capture_source,
5327 .unsol_event = alc260_hp_3013_unsol_event,
5328 .init_hook = alc260_hp_3013_automute,
5330 [ALC260_FUJITSU_S702X] = {
5331 .mixers = { alc260_fujitsu_mixer,
5332 alc260_capture_mixer },
5333 .init_verbs = { alc260_fujitsu_init_verbs },
5334 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5335 .dac_nids = alc260_dac_nids,
5336 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5337 .adc_nids = alc260_dual_adc_nids,
5338 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5339 .channel_mode = alc260_modes,
5340 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5341 .input_mux = alc260_fujitsu_capture_sources,
5344 .mixers = { alc260_acer_mixer,
5345 alc260_capture_mixer },
5346 .init_verbs = { alc260_acer_init_verbs },
5347 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5348 .dac_nids = alc260_dac_nids,
5349 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5350 .adc_nids = alc260_dual_adc_nids,
5351 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5352 .channel_mode = alc260_modes,
5353 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5354 .input_mux = alc260_acer_capture_sources,
5357 .mixers = { alc260_will_mixer,
5358 alc260_capture_mixer },
5359 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5360 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5361 .dac_nids = alc260_dac_nids,
5362 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5363 .adc_nids = alc260_adc_nids,
5364 .dig_out_nid = ALC260_DIGOUT_NID,
5365 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5366 .channel_mode = alc260_modes,
5367 .input_mux = &alc260_capture_source,
5369 [ALC260_REPLACER_672V] = {
5370 .mixers = { alc260_replacer_672v_mixer,
5371 alc260_capture_mixer },
5372 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5373 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5374 .dac_nids = alc260_dac_nids,
5375 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5376 .adc_nids = alc260_adc_nids,
5377 .dig_out_nid = ALC260_DIGOUT_NID,
5378 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5379 .channel_mode = alc260_modes,
5380 .input_mux = &alc260_capture_source,
5381 .unsol_event = alc260_replacer_672v_unsol_event,
5382 .init_hook = alc260_replacer_672v_automute,
5384 #ifdef CONFIG_SND_DEBUG
5386 .mixers = { alc260_test_mixer,
5387 alc260_capture_mixer },
5388 .init_verbs = { alc260_test_init_verbs },
5389 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5390 .dac_nids = alc260_test_dac_nids,
5391 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5392 .adc_nids = alc260_test_adc_nids,
5393 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5394 .channel_mode = alc260_modes,
5395 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5396 .input_mux = alc260_test_capture_sources,
5401 static int patch_alc260(struct hda_codec *codec)
5403 struct alc_spec *spec;
5404 int err, board_config;
5406 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5412 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5415 if (board_config < 0) {
5416 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5417 "trying auto-probe from BIOS...\n");
5418 board_config = ALC260_AUTO;
5421 if (board_config == ALC260_AUTO) {
5422 /* automatic parse from the BIOS config */
5423 err = alc260_parse_auto_config(codec);
5429 "hda_codec: Cannot set up configuration "
5430 "from BIOS. Using base mode...\n");
5431 board_config = ALC260_BASIC;
5435 if (board_config != ALC260_AUTO)
5436 setup_preset(spec, &alc260_presets[board_config]);
5438 spec->stream_name_analog = "ALC260 Analog";
5439 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5440 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5442 spec->stream_name_digital = "ALC260 Digital";
5443 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5444 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5446 spec->vmaster_nid = 0x08;
5448 codec->patch_ops = alc_patch_ops;
5449 if (board_config == ALC260_AUTO)
5450 spec->init_hook = alc260_auto_init;
5451 #ifdef CONFIG_SND_HDA_POWER_SAVE
5452 if (!spec->loopback.amplist)
5453 spec->loopback.amplist = alc260_loopbacks;
5463 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5464 * configuration. Each pin widget can choose any input DACs and a mixer.
5465 * Each ADC is connected from a mixer of all inputs. This makes possible
5466 * 6-channel independent captures.
5468 * In addition, an independent DAC for the multi-playback (not used in this
5471 #define ALC882_DIGOUT_NID 0x06
5472 #define ALC882_DIGIN_NID 0x0a
5474 static struct hda_channel_mode alc882_ch_modes[1] = {
5478 static hda_nid_t alc882_dac_nids[4] = {
5479 /* front, rear, clfe, rear_surr */
5480 0x02, 0x03, 0x04, 0x05
5483 /* identical with ALC880 */
5484 #define alc882_adc_nids alc880_adc_nids
5485 #define alc882_adc_nids_alt alc880_adc_nids_alt
5487 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5488 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5491 /* FIXME: should be a matrix-type input source selection */
5493 static struct hda_input_mux alc882_capture_source = {
5497 { "Front Mic", 0x1 },
5502 #define alc882_mux_enum_info alc_mux_enum_info
5503 #define alc882_mux_enum_get alc_mux_enum_get
5505 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5506 struct snd_ctl_elem_value *ucontrol)
5508 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5509 struct alc_spec *spec = codec->spec;
5510 const struct hda_input_mux *imux = spec->input_mux;
5511 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5512 hda_nid_t nid = spec->capsrc_nids ?
5513 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5514 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5515 unsigned int i, idx;
5517 idx = ucontrol->value.enumerated.item[0];
5518 if (idx >= imux->num_items)
5519 idx = imux->num_items - 1;
5520 if (*cur_val == idx)
5522 for (i = 0; i < imux->num_items; i++) {
5523 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5524 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5525 imux->items[i].index,
5535 static struct hda_verb alc882_3ST_ch2_init[] = {
5536 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5537 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5538 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5539 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5546 static struct hda_verb alc882_3ST_ch6_init[] = {
5547 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5548 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5549 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5550 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5551 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5552 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5556 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5557 { 2, alc882_3ST_ch2_init },
5558 { 6, alc882_3ST_ch6_init },
5564 static struct hda_verb alc882_sixstack_ch6_init[] = {
5565 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5566 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5567 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5568 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5575 static struct hda_verb alc882_sixstack_ch8_init[] = {
5576 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5577 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5578 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5579 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5583 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5584 { 6, alc882_sixstack_ch6_init },
5585 { 8, alc882_sixstack_ch8_init },
5589 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5595 static struct hda_verb alc885_mbp_ch2_init[] = {
5596 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5597 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5598 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5605 static struct hda_verb alc885_mbp_ch6_init[] = {
5606 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5607 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5608 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5609 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5610 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5614 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5615 { 2, alc885_mbp_ch2_init },
5616 { 6, alc885_mbp_ch6_init },
5620 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5621 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5623 static struct snd_kcontrol_new alc882_base_mixer[] = {
5624 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5625 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5626 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5627 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5628 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5629 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5630 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5631 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5632 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5633 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5635 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5636 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5638 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5640 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5643 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5644 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5645 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5646 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5650 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5651 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5652 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5653 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5654 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5656 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5658 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5659 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5660 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5663 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5664 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5665 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5671 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5673 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5674 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5678 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5679 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5680 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5681 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5682 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5683 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5684 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5685 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5686 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5688 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5689 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5691 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5695 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5696 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5698 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5699 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5700 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5701 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5702 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5703 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5704 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5707 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5708 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5711 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5715 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5716 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5717 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5719 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5720 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5724 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5725 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5726 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5727 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5731 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5734 .name = "Channel Mode",
5735 .info = alc_ch_mode_info,
5736 .get = alc_ch_mode_get,
5737 .put = alc_ch_mode_put,
5742 static struct hda_verb alc882_init_verbs[] = {
5743 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5750 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5753 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5754 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5760 /* Front Pin: output 0 (0x0c) */
5761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5762 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5763 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5764 /* Rear Pin: output 1 (0x0d) */
5765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5767 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5768 /* CLFE Pin: output 2 (0x0e) */
5769 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5770 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5771 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5772 /* Side Pin: output 3 (0x0f) */
5773 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5774 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5775 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5776 /* Mic (rear) pin: input vref at 80% */
5777 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5778 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5779 /* Front Mic pin: input vref at 80% */
5780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5782 /* Line In pin: input */
5783 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5785 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5787 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5788 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5789 /* CD pin widget for input */
5790 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5792 /* FIXME: use matrix-type input source selection */
5793 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5794 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5795 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5796 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5797 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5798 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5800 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5801 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5802 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5803 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5805 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5806 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5807 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5809 /* ADC1: mute amp left and right */
5810 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5811 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5812 /* ADC2: mute amp left and right */
5813 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5814 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5815 /* ADC3: mute amp left and right */
5816 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5817 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5822 static struct hda_verb alc882_eapd_verbs[] = {
5823 /* change to EAPD mode */
5824 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5825 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5830 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5831 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5832 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5834 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5835 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5836 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5837 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5841 static struct hda_verb alc882_macpro_init_verbs[] = {
5842 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5846 /* Front Pin: output 0 (0x0c) */
5847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5849 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5850 /* Front Mic pin: input vref at 80% */
5851 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5852 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5853 /* Speaker: output */
5854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5856 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5857 /* Headphone output (output 0 - 0x0c) */
5858 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5860 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5862 /* FIXME: use matrix-type input source selection */
5863 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5864 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5865 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5866 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5867 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5870 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5871 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5872 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5873 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5879 /* ADC1: mute amp left and right */
5880 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5881 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5882 /* ADC2: mute amp left and right */
5883 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5884 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5885 /* ADC3: mute amp left and right */
5886 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5887 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5892 /* Macbook Pro rev3 */
5893 static struct hda_verb alc885_mbp3_init_verbs[] = {
5894 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5895 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5896 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5897 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5899 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5900 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5901 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5902 /* Front Pin: output 0 (0x0c) */
5903 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5904 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5905 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5906 /* HP Pin: output 0 (0x0d) */
5907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5909 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5910 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5911 /* Mic (rear) pin: input vref at 80% */
5912 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5913 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5914 /* Front Mic pin: input vref at 80% */
5915 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5916 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5917 /* Line In pin: use output 1 when in LineOut mode */
5918 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5920 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5922 /* FIXME: use matrix-type input source selection */
5923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5924 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5925 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5939 /* ADC1: mute amp left and right */
5940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5941 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5942 /* ADC2: mute amp left and right */
5943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5944 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5945 /* ADC3: mute amp left and right */
5946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5947 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5952 /* iMac 24 mixer. */
5953 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5954 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5955 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5959 /* iMac 24 init verbs. */
5960 static struct hda_verb alc885_imac24_init_verbs[] = {
5961 /* Internal speakers: output 0 (0x0c) */
5962 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5963 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5964 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5965 /* Internal speakers: output 0 (0x0c) */
5966 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5967 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5968 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5969 /* Headphone: output 0 (0x0c) */
5970 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5971 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5972 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5973 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5974 /* Front Mic: input vref at 80% */
5975 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5976 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5980 /* Toggle speaker-output according to the hp-jack state */
5981 static void alc885_imac24_automute(struct hda_codec *codec)
5983 unsigned int present;
5985 present = snd_hda_codec_read(codec, 0x14, 0,
5986 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5987 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5988 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5989 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5990 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5993 /* Processes unsolicited events. */
5994 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5997 /* Headphone insertion or removal. */
5998 if ((res >> 26) == ALC880_HP_EVENT)
5999 alc885_imac24_automute(codec);
6002 static void alc885_mbp3_automute(struct hda_codec *codec)
6004 unsigned int present;
6006 present = snd_hda_codec_read(codec, 0x15, 0,
6007 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6008 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6009 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6010 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6011 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6014 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6017 /* Headphone insertion or removal. */
6018 if ((res >> 26) == ALC880_HP_EVENT)
6019 alc885_mbp3_automute(codec);
6023 static struct hda_verb alc882_targa_verbs[] = {
6024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6030 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6031 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6032 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6034 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6035 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6036 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6037 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6041 /* toggle speaker-output according to the hp-jack state */
6042 static void alc882_targa_automute(struct hda_codec *codec)
6044 unsigned int present;
6046 present = snd_hda_codec_read(codec, 0x14, 0,
6047 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6048 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6049 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6050 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6054 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6056 /* Looks like the unsol event is incompatible with the standard
6057 * definition. 4bit tag is placed at 26 bit!
6059 if (((res >> 26) == ALC880_HP_EVENT)) {
6060 alc882_targa_automute(codec);
6064 static struct hda_verb alc882_asus_a7j_verbs[] = {
6065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6066 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6068 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6069 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6070 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6072 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6073 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6074 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6076 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6077 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6078 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6082 static struct hda_verb alc882_asus_a7m_verbs[] = {
6083 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6086 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6087 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6090 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6091 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6092 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6094 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6095 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6096 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6100 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6102 unsigned int gpiostate, gpiomask, gpiodir;
6104 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6105 AC_VERB_GET_GPIO_DATA, 0);
6108 gpiostate |= (1 << pin);
6110 gpiostate &= ~(1 << pin);
6112 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6113 AC_VERB_GET_GPIO_MASK, 0);
6114 gpiomask |= (1 << pin);
6116 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6117 AC_VERB_GET_GPIO_DIRECTION, 0);
6118 gpiodir |= (1 << pin);
6121 snd_hda_codec_write(codec, codec->afg, 0,
6122 AC_VERB_SET_GPIO_MASK, gpiomask);
6123 snd_hda_codec_write(codec, codec->afg, 0,
6124 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6128 snd_hda_codec_write(codec, codec->afg, 0,
6129 AC_VERB_SET_GPIO_DATA, gpiostate);
6132 /* set up GPIO at initialization */
6133 static void alc885_macpro_init_hook(struct hda_codec *codec)
6135 alc882_gpio_mute(codec, 0, 0);
6136 alc882_gpio_mute(codec, 1, 0);
6139 /* set up GPIO and update auto-muting at initialization */
6140 static void alc885_imac24_init_hook(struct hda_codec *codec)
6142 alc885_macpro_init_hook(codec);
6143 alc885_imac24_automute(codec);
6147 * generic initialization of ADC, input mixers and output mixers
6149 static struct hda_verb alc882_auto_init_verbs[] = {
6151 * Unmute ADC0-2 and set the default input to mic-in
6153 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6155 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6157 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6160 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6162 * Note: PASD motherboards uses the Line In 2 as the input for
6163 * front panel mic (mic 2)
6165 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6166 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6168 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6173 * Set up output mixers (0x0c - 0x0f)
6175 /* set vol=0 to output mixers */
6176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6178 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6179 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6180 /* set up input amps for analog loopback */
6181 /* Amp Indices: DAC = 0, mixer = 1 */
6182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6186 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6187 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6188 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6189 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6190 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6191 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6193 /* FIXME: use matrix-type input source selection */
6194 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6195 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6197 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6201 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6202 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6203 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6204 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6207 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6208 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6209 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6214 /* capture mixer elements */
6215 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6216 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6217 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6218 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6219 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6222 /* The multiple "Capture Source" controls confuse alsamixer
6223 * So call somewhat different..
6225 /* .name = "Capture Source", */
6226 .name = "Input Source",
6228 .info = alc882_mux_enum_info,
6229 .get = alc882_mux_enum_get,
6230 .put = alc882_mux_enum_put,
6235 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6236 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6237 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6238 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6239 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6240 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6241 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6244 /* The multiple "Capture Source" controls confuse alsamixer
6245 * So call somewhat different..
6247 /* .name = "Capture Source", */
6248 .name = "Input Source",
6250 .info = alc882_mux_enum_info,
6251 .get = alc882_mux_enum_get,
6252 .put = alc882_mux_enum_put,
6257 #ifdef CONFIG_SND_HDA_POWER_SAVE
6258 #define alc882_loopbacks alc880_loopbacks
6261 /* pcm configuration: identiacal with ALC880 */
6262 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6263 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6264 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6265 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6268 * configuration and preset
6270 static const char *alc882_models[ALC882_MODEL_LAST] = {
6271 [ALC882_3ST_DIG] = "3stack-dig",
6272 [ALC882_6ST_DIG] = "6stack-dig",
6273 [ALC882_ARIMA] = "arima",
6274 [ALC882_W2JC] = "w2jc",
6275 [ALC882_TARGA] = "targa",
6276 [ALC882_ASUS_A7J] = "asus-a7j",
6277 [ALC882_ASUS_A7M] = "asus-a7m",
6278 [ALC885_MACPRO] = "macpro",
6279 [ALC885_MBP3] = "mbp3",
6280 [ALC885_IMAC24] = "imac24",
6281 [ALC882_AUTO] = "auto",
6284 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6285 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6286 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6287 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6288 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6289 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6290 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6291 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6292 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6293 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6294 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6295 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6296 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6300 static struct alc_config_preset alc882_presets[] = {
6301 [ALC882_3ST_DIG] = {
6302 .mixers = { alc882_base_mixer },
6303 .init_verbs = { alc882_init_verbs },
6304 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6305 .dac_nids = alc882_dac_nids,
6306 .dig_out_nid = ALC882_DIGOUT_NID,
6307 .dig_in_nid = ALC882_DIGIN_NID,
6308 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6309 .channel_mode = alc882_ch_modes,
6311 .input_mux = &alc882_capture_source,
6313 [ALC882_6ST_DIG] = {
6314 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6315 .init_verbs = { alc882_init_verbs },
6316 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6317 .dac_nids = alc882_dac_nids,
6318 .dig_out_nid = ALC882_DIGOUT_NID,
6319 .dig_in_nid = ALC882_DIGIN_NID,
6320 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6321 .channel_mode = alc882_sixstack_modes,
6322 .input_mux = &alc882_capture_source,
6325 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6326 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6327 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6328 .dac_nids = alc882_dac_nids,
6329 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6330 .channel_mode = alc882_sixstack_modes,
6331 .input_mux = &alc882_capture_source,
6334 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6335 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6336 alc880_gpio1_init_verbs },
6337 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6338 .dac_nids = alc882_dac_nids,
6339 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6340 .channel_mode = alc880_threestack_modes,
6342 .input_mux = &alc882_capture_source,
6343 .dig_out_nid = ALC882_DIGOUT_NID,
6346 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6347 .init_verbs = { alc885_mbp3_init_verbs,
6348 alc880_gpio1_init_verbs },
6349 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6350 .dac_nids = alc882_dac_nids,
6351 .channel_mode = alc885_mbp_6ch_modes,
6352 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6353 .input_mux = &alc882_capture_source,
6354 .dig_out_nid = ALC882_DIGOUT_NID,
6355 .dig_in_nid = ALC882_DIGIN_NID,
6356 .unsol_event = alc885_mbp3_unsol_event,
6357 .init_hook = alc885_mbp3_automute,
6360 .mixers = { alc882_macpro_mixer },
6361 .init_verbs = { alc882_macpro_init_verbs },
6362 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6363 .dac_nids = alc882_dac_nids,
6364 .dig_out_nid = ALC882_DIGOUT_NID,
6365 .dig_in_nid = ALC882_DIGIN_NID,
6366 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6367 .channel_mode = alc882_ch_modes,
6368 .input_mux = &alc882_capture_source,
6369 .init_hook = alc885_macpro_init_hook,
6372 .mixers = { alc885_imac24_mixer },
6373 .init_verbs = { alc885_imac24_init_verbs },
6374 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6375 .dac_nids = alc882_dac_nids,
6376 .dig_out_nid = ALC882_DIGOUT_NID,
6377 .dig_in_nid = ALC882_DIGIN_NID,
6378 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6379 .channel_mode = alc882_ch_modes,
6380 .input_mux = &alc882_capture_source,
6381 .unsol_event = alc885_imac24_unsol_event,
6382 .init_hook = alc885_imac24_init_hook,
6385 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6386 alc882_capture_mixer },
6387 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6388 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6389 .dac_nids = alc882_dac_nids,
6390 .dig_out_nid = ALC882_DIGOUT_NID,
6391 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6392 .adc_nids = alc882_adc_nids,
6393 .capsrc_nids = alc882_capsrc_nids,
6394 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6395 .channel_mode = alc882_3ST_6ch_modes,
6397 .input_mux = &alc882_capture_source,
6398 .unsol_event = alc882_targa_unsol_event,
6399 .init_hook = alc882_targa_automute,
6401 [ALC882_ASUS_A7J] = {
6402 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6403 alc882_capture_mixer },
6404 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6405 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6406 .dac_nids = alc882_dac_nids,
6407 .dig_out_nid = ALC882_DIGOUT_NID,
6408 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6409 .adc_nids = alc882_adc_nids,
6410 .capsrc_nids = alc882_capsrc_nids,
6411 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6412 .channel_mode = alc882_3ST_6ch_modes,
6414 .input_mux = &alc882_capture_source,
6416 [ALC882_ASUS_A7M] = {
6417 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6418 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6419 alc880_gpio1_init_verbs,
6420 alc882_asus_a7m_verbs },
6421 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6422 .dac_nids = alc882_dac_nids,
6423 .dig_out_nid = ALC882_DIGOUT_NID,
6424 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6425 .channel_mode = alc880_threestack_modes,
6427 .input_mux = &alc882_capture_source,
6436 PINFIX_ABIT_AW9D_MAX
6439 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6440 { 0x15, 0x01080104 }, /* side */
6441 { 0x16, 0x01011012 }, /* rear */
6442 { 0x17, 0x01016011 }, /* clfe */
6446 static const struct alc_pincfg *alc882_pin_fixes[] = {
6447 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6450 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6451 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6456 * BIOS auto configuration
6458 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6459 hda_nid_t nid, int pin_type,
6463 struct alc_spec *spec = codec->spec;
6466 alc_set_pin_output(codec, nid, pin_type);
6467 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6470 idx = spec->multiout.dac_nids[dac_idx] - 2;
6471 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6475 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6477 struct alc_spec *spec = codec->spec;
6480 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6481 for (i = 0; i <= HDA_SIDE; i++) {
6482 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6483 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6485 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6490 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6492 struct alc_spec *spec = codec->spec;
6495 pin = spec->autocfg.hp_pins[0];
6496 if (pin) /* connect to front */
6498 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6499 pin = spec->autocfg.speaker_pins[0];
6501 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6504 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6505 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6507 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6509 struct alc_spec *spec = codec->spec;
6512 for (i = 0; i < AUTO_PIN_LAST; i++) {
6513 hda_nid_t nid = spec->autocfg.input_pins[i];
6518 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6519 unsigned int pincap;
6520 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6521 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6525 snd_hda_codec_write(codec, nid, 0,
6526 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6527 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6528 snd_hda_codec_write(codec, nid, 0,
6529 AC_VERB_SET_AMP_GAIN_MUTE,
6534 static void alc882_auto_init_input_src(struct hda_codec *codec)
6536 struct alc_spec *spec = codec->spec;
6537 const struct hda_input_mux *imux = spec->input_mux;
6540 for (c = 0; c < spec->num_adc_nids; c++) {
6541 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6542 hda_nid_t nid = spec->capsrc_nids[c];
6543 int conns, mute, idx, item;
6545 conns = snd_hda_get_connections(codec, nid, conn_list,
6546 ARRAY_SIZE(conn_list));
6549 for (idx = 0; idx < conns; idx++) {
6550 /* if the current connection is the selected one,
6551 * unmute it as default - otherwise mute it
6553 mute = AMP_IN_MUTE(idx);
6554 for (item = 0; item < imux->num_items; item++) {
6555 if (imux->items[item].index == idx) {
6556 if (spec->cur_mux[c] == item)
6557 mute = AMP_IN_UNMUTE(idx);
6561 snd_hda_codec_write(codec, nid, 0,
6562 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6567 /* add mic boosts if needed */
6568 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6570 struct alc_spec *spec = codec->spec;
6574 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6575 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6576 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6578 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6582 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6583 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6584 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6586 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6593 /* almost identical with ALC880 parser... */
6594 static int alc882_parse_auto_config(struct hda_codec *codec)
6596 struct alc_spec *spec = codec->spec;
6597 int err = alc880_parse_auto_config(codec);
6602 return 0; /* no config found */
6604 err = alc_auto_add_mic_boost(codec);
6608 /* hack - override the init verbs */
6609 spec->init_verbs[0] = alc882_auto_init_verbs;
6611 return 1; /* config found */
6614 /* additional initialization for auto-configuration model */
6615 static void alc882_auto_init(struct hda_codec *codec)
6617 struct alc_spec *spec = codec->spec;
6618 alc882_auto_init_multi_out(codec);
6619 alc882_auto_init_hp_out(codec);
6620 alc882_auto_init_analog_input(codec);
6621 alc882_auto_init_input_src(codec);
6622 if (spec->unsol_event)
6623 alc_sku_automute(codec);
6626 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6628 static int patch_alc882(struct hda_codec *codec)
6630 struct alc_spec *spec;
6631 int err, board_config;
6633 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6639 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6643 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6644 /* Pick up systems that don't supply PCI SSID */
6645 switch (codec->subsystem_id) {
6646 case 0x106b0c00: /* Mac Pro */
6647 board_config = ALC885_MACPRO;
6649 case 0x106b1000: /* iMac 24 */
6650 board_config = ALC885_IMAC24;
6652 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6653 case 0x106b2c00: /* Macbook Pro rev3 */
6654 case 0x106b3600: /* Macbook 3.1 */
6655 board_config = ALC885_MBP3;
6658 /* ALC889A is handled better as ALC888-compatible */
6659 if (codec->revision_id == 0x100103) {
6661 return patch_alc883(codec);
6663 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6664 "trying auto-probe from BIOS...\n");
6665 board_config = ALC882_AUTO;
6669 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6671 if (board_config == ALC882_AUTO) {
6672 /* automatic parse from the BIOS config */
6673 err = alc882_parse_auto_config(codec);
6679 "hda_codec: Cannot set up configuration "
6680 "from BIOS. Using base mode...\n");
6681 board_config = ALC882_3ST_DIG;
6685 if (board_config != ALC882_AUTO)
6686 setup_preset(spec, &alc882_presets[board_config]);
6688 if (codec->vendor_id == 0x10ec0885) {
6689 spec->stream_name_analog = "ALC885 Analog";
6690 spec->stream_name_digital = "ALC885 Digital";
6692 spec->stream_name_analog = "ALC882 Analog";
6693 spec->stream_name_digital = "ALC882 Digital";
6696 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6697 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6698 /* FIXME: setup DAC5 */
6699 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6700 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6702 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6703 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6705 if (!spec->adc_nids && spec->input_mux) {
6706 /* check whether NID 0x07 is valid */
6707 unsigned int wcap = get_wcaps(codec, 0x07);
6709 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6710 if (wcap != AC_WID_AUD_IN) {
6711 spec->adc_nids = alc882_adc_nids_alt;
6712 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6713 spec->capsrc_nids = alc882_capsrc_nids_alt;
6714 spec->mixers[spec->num_mixers] =
6715 alc882_capture_alt_mixer;
6718 spec->adc_nids = alc882_adc_nids;
6719 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6720 spec->capsrc_nids = alc882_capsrc_nids;
6721 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6726 spec->vmaster_nid = 0x0c;
6728 codec->patch_ops = alc_patch_ops;
6729 if (board_config == ALC882_AUTO)
6730 spec->init_hook = alc882_auto_init;
6731 #ifdef CONFIG_SND_HDA_POWER_SAVE
6732 if (!spec->loopback.amplist)
6733 spec->loopback.amplist = alc882_loopbacks;
6742 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6743 * configuration. Each pin widget can choose any input DACs and a mixer.
6744 * Each ADC is connected from a mixer of all inputs. This makes possible
6745 * 6-channel independent captures.
6747 * In addition, an independent DAC for the multi-playback (not used in this
6750 #define ALC883_DIGOUT_NID 0x06
6751 #define ALC883_DIGIN_NID 0x0a
6753 static hda_nid_t alc883_dac_nids[4] = {
6754 /* front, rear, clfe, rear_surr */
6755 0x02, 0x03, 0x04, 0x05
6758 static hda_nid_t alc883_adc_nids[2] = {
6763 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6766 /* FIXME: should be a matrix-type input source selection */
6768 static struct hda_input_mux alc883_capture_source = {
6772 { "Front Mic", 0x1 },
6778 static struct hda_input_mux alc883_3stack_6ch_intel = {
6782 { "Front Mic", 0x0 },
6788 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6796 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6806 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6814 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6818 { "Front Mic", 0x1 },
6823 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6831 #define alc883_mux_enum_info alc_mux_enum_info
6832 #define alc883_mux_enum_get alc_mux_enum_get
6833 /* ALC883 has the ALC882-type input selection */
6834 #define alc883_mux_enum_put alc882_mux_enum_put
6839 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6846 static struct hda_verb alc883_3ST_ch2_init[] = {
6847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6857 static struct hda_verb alc883_3ST_ch4_init[] = {
6858 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6859 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6862 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6869 static struct hda_verb alc883_3ST_ch6_init[] = {
6870 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6871 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6872 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6873 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6874 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6875 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6879 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6880 { 2, alc883_3ST_ch2_init },
6881 { 4, alc883_3ST_ch4_init },
6882 { 6, alc883_3ST_ch6_init },
6888 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6889 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6890 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6891 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6892 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6899 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6900 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6901 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6902 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6903 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6904 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6911 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6912 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6913 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6914 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6915 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6916 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6917 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6921 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6922 { 2, alc883_3ST_ch2_intel_init },
6923 { 4, alc883_3ST_ch4_intel_init },
6924 { 6, alc883_3ST_ch6_intel_init },
6930 static struct hda_verb alc883_sixstack_ch6_init[] = {
6931 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6932 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6933 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6934 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6941 static struct hda_verb alc883_sixstack_ch8_init[] = {
6942 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6943 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6944 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6945 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6949 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6950 { 6, alc883_sixstack_ch6_init },
6951 { 8, alc883_sixstack_ch8_init },
6954 static struct hda_verb alc883_medion_eapd_verbs[] = {
6955 /* eanable EAPD on medion laptop */
6956 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6957 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6961 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6962 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6965 static struct snd_kcontrol_new alc883_base_mixer[] = {
6966 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6967 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6968 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6969 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6970 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6971 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6972 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6973 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6974 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6975 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6980 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6982 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6984 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6985 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6987 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6988 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6989 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6990 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6991 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6992 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6995 /* .name = "Capture Source", */
6996 .name = "Input Source",
6998 .info = alc883_mux_enum_info,
6999 .get = alc883_mux_enum_get,
7000 .put = alc883_mux_enum_put,
7005 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7007 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7008 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7009 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7010 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7011 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7012 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7014 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7016 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7017 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7018 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7019 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7020 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7021 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7022 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7025 /* .name = "Capture Source", */
7026 .name = "Input Source",
7028 .info = alc883_mux_enum_info,
7029 .get = alc883_mux_enum_get,
7030 .put = alc883_mux_enum_put,
7035 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7036 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7037 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7038 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7039 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7041 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7043 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7044 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7045 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7046 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7047 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7048 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7049 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7052 /* .name = "Capture Source", */
7053 .name = "Input Source",
7055 .info = alc883_mux_enum_info,
7056 .get = alc883_mux_enum_get,
7057 .put = alc883_mux_enum_put,
7062 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7063 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7064 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7065 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7066 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7068 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7070 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7071 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7072 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7073 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7074 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7075 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7076 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7078 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7079 /* .name = "Capture Source", */
7080 .name = "Input Source",
7082 .info = alc883_mux_enum_info,
7083 .get = alc883_mux_enum_get,
7084 .put = alc883_mux_enum_put,
7089 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7090 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7091 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7092 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7093 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7094 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7095 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7096 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7097 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7098 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7100 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7101 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7102 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7103 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7104 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7105 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7106 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7107 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7108 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7111 /* .name = "Capture Source", */
7112 .name = "Input Source",
7114 .info = alc883_mux_enum_info,
7115 .get = alc883_mux_enum_get,
7116 .put = alc883_mux_enum_put,
7121 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7122 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7123 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7124 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7125 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7126 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7127 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7128 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7129 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7130 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7133 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7134 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7135 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7136 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7138 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7139 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7140 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7141 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7142 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7143 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7144 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7147 /* .name = "Capture Source", */
7148 .name = "Input Source",
7150 .info = alc883_mux_enum_info,
7151 .get = alc883_mux_enum_get,
7152 .put = alc883_mux_enum_put,
7157 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7158 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7159 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7160 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7161 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7162 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7164 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7165 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7166 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7167 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7175 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7177 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7178 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7179 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7180 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7181 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7182 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7183 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7185 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7186 /* .name = "Capture Source", */
7187 .name = "Input Source",
7189 .info = alc883_mux_enum_info,
7190 .get = alc883_mux_enum_get,
7191 .put = alc883_mux_enum_put,
7196 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7197 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7198 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7199 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7200 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7201 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7202 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7203 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7204 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7206 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7207 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7211 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7214 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7216 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7217 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7218 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7219 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7223 /* .name = "Capture Source", */
7224 .name = "Input Source",
7226 .info = alc883_mux_enum_info,
7227 .get = alc883_mux_enum_get,
7228 .put = alc883_mux_enum_put,
7233 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7234 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7236 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7237 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7238 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7239 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7240 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7241 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7242 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7243 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7244 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7248 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7249 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7250 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7251 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7252 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7253 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7256 /* .name = "Capture Source", */
7257 .name = "Input Source",
7259 .info = alc883_mux_enum_info,
7260 .get = alc883_mux_enum_get,
7261 .put = alc883_mux_enum_put,
7266 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7269 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7270 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7271 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7273 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7274 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7275 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7276 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7277 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7278 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7279 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7280 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7281 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7284 /* .name = "Capture Source", */
7285 .name = "Input Source",
7287 .info = alc883_mux_enum_info,
7288 .get = alc883_mux_enum_get,
7289 .put = alc883_mux_enum_put,
7294 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7296 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7297 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7298 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7301 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7303 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7304 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7307 /* .name = "Capture Source", */
7308 .name = "Input Source",
7310 .info = alc883_mux_enum_info,
7311 .get = alc883_mux_enum_get,
7312 .put = alc883_mux_enum_put,
7317 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7318 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7319 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7320 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7321 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7322 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7325 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7326 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7327 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7328 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7329 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7330 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7333 /* .name = "Capture Source", */
7334 .name = "Input Source",
7336 .info = alc883_mux_enum_info,
7337 .get = alc883_mux_enum_get,
7338 .put = alc883_mux_enum_put,
7343 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7346 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7353 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7354 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7355 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7356 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7359 /* .name = "Capture Source", */
7360 .name = "Input Source",
7362 .info = alc883_mux_enum_info,
7363 .get = alc883_mux_enum_get,
7364 .put = alc883_mux_enum_put,
7369 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7371 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7372 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7373 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7374 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7376 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7378 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7379 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7380 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7381 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7383 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7384 /* .name = "Capture Source", */
7385 .name = "Input Source",
7387 .info = alc883_mux_enum_info,
7388 .get = alc883_mux_enum_get,
7389 .put = alc883_mux_enum_put,
7394 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7395 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7396 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7397 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7398 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7399 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7400 0x0d, 1, 0x0, HDA_OUTPUT),
7401 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7402 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7403 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7404 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7405 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7407 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7408 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7409 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7410 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7411 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7413 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7414 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7416 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7417 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7420 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7421 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7424 /* .name = "Capture Source", */
7425 .name = "Input Source",
7427 .info = alc883_mux_enum_info,
7428 .get = alc883_mux_enum_get,
7429 .put = alc883_mux_enum_put,
7434 static struct hda_bind_ctls alc883_bind_cap_vol = {
7435 .ops = &snd_hda_bind_vol,
7437 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7438 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7443 static struct hda_bind_ctls alc883_bind_cap_switch = {
7444 .ops = &snd_hda_bind_sw,
7446 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7447 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7452 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7453 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7454 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7456 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7457 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7459 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7460 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7461 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7462 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7465 /* .name = "Capture Source", */
7466 .name = "Input Source",
7468 .info = alc883_mux_enum_info,
7469 .get = alc883_mux_enum_get,
7470 .put = alc883_mux_enum_put,
7475 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7478 .name = "Channel Mode",
7479 .info = alc_ch_mode_info,
7480 .get = alc_ch_mode_get,
7481 .put = alc_ch_mode_put,
7486 static struct hda_verb alc883_init_verbs[] = {
7487 /* ADC1: mute amp left and right */
7488 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7490 /* ADC2: mute amp left and right */
7491 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7492 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7493 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7496 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7499 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7500 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7502 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7503 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7504 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7506 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7510 /* mute analog input loopbacks */
7511 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7512 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7517 /* Front Pin: output 0 (0x0c) */
7518 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7519 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7520 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7521 /* Rear Pin: output 1 (0x0d) */
7522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7523 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7524 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7525 /* CLFE Pin: output 2 (0x0e) */
7526 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7527 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7528 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7529 /* Side Pin: output 3 (0x0f) */
7530 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7531 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7532 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7533 /* Mic (rear) pin: input vref at 80% */
7534 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7535 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7536 /* Front Mic pin: input vref at 80% */
7537 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7538 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7539 /* Line In pin: input */
7540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7541 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7542 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7544 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7545 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7546 /* CD pin widget for input */
7547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7549 /* FIXME: use matrix-type input source selection */
7550 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7552 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7553 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7554 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7555 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7557 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7558 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7559 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7560 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7564 /* toggle speaker-output according to the hp-jack state */
7565 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7567 unsigned int present;
7569 present = snd_hda_codec_read(codec, 0x15, 0,
7570 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7571 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7572 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7573 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7574 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7577 /* auto-toggle front mic */
7579 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7581 unsigned int present;
7584 present = snd_hda_codec_read(codec, 0x18, 0,
7585 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7586 bits = present ? HDA_AMP_MUTE : 0;
7587 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7591 static void alc883_mitac_automute(struct hda_codec *codec)
7593 alc883_mitac_hp_automute(codec);
7594 /* alc883_mitac_mic_automute(codec); */
7597 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7600 switch (res >> 26) {
7601 case ALC880_HP_EVENT:
7602 alc883_mitac_hp_automute(codec);
7604 case ALC880_MIC_EVENT:
7605 /* alc883_mitac_mic_automute(codec); */
7610 static struct hda_verb alc883_mitac_verbs[] = {
7612 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7613 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7615 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7616 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7618 /* enable unsolicited event */
7619 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7620 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7625 static struct hda_verb alc883_clevo_m720_verbs[] = {
7627 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7628 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7630 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7631 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7633 /* enable unsolicited event */
7634 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7635 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7640 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7642 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7645 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7648 /* enable unsolicited event */
7649 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7654 static struct hda_verb alc883_tagra_verbs[] = {
7655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7662 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7663 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7666 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7667 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7668 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7673 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7674 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7675 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7676 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7680 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7681 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7683 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7688 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7689 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7690 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7691 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7692 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7693 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7697 static struct hda_verb alc883_haier_w66_verbs[] = {
7698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7701 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7703 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7710 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7711 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7712 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7715 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7716 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7717 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7718 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7722 static struct hda_verb alc888_3st_hp_verbs[] = {
7723 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7724 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7725 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7729 static struct hda_verb alc888_6st_dell_verbs[] = {
7730 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7734 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7735 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7736 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7737 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7738 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7742 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7743 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7745 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7746 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7750 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7751 { 2, alc888_3st_hp_2ch_init },
7752 { 6, alc888_3st_hp_6ch_init },
7755 /* toggle front-jack and RCA according to the hp-jack state */
7756 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7758 unsigned int present;
7760 present = snd_hda_codec_read(codec, 0x1b, 0,
7761 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7762 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7763 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7764 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7765 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7768 /* toggle RCA according to the front-jack state */
7769 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7771 unsigned int present;
7773 present = snd_hda_codec_read(codec, 0x14, 0,
7774 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7775 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7776 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7779 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7782 if ((res >> 26) == ALC880_HP_EVENT)
7783 alc888_lenovo_ms7195_front_automute(codec);
7784 if ((res >> 26) == ALC880_FRONT_EVENT)
7785 alc888_lenovo_ms7195_rca_automute(codec);
7788 static struct hda_verb alc883_medion_md2_verbs[] = {
7789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7794 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7798 /* toggle speaker-output according to the hp-jack state */
7799 static void alc883_medion_md2_automute(struct hda_codec *codec)
7801 unsigned int present;
7803 present = snd_hda_codec_read(codec, 0x14, 0,
7804 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7805 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7806 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7809 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7812 if ((res >> 26) == ALC880_HP_EVENT)
7813 alc883_medion_md2_automute(codec);
7816 /* toggle speaker-output according to the hp-jack state */
7817 static void alc883_tagra_automute(struct hda_codec *codec)
7819 unsigned int present;
7822 present = snd_hda_codec_read(codec, 0x14, 0,
7823 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7824 bits = present ? HDA_AMP_MUTE : 0;
7825 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7826 HDA_AMP_MUTE, bits);
7827 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7831 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7833 if ((res >> 26) == ALC880_HP_EVENT)
7834 alc883_tagra_automute(codec);
7837 /* toggle speaker-output according to the hp-jack state */
7838 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7840 unsigned int present;
7843 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7844 & AC_PINSENSE_PRESENCE;
7845 bits = present ? HDA_AMP_MUTE : 0;
7846 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7847 HDA_AMP_MUTE, bits);
7850 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7852 unsigned int present;
7854 present = snd_hda_codec_read(codec, 0x18, 0,
7855 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7856 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7857 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7860 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7862 alc883_clevo_m720_hp_automute(codec);
7863 alc883_clevo_m720_mic_automute(codec);
7866 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7869 switch (res >> 26) {
7870 case ALC880_HP_EVENT:
7871 alc883_clevo_m720_hp_automute(codec);
7873 case ALC880_MIC_EVENT:
7874 alc883_clevo_m720_mic_automute(codec);
7879 /* toggle speaker-output according to the hp-jack state */
7880 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7882 unsigned int present;
7885 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7886 & AC_PINSENSE_PRESENCE;
7887 bits = present ? HDA_AMP_MUTE : 0;
7888 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7889 HDA_AMP_MUTE, bits);
7892 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7895 if ((res >> 26) == ALC880_HP_EVENT)
7896 alc883_2ch_fujitsu_pi2515_automute(codec);
7899 static void alc883_haier_w66_automute(struct hda_codec *codec)
7901 unsigned int present;
7904 present = snd_hda_codec_read(codec, 0x1b, 0,
7905 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7906 bits = present ? 0x80 : 0;
7907 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7911 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7914 if ((res >> 26) == ALC880_HP_EVENT)
7915 alc883_haier_w66_automute(codec);
7918 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7920 unsigned int present;
7923 present = snd_hda_codec_read(codec, 0x14, 0,
7924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7925 bits = present ? HDA_AMP_MUTE : 0;
7926 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7927 HDA_AMP_MUTE, bits);
7930 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7932 unsigned int present;
7935 present = snd_hda_codec_read(codec, 0x1b, 0,
7936 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7937 bits = present ? HDA_AMP_MUTE : 0;
7938 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7939 HDA_AMP_MUTE, bits);
7940 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7941 HDA_AMP_MUTE, bits);
7944 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7947 if ((res >> 26) == ALC880_HP_EVENT)
7948 alc883_lenovo_101e_all_automute(codec);
7949 if ((res >> 26) == ALC880_FRONT_EVENT)
7950 alc883_lenovo_101e_ispeaker_automute(codec);
7953 /* toggle speaker-output according to the hp-jack state */
7954 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7956 unsigned int present;
7958 present = snd_hda_codec_read(codec, 0x14, 0,
7959 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7960 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7961 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7962 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7963 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7966 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7969 if ((res >> 26) == ALC880_HP_EVENT)
7970 alc883_acer_aspire_automute(codec);
7973 static struct hda_verb alc883_acer_eapd_verbs[] = {
7974 /* HP Pin: output 0 (0x0c) */
7975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7976 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7978 /* Front Pin: output 0 (0x0c) */
7979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7981 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7982 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7983 /* eanable EAPD on medion laptop */
7984 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7985 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7986 /* enable unsolicited event */
7987 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7991 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7993 unsigned int present;
7995 present = snd_hda_codec_read(codec, 0x1b, 0,
7996 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7997 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7998 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7999 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8000 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8001 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8002 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8003 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8004 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8007 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8010 switch (res >> 26) {
8011 case ALC880_HP_EVENT:
8012 printk("hp_event\n");
8013 alc888_6st_dell_front_automute(codec);
8018 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8021 unsigned int present;
8023 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8024 present = snd_hda_codec_read(codec, 0x1b, 0,
8025 AC_VERB_GET_PIN_SENSE, 0);
8026 present = (present & 0x80000000) != 0;
8028 /* mute internal speaker */
8029 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8030 HDA_AMP_MUTE, HDA_AMP_MUTE);
8031 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8032 HDA_AMP_MUTE, HDA_AMP_MUTE);
8033 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8034 HDA_AMP_MUTE, HDA_AMP_MUTE);
8035 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8036 HDA_AMP_MUTE, HDA_AMP_MUTE);
8037 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8038 HDA_AMP_MUTE, HDA_AMP_MUTE);
8040 /* unmute internal speaker if necessary */
8041 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8042 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8043 HDA_AMP_MUTE, mute);
8044 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8045 HDA_AMP_MUTE, mute);
8046 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8047 HDA_AMP_MUTE, mute);
8048 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8049 HDA_AMP_MUTE, mute);
8050 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8051 HDA_AMP_MUTE, mute);
8055 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8058 if ((res >> 26) == ALC880_HP_EVENT)
8059 alc888_lenovo_sky_front_automute(codec);
8063 * generic initialization of ADC, input mixers and output mixers
8065 static struct hda_verb alc883_auto_init_verbs[] = {
8067 * Unmute ADC0-2 and set the default input to mic-in
8069 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8071 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8074 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8076 * Note: PASD motherboards uses the Line In 2 as the input for
8077 * front panel mic (mic 2)
8079 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8083 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8084 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8087 * Set up output mixers (0x0c - 0x0f)
8089 /* set vol=0 to output mixers */
8090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8091 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8092 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8093 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8094 /* set up input amps for analog loopback */
8095 /* Amp Indices: DAC = 0, mixer = 1 */
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8098 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8100 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8102 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8103 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8104 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8105 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8107 /* FIXME: use matrix-type input source selection */
8108 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8110 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8111 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8113 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8119 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8125 /* capture mixer elements */
8126 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8127 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8128 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8129 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8130 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8133 /* The multiple "Capture Source" controls confuse alsamixer
8134 * So call somewhat different..
8136 /* .name = "Capture Source", */
8137 .name = "Input Source",
8139 .info = alc882_mux_enum_info,
8140 .get = alc882_mux_enum_get,
8141 .put = alc882_mux_enum_put,
8146 static struct hda_verb alc888_asus_m90v_verbs[] = {
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8148 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8149 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8150 /* enable unsolicited event */
8151 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8152 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8156 static void alc883_nb_mic_automute(struct hda_codec *codec)
8158 unsigned int present;
8160 present = snd_hda_codec_read(codec, 0x18, 0,
8161 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8162 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8163 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8164 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8165 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8168 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8170 unsigned int present;
8173 present = snd_hda_codec_read(codec, 0x1b, 0,
8174 AC_VERB_GET_PIN_SENSE, 0)
8175 & AC_PINSENSE_PRESENCE;
8176 bits = present ? 0 : PIN_OUT;
8177 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8179 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8181 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8185 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8188 switch (res >> 26) {
8189 case ALC880_HP_EVENT:
8190 alc883_M90V_speaker_automute(codec);
8192 case ALC880_MIC_EVENT:
8193 alc883_nb_mic_automute(codec);
8198 static void alc883_mode2_inithook(struct hda_codec *codec)
8200 alc883_M90V_speaker_automute(codec);
8201 alc883_nb_mic_automute(codec);
8204 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8206 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8207 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8210 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8211 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8212 /* enable unsolicited event */
8213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8217 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8219 unsigned int present;
8222 present = snd_hda_codec_read(codec, 0x14, 0,
8223 AC_VERB_GET_PIN_SENSE, 0)
8224 & AC_PINSENSE_PRESENCE;
8225 bits = present ? 0 : PIN_OUT;
8226 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8230 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8233 switch (res >> 26) {
8234 case ALC880_HP_EVENT:
8235 alc883_eee1601_speaker_automute(codec);
8240 static void alc883_eee1601_inithook(struct hda_codec *codec)
8242 alc883_eee1601_speaker_automute(codec);
8245 #ifdef CONFIG_SND_HDA_POWER_SAVE
8246 #define alc883_loopbacks alc880_loopbacks
8249 /* pcm configuration: identiacal with ALC880 */
8250 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8251 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8252 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8253 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8254 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8257 * configuration and preset
8259 static const char *alc883_models[ALC883_MODEL_LAST] = {
8260 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8261 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8262 [ALC883_3ST_6ch] = "3stack-6ch",
8263 [ALC883_6ST_DIG] = "6stack-dig",
8264 [ALC883_TARGA_DIG] = "targa-dig",
8265 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8266 [ALC883_ACER] = "acer",
8267 [ALC883_ACER_ASPIRE] = "acer-aspire",
8268 [ALC883_MEDION] = "medion",
8269 [ALC883_MEDION_MD2] = "medion-md2",
8270 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8271 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8272 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8273 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8274 [ALC888_LENOVO_SKY] = "lenovo-sky",
8275 [ALC883_HAIER_W66] = "haier-w66",
8276 [ALC888_3ST_HP] = "3stack-hp",
8277 [ALC888_6ST_DELL] = "6stack-dell",
8278 [ALC883_MITAC] = "mitac",
8279 [ALC883_CLEVO_M720] = "clevo-m720",
8280 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8281 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8282 [ALC883_AUTO] = "auto",
8285 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8286 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8287 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8288 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8289 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8290 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8291 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8292 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8293 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8294 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8295 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8296 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8297 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8298 SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
8299 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8300 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8301 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8302 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8303 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8304 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8305 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8306 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8307 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8308 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8309 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8310 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8311 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8312 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8313 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8314 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8315 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8316 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8317 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8318 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8319 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8320 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8321 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8322 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8323 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8324 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8325 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8326 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8327 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8328 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8329 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8330 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8331 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8332 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8333 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8334 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8335 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8336 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8337 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8338 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8339 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8340 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8341 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8342 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8343 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8344 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8345 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8346 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8350 static struct alc_config_preset alc883_presets[] = {
8351 [ALC883_3ST_2ch_DIG] = {
8352 .mixers = { alc883_3ST_2ch_mixer },
8353 .init_verbs = { alc883_init_verbs },
8354 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8355 .dac_nids = alc883_dac_nids,
8356 .dig_out_nid = ALC883_DIGOUT_NID,
8357 .dig_in_nid = ALC883_DIGIN_NID,
8358 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8359 .channel_mode = alc883_3ST_2ch_modes,
8360 .input_mux = &alc883_capture_source,
8362 [ALC883_3ST_6ch_DIG] = {
8363 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8364 .init_verbs = { alc883_init_verbs },
8365 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8366 .dac_nids = alc883_dac_nids,
8367 .dig_out_nid = ALC883_DIGOUT_NID,
8368 .dig_in_nid = ALC883_DIGIN_NID,
8369 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8370 .channel_mode = alc883_3ST_6ch_modes,
8372 .input_mux = &alc883_capture_source,
8374 [ALC883_3ST_6ch] = {
8375 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8376 .init_verbs = { alc883_init_verbs },
8377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8378 .dac_nids = alc883_dac_nids,
8379 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8380 .channel_mode = alc883_3ST_6ch_modes,
8382 .input_mux = &alc883_capture_source,
8384 [ALC883_3ST_6ch_INTEL] = {
8385 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8386 .init_verbs = { alc883_init_verbs },
8387 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8388 .dac_nids = alc883_dac_nids,
8389 .dig_out_nid = ALC883_DIGOUT_NID,
8390 .dig_in_nid = ALC883_DIGIN_NID,
8391 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8392 .channel_mode = alc883_3ST_6ch_intel_modes,
8394 .input_mux = &alc883_3stack_6ch_intel,
8396 [ALC883_6ST_DIG] = {
8397 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8398 .init_verbs = { alc883_init_verbs },
8399 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8400 .dac_nids = alc883_dac_nids,
8401 .dig_out_nid = ALC883_DIGOUT_NID,
8402 .dig_in_nid = ALC883_DIGIN_NID,
8403 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8404 .channel_mode = alc883_sixstack_modes,
8405 .input_mux = &alc883_capture_source,
8407 [ALC883_TARGA_DIG] = {
8408 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8409 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8410 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8411 .dac_nids = alc883_dac_nids,
8412 .dig_out_nid = ALC883_DIGOUT_NID,
8413 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8414 .channel_mode = alc883_3ST_6ch_modes,
8416 .input_mux = &alc883_capture_source,
8417 .unsol_event = alc883_tagra_unsol_event,
8418 .init_hook = alc883_tagra_automute,
8420 [ALC883_TARGA_2ch_DIG] = {
8421 .mixers = { alc883_tagra_2ch_mixer},
8422 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8423 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8424 .dac_nids = alc883_dac_nids,
8425 .dig_out_nid = ALC883_DIGOUT_NID,
8426 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8427 .channel_mode = alc883_3ST_2ch_modes,
8428 .input_mux = &alc883_capture_source,
8429 .unsol_event = alc883_tagra_unsol_event,
8430 .init_hook = alc883_tagra_automute,
8433 .mixers = { alc883_base_mixer },
8434 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8435 * and the headphone jack. Turn this on and rely on the
8436 * standard mute methods whenever the user wants to turn
8437 * these outputs off.
8439 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8440 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8441 .dac_nids = alc883_dac_nids,
8442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8443 .channel_mode = alc883_3ST_2ch_modes,
8444 .input_mux = &alc883_capture_source,
8446 [ALC883_ACER_ASPIRE] = {
8447 .mixers = { alc883_acer_aspire_mixer },
8448 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8449 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8450 .dac_nids = alc883_dac_nids,
8451 .dig_out_nid = ALC883_DIGOUT_NID,
8452 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8453 .channel_mode = alc883_3ST_2ch_modes,
8454 .input_mux = &alc883_capture_source,
8455 .unsol_event = alc883_acer_aspire_unsol_event,
8456 .init_hook = alc883_acer_aspire_automute,
8459 .mixers = { alc883_fivestack_mixer,
8460 alc883_chmode_mixer },
8461 .init_verbs = { alc883_init_verbs,
8462 alc883_medion_eapd_verbs },
8463 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8464 .dac_nids = alc883_dac_nids,
8465 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8466 .channel_mode = alc883_sixstack_modes,
8467 .input_mux = &alc883_capture_source,
8469 [ALC883_MEDION_MD2] = {
8470 .mixers = { alc883_medion_md2_mixer},
8471 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8472 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8473 .dac_nids = alc883_dac_nids,
8474 .dig_out_nid = ALC883_DIGOUT_NID,
8475 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8476 .channel_mode = alc883_3ST_2ch_modes,
8477 .input_mux = &alc883_capture_source,
8478 .unsol_event = alc883_medion_md2_unsol_event,
8479 .init_hook = alc883_medion_md2_automute,
8481 [ALC883_LAPTOP_EAPD] = {
8482 .mixers = { alc883_base_mixer },
8483 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8485 .dac_nids = alc883_dac_nids,
8486 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8487 .channel_mode = alc883_3ST_2ch_modes,
8488 .input_mux = &alc883_capture_source,
8490 [ALC883_CLEVO_M720] = {
8491 .mixers = { alc883_clevo_m720_mixer },
8492 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8493 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8494 .dac_nids = alc883_dac_nids,
8495 .dig_out_nid = ALC883_DIGOUT_NID,
8496 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8497 .channel_mode = alc883_3ST_2ch_modes,
8498 .input_mux = &alc883_capture_source,
8499 .unsol_event = alc883_clevo_m720_unsol_event,
8500 .init_hook = alc883_clevo_m720_automute,
8502 [ALC883_LENOVO_101E_2ch] = {
8503 .mixers = { alc883_lenovo_101e_2ch_mixer},
8504 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8505 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8506 .dac_nids = alc883_dac_nids,
8507 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8508 .channel_mode = alc883_3ST_2ch_modes,
8509 .input_mux = &alc883_lenovo_101e_capture_source,
8510 .unsol_event = alc883_lenovo_101e_unsol_event,
8511 .init_hook = alc883_lenovo_101e_all_automute,
8513 [ALC883_LENOVO_NB0763] = {
8514 .mixers = { alc883_lenovo_nb0763_mixer },
8515 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8516 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8517 .dac_nids = alc883_dac_nids,
8518 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8519 .channel_mode = alc883_3ST_2ch_modes,
8521 .input_mux = &alc883_lenovo_nb0763_capture_source,
8522 .unsol_event = alc883_medion_md2_unsol_event,
8523 .init_hook = alc883_medion_md2_automute,
8525 [ALC888_LENOVO_MS7195_DIG] = {
8526 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8527 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8528 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8529 .dac_nids = alc883_dac_nids,
8530 .dig_out_nid = ALC883_DIGOUT_NID,
8531 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8532 .channel_mode = alc883_3ST_6ch_modes,
8534 .input_mux = &alc883_capture_source,
8535 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8536 .init_hook = alc888_lenovo_ms7195_front_automute,
8538 [ALC883_HAIER_W66] = {
8539 .mixers = { alc883_tagra_2ch_mixer},
8540 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8541 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8542 .dac_nids = alc883_dac_nids,
8543 .dig_out_nid = ALC883_DIGOUT_NID,
8544 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8545 .channel_mode = alc883_3ST_2ch_modes,
8546 .input_mux = &alc883_capture_source,
8547 .unsol_event = alc883_haier_w66_unsol_event,
8548 .init_hook = alc883_haier_w66_automute,
8551 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8552 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8553 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8554 .dac_nids = alc883_dac_nids,
8555 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8556 .channel_mode = alc888_3st_hp_modes,
8558 .input_mux = &alc883_capture_source,
8560 [ALC888_6ST_DELL] = {
8561 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8562 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8563 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8564 .dac_nids = alc883_dac_nids,
8565 .dig_out_nid = ALC883_DIGOUT_NID,
8566 .dig_in_nid = ALC883_DIGIN_NID,
8567 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8568 .channel_mode = alc883_sixstack_modes,
8569 .input_mux = &alc883_capture_source,
8570 .unsol_event = alc888_6st_dell_unsol_event,
8571 .init_hook = alc888_6st_dell_front_automute,
8574 .mixers = { alc883_mitac_mixer },
8575 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8576 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8577 .dac_nids = alc883_dac_nids,
8578 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8579 .channel_mode = alc883_3ST_2ch_modes,
8580 .input_mux = &alc883_capture_source,
8581 .unsol_event = alc883_mitac_unsol_event,
8582 .init_hook = alc883_mitac_automute,
8584 [ALC883_FUJITSU_PI2515] = {
8585 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8586 .init_verbs = { alc883_init_verbs,
8587 alc883_2ch_fujitsu_pi2515_verbs},
8588 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8589 .dac_nids = alc883_dac_nids,
8590 .dig_out_nid = ALC883_DIGOUT_NID,
8591 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8592 .channel_mode = alc883_3ST_2ch_modes,
8593 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8594 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8595 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8597 [ALC888_LENOVO_SKY] = {
8598 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8599 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8601 .dac_nids = alc883_dac_nids,
8602 .dig_out_nid = ALC883_DIGOUT_NID,
8603 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8604 .adc_nids = alc883_adc_nids,
8605 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8606 .channel_mode = alc883_sixstack_modes,
8608 .input_mux = &alc883_lenovo_sky_capture_source,
8609 .unsol_event = alc883_lenovo_sky_unsol_event,
8610 .init_hook = alc888_lenovo_sky_front_automute,
8612 [ALC888_ASUS_M90V] = {
8613 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8614 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8615 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8616 .dac_nids = alc883_dac_nids,
8617 .dig_out_nid = ALC883_DIGOUT_NID,
8618 .dig_in_nid = ALC883_DIGIN_NID,
8619 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8620 .channel_mode = alc883_3ST_6ch_modes,
8622 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8623 .unsol_event = alc883_mode2_unsol_event,
8624 .init_hook = alc883_mode2_inithook,
8626 [ALC888_ASUS_EEE1601] = {
8627 .mixers = { alc883_asus_eee1601_mixer },
8628 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8630 .dac_nids = alc883_dac_nids,
8631 .dig_out_nid = ALC883_DIGOUT_NID,
8632 .dig_in_nid = ALC883_DIGIN_NID,
8633 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8634 .channel_mode = alc883_3ST_2ch_modes,
8636 .input_mux = &alc883_asus_eee1601_capture_source,
8637 .unsol_event = alc883_eee1601_unsol_event,
8638 .init_hook = alc883_eee1601_inithook,
8644 * BIOS auto configuration
8646 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8647 hda_nid_t nid, int pin_type,
8651 struct alc_spec *spec = codec->spec;
8654 alc_set_pin_output(codec, nid, pin_type);
8655 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8658 idx = spec->multiout.dac_nids[dac_idx] - 2;
8659 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8663 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8665 struct alc_spec *spec = codec->spec;
8668 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8669 for (i = 0; i <= HDA_SIDE; i++) {
8670 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8671 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8673 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8678 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8680 struct alc_spec *spec = codec->spec;
8683 pin = spec->autocfg.hp_pins[0];
8684 if (pin) /* connect to front */
8686 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8687 pin = spec->autocfg.speaker_pins[0];
8689 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8692 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8693 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8695 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8697 struct alc_spec *spec = codec->spec;
8700 for (i = 0; i < AUTO_PIN_LAST; i++) {
8701 hda_nid_t nid = spec->autocfg.input_pins[i];
8702 if (alc883_is_input_pin(nid)) {
8703 snd_hda_codec_write(codec, nid, 0,
8704 AC_VERB_SET_PIN_WIDGET_CONTROL,
8705 (i <= AUTO_PIN_FRONT_MIC ?
8706 PIN_VREF80 : PIN_IN));
8707 if (nid != ALC883_PIN_CD_NID)
8708 snd_hda_codec_write(codec, nid, 0,
8709 AC_VERB_SET_AMP_GAIN_MUTE,
8715 #define alc883_auto_init_input_src alc882_auto_init_input_src
8717 /* almost identical with ALC880 parser... */
8718 static int alc883_parse_auto_config(struct hda_codec *codec)
8720 struct alc_spec *spec = codec->spec;
8721 int err = alc880_parse_auto_config(codec);
8726 return 0; /* no config found */
8728 err = alc_auto_add_mic_boost(codec);
8732 /* hack - override the init verbs */
8733 spec->init_verbs[0] = alc883_auto_init_verbs;
8734 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8737 return 1; /* config found */
8740 /* additional initialization for auto-configuration model */
8741 static void alc883_auto_init(struct hda_codec *codec)
8743 struct alc_spec *spec = codec->spec;
8744 alc883_auto_init_multi_out(codec);
8745 alc883_auto_init_hp_out(codec);
8746 alc883_auto_init_analog_input(codec);
8747 alc883_auto_init_input_src(codec);
8748 if (spec->unsol_event)
8749 alc_sku_automute(codec);
8752 static int patch_alc883(struct hda_codec *codec)
8754 struct alc_spec *spec;
8755 int err, board_config;
8757 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8763 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8765 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8768 if (board_config < 0) {
8769 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8770 "trying auto-probe from BIOS...\n");
8771 board_config = ALC883_AUTO;
8774 if (board_config == ALC883_AUTO) {
8775 /* automatic parse from the BIOS config */
8776 err = alc883_parse_auto_config(codec);
8782 "hda_codec: Cannot set up configuration "
8783 "from BIOS. Using base mode...\n");
8784 board_config = ALC883_3ST_2ch_DIG;
8788 if (board_config != ALC883_AUTO)
8789 setup_preset(spec, &alc883_presets[board_config]);
8791 switch (codec->vendor_id) {
8793 spec->stream_name_analog = "ALC888 Analog";
8794 spec->stream_name_digital = "ALC888 Digital";
8797 spec->stream_name_analog = "ALC889 Analog";
8798 spec->stream_name_digital = "ALC889 Digital";
8801 spec->stream_name_analog = "ALC883 Analog";
8802 spec->stream_name_digital = "ALC883 Digital";
8806 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8807 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8808 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8810 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8811 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8813 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8814 spec->adc_nids = alc883_adc_nids;
8815 spec->capsrc_nids = alc883_capsrc_nids;
8817 spec->vmaster_nid = 0x0c;
8819 codec->patch_ops = alc_patch_ops;
8820 if (board_config == ALC883_AUTO)
8821 spec->init_hook = alc883_auto_init;
8823 #ifdef CONFIG_SND_HDA_POWER_SAVE
8824 if (!spec->loopback.amplist)
8825 spec->loopback.amplist = alc883_loopbacks;
8835 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8836 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8838 #define alc262_dac_nids alc260_dac_nids
8839 #define alc262_adc_nids alc882_adc_nids
8840 #define alc262_adc_nids_alt alc882_adc_nids_alt
8841 #define alc262_capsrc_nids alc882_capsrc_nids
8842 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8844 #define alc262_modes alc260_modes
8845 #define alc262_capture_source alc882_capture_source
8847 static hda_nid_t alc262_dmic_adc_nids[1] = {
8852 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8854 static struct snd_kcontrol_new alc262_base_mixer[] = {
8855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8856 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8863 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8864 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8866 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8867 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8868 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8869 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8870 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8871 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8872 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8876 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8877 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8878 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8879 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8880 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8882 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8886 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8888 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8889 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8890 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8891 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8892 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8896 /* update HP, line and mono-out pins according to the master switch */
8897 static void alc262_hp_master_update(struct hda_codec *codec)
8899 struct alc_spec *spec = codec->spec;
8900 int val = spec->master_sw;
8903 snd_hda_codec_write_cache(codec, 0x1b, 0,
8904 AC_VERB_SET_PIN_WIDGET_CONTROL,
8906 snd_hda_codec_write_cache(codec, 0x15, 0,
8907 AC_VERB_SET_PIN_WIDGET_CONTROL,
8909 /* mono (speaker) depending on the HP jack sense */
8910 val = val && !spec->jack_present;
8911 snd_hda_codec_write_cache(codec, 0x16, 0,
8912 AC_VERB_SET_PIN_WIDGET_CONTROL,
8916 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8918 struct alc_spec *spec = codec->spec;
8919 unsigned int presence;
8920 presence = snd_hda_codec_read(codec, 0x1b, 0,
8921 AC_VERB_GET_PIN_SENSE, 0);
8922 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8923 alc262_hp_master_update(codec);
8926 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8928 if ((res >> 26) != ALC880_HP_EVENT)
8930 alc262_hp_bpc_automute(codec);
8933 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8935 struct alc_spec *spec = codec->spec;
8936 unsigned int presence;
8937 presence = snd_hda_codec_read(codec, 0x15, 0,
8938 AC_VERB_GET_PIN_SENSE, 0);
8939 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8940 alc262_hp_master_update(codec);
8943 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8946 if ((res >> 26) != ALC880_HP_EVENT)
8948 alc262_hp_wildwest_automute(codec);
8951 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8952 struct snd_ctl_elem_value *ucontrol)
8954 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8955 struct alc_spec *spec = codec->spec;
8956 *ucontrol->value.integer.value = spec->master_sw;
8960 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8961 struct snd_ctl_elem_value *ucontrol)
8963 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8964 struct alc_spec *spec = codec->spec;
8965 int val = !!*ucontrol->value.integer.value;
8967 if (val == spec->master_sw)
8969 spec->master_sw = val;
8970 alc262_hp_master_update(codec);
8974 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8976 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8977 .name = "Master Playback Switch",
8978 .info = snd_ctl_boolean_mono_info,
8979 .get = alc262_hp_master_sw_get,
8980 .put = alc262_hp_master_sw_put,
8982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8983 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8985 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8987 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8992 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8993 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8999 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9000 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9001 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9002 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9006 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9008 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9009 .name = "Master Playback Switch",
9010 .info = snd_ctl_boolean_mono_info,
9011 .get = alc262_hp_master_sw_get,
9012 .put = alc262_hp_master_sw_put,
9014 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9015 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9016 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9017 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9018 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9020 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9022 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9023 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9024 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9025 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9026 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9027 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9028 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9029 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9030 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9034 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9035 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9036 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9037 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9041 /* mute/unmute internal speaker according to the hp jack and mute state */
9042 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9044 struct alc_spec *spec = codec->spec;
9046 if (force || !spec->sense_updated) {
9047 unsigned int present;
9048 present = snd_hda_codec_read(codec, 0x15, 0,
9049 AC_VERB_GET_PIN_SENSE, 0);
9050 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9051 spec->sense_updated = 1;
9053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9054 spec->jack_present ? HDA_AMP_MUTE : 0);
9057 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9060 if ((res >> 26) != ALC880_HP_EVENT)
9062 alc262_hp_t5735_automute(codec, 1);
9065 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9067 alc262_hp_t5735_automute(codec, 1);
9070 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9071 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9072 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9073 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9074 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9077 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9081 static struct hda_verb alc262_hp_t5735_verbs[] = {
9082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9085 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9089 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9090 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9091 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9092 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9093 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9094 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9095 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9099 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9100 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9101 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9102 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9103 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9104 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9105 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9106 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9113 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9120 /* bind hp and internal speaker mute (with plug check) */
9121 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9122 struct snd_ctl_elem_value *ucontrol)
9124 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9125 long *valp = ucontrol->value.integer.value;
9128 /* change hp mute */
9129 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9131 valp[0] ? 0 : HDA_AMP_MUTE);
9132 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9134 valp[1] ? 0 : HDA_AMP_MUTE);
9136 /* change speaker according to HP jack state */
9137 struct alc_spec *spec = codec->spec;
9139 if (spec->jack_present)
9140 mute = HDA_AMP_MUTE;
9142 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9144 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9145 HDA_AMP_MUTE, mute);
9150 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9151 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9154 .name = "Master Playback Switch",
9155 .info = snd_hda_mixer_amp_switch_info,
9156 .get = snd_hda_mixer_amp_switch_get,
9157 .put = alc262_sony_master_sw_put,
9158 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9162 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9163 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9167 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9168 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9169 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9170 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9171 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9173 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9174 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9178 #define alc262_capture_mixer alc882_capture_mixer
9179 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9182 * generic initialization of ADC, input mixers and output mixers
9184 static struct hda_verb alc262_init_verbs[] = {
9186 * Unmute ADC0-2 and set the default input to mic-in
9188 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9190 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9191 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9192 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9193 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9195 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9197 * Note: PASD motherboards uses the Line In 2 as the input for
9198 * front panel mic (mic 2)
9200 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9201 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9202 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9203 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9204 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9205 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9208 * Set up output mixers (0x0c - 0x0e)
9210 /* set vol=0 to output mixers */
9211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9212 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9213 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9214 /* set up input amps for analog loopback */
9215 /* Amp Indices: DAC = 0, mixer = 1 */
9216 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9225 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9227 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9228 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9230 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9232 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9234 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9237 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9239 /* FIXME: use matrix-type input source selection */
9240 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9241 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9242 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9243 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9247 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9248 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9249 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9250 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9252 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9253 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9254 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9255 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9260 static struct hda_verb alc262_eapd_verbs[] = {
9261 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9262 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9266 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9267 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9272 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9274 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9275 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9277 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9278 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9282 static struct hda_verb alc262_sony_unsol_verbs[] = {
9283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9285 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9287 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9292 static struct hda_input_mux alc262_dmic_capture_source = {
9295 { "Int DMic", 0x9 },
9300 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9301 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9302 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9303 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9306 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9307 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9310 /* The multiple "Capture Source" controls confuse alsamixer
9311 * So call somewhat different..
9313 /* .name = "Capture Source", */
9314 .name = "Input Source",
9316 .info = alc_mux_enum_info,
9317 .get = alc_mux_enum_get,
9318 .put = alc_mux_enum_put,
9323 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9328 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9329 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9330 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9335 static void alc262_dmic_automute(struct hda_codec *codec)
9337 unsigned int present;
9339 present = snd_hda_codec_read(codec, 0x18, 0,
9340 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9341 snd_hda_codec_write(codec, 0x22, 0,
9342 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9345 /* toggle speaker-output according to the hp-jack state */
9346 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9348 unsigned int present;
9351 present = snd_hda_codec_read(codec, 0x15, 0,
9352 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9353 bits = present ? 0 : PIN_OUT;
9354 snd_hda_codec_write(codec, 0x14, 0,
9355 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9360 /* unsolicited event for HP jack sensing */
9361 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9364 if ((res >> 26) == ALC880_HP_EVENT)
9365 alc262_toshiba_s06_speaker_automute(codec);
9366 if ((res >> 26) == ALC880_MIC_EVENT)
9367 alc262_dmic_automute(codec);
9371 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9373 alc262_toshiba_s06_speaker_automute(codec);
9374 alc262_dmic_automute(codec);
9377 /* mute/unmute internal speaker according to the hp jack and mute state */
9378 static void alc262_hippo_automute(struct hda_codec *codec)
9380 struct alc_spec *spec = codec->spec;
9382 unsigned int present;
9384 /* need to execute and sync at first */
9385 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9386 present = snd_hda_codec_read(codec, 0x15, 0,
9387 AC_VERB_GET_PIN_SENSE, 0);
9388 spec->jack_present = (present & 0x80000000) != 0;
9389 if (spec->jack_present) {
9390 /* mute internal speaker */
9391 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9392 HDA_AMP_MUTE, HDA_AMP_MUTE);
9394 /* unmute internal speaker if necessary */
9395 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9396 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9397 HDA_AMP_MUTE, mute);
9401 /* unsolicited event for HP jack sensing */
9402 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9405 if ((res >> 26) != ALC880_HP_EVENT)
9407 alc262_hippo_automute(codec);
9410 static void alc262_hippo1_automute(struct hda_codec *codec)
9413 unsigned int present;
9415 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9416 present = snd_hda_codec_read(codec, 0x1b, 0,
9417 AC_VERB_GET_PIN_SENSE, 0);
9418 present = (present & 0x80000000) != 0;
9420 /* mute internal speaker */
9421 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9422 HDA_AMP_MUTE, HDA_AMP_MUTE);
9424 /* unmute internal speaker if necessary */
9425 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9426 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9427 HDA_AMP_MUTE, mute);
9431 /* unsolicited event for HP jack sensing */
9432 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9435 if ((res >> 26) != ALC880_HP_EVENT)
9437 alc262_hippo1_automute(codec);
9443 * 0x16 = internal speaker
9444 * 0x18 = external mic
9447 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9448 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9449 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9453 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9456 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9460 static struct hda_verb alc262_nec_verbs[] = {
9461 /* Unmute Speaker */
9462 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9468 /* External mic to headphone */
9469 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9470 /* External mic to speaker */
9471 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9477 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9478 * 0x1b = port replicator headphone out
9481 #define ALC_HP_EVENT 0x37
9483 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9484 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9486 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9491 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9492 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9493 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9497 static struct hda_input_mux alc262_fujitsu_capture_source = {
9506 static struct hda_input_mux alc262_HP_capture_source = {
9510 { "Front Mic", 0x1 },
9517 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9521 { "Front Mic", 0x2 },
9527 /* mute/unmute internal speaker according to the hp jacks and mute state */
9528 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9530 struct alc_spec *spec = codec->spec;
9533 if (force || !spec->sense_updated) {
9534 unsigned int present;
9535 /* need to execute and sync at first */
9536 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9537 /* check laptop HP jack */
9538 present = snd_hda_codec_read(codec, 0x14, 0,
9539 AC_VERB_GET_PIN_SENSE, 0);
9540 /* need to execute and sync at first */
9541 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9542 /* check docking HP jack */
9543 present |= snd_hda_codec_read(codec, 0x1b, 0,
9544 AC_VERB_GET_PIN_SENSE, 0);
9545 if (present & AC_PINSENSE_PRESENCE)
9546 spec->jack_present = 1;
9548 spec->jack_present = 0;
9549 spec->sense_updated = 1;
9551 /* unmute internal speaker only if both HPs are unplugged and
9552 * master switch is on
9554 if (spec->jack_present)
9555 mute = HDA_AMP_MUTE;
9557 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9558 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9559 HDA_AMP_MUTE, mute);
9562 /* unsolicited event for HP jack sensing */
9563 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9566 if ((res >> 26) != ALC_HP_EVENT)
9568 alc262_fujitsu_automute(codec, 1);
9571 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9573 alc262_fujitsu_automute(codec, 1);
9576 /* bind volumes of both NID 0x0c and 0x0d */
9577 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9578 .ops = &snd_hda_bind_vol,
9580 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9581 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9586 /* mute/unmute internal speaker according to the hp jack and mute state */
9587 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9589 struct alc_spec *spec = codec->spec;
9592 if (force || !spec->sense_updated) {
9593 unsigned int present_int_hp;
9594 /* need to execute and sync at first */
9595 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9596 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9597 AC_VERB_GET_PIN_SENSE, 0);
9598 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9599 spec->sense_updated = 1;
9601 if (spec->jack_present) {
9602 /* mute internal speaker */
9603 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9604 HDA_AMP_MUTE, HDA_AMP_MUTE);
9605 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9606 HDA_AMP_MUTE, HDA_AMP_MUTE);
9608 /* unmute internal speaker if necessary */
9609 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9610 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9611 HDA_AMP_MUTE, mute);
9612 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9613 HDA_AMP_MUTE, mute);
9617 /* unsolicited event for HP jack sensing */
9618 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9621 if ((res >> 26) != ALC_HP_EVENT)
9623 alc262_lenovo_3000_automute(codec, 1);
9626 /* bind hp and internal speaker mute (with plug check) */
9627 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9628 struct snd_ctl_elem_value *ucontrol)
9630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9631 long *valp = ucontrol->value.integer.value;
9634 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9636 valp ? 0 : HDA_AMP_MUTE);
9637 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9639 valp ? 0 : HDA_AMP_MUTE);
9642 alc262_fujitsu_automute(codec, 0);
9646 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9647 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9649 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9650 .name = "Master Playback Switch",
9651 .info = snd_hda_mixer_amp_switch_info,
9652 .get = snd_hda_mixer_amp_switch_get,
9653 .put = alc262_fujitsu_master_sw_put,
9654 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9656 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9657 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9658 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9659 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9660 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9663 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9664 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9665 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9669 /* bind hp and internal speaker mute (with plug check) */
9670 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9671 struct snd_ctl_elem_value *ucontrol)
9673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9674 long *valp = ucontrol->value.integer.value;
9677 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9679 valp ? 0 : HDA_AMP_MUTE);
9682 alc262_lenovo_3000_automute(codec, 0);
9686 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9687 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9690 .name = "Master Playback Switch",
9691 .info = snd_hda_mixer_amp_switch_info,
9692 .get = snd_hda_mixer_amp_switch_get,
9693 .put = alc262_lenovo_3000_master_sw_put,
9694 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9696 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9697 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9698 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9699 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9700 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9701 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9702 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9703 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9707 /* additional init verbs for Benq laptops */
9708 static struct hda_verb alc262_EAPD_verbs[] = {
9709 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9710 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9714 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9715 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9716 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9718 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9719 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9723 /* Samsung Q1 Ultra Vista model setup */
9724 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9725 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9726 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9729 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9730 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9734 static struct hda_verb alc262_ultra_verbs[] = {
9736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9743 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9748 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9749 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9751 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9753 /* ADC, choose mic */
9754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9767 /* mute/unmute internal speaker according to the hp jack and mute state */
9768 static void alc262_ultra_automute(struct hda_codec *codec)
9770 struct alc_spec *spec = codec->spec;
9774 /* auto-mute only when HP is used as HP */
9775 if (!spec->cur_mux[0]) {
9776 unsigned int present;
9777 /* need to execute and sync at first */
9778 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9779 present = snd_hda_codec_read(codec, 0x15, 0,
9780 AC_VERB_GET_PIN_SENSE, 0);
9781 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9782 if (spec->jack_present)
9783 mute = HDA_AMP_MUTE;
9785 /* mute/unmute internal speaker */
9786 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9787 HDA_AMP_MUTE, mute);
9788 /* mute/unmute HP */
9789 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9790 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9793 /* unsolicited event for HP jack sensing */
9794 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9797 if ((res >> 26) != ALC880_HP_EVENT)
9799 alc262_ultra_automute(codec);
9802 static struct hda_input_mux alc262_ultra_capture_source = {
9806 { "Headphone", 0x7 },
9810 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9811 struct snd_ctl_elem_value *ucontrol)
9813 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9814 struct alc_spec *spec = codec->spec;
9817 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9820 /* reprogram the HP pin as mic or HP according to the input source */
9821 snd_hda_codec_write_cache(codec, 0x15, 0,
9822 AC_VERB_SET_PIN_WIDGET_CONTROL,
9823 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9824 alc262_ultra_automute(codec); /* mute/unmute HP */
9828 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9829 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9830 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9833 .name = "Capture Source",
9834 .info = alc882_mux_enum_info,
9835 .get = alc882_mux_enum_get,
9836 .put = alc262_ultra_mux_enum_put,
9841 /* add playback controls from the parsed DAC table */
9842 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9843 const struct auto_pin_cfg *cfg)
9848 spec->multiout.num_dacs = 1; /* only use one dac */
9849 spec->multiout.dac_nids = spec->private_dac_nids;
9850 spec->multiout.dac_nids[0] = 2;
9852 nid = cfg->line_out_pins[0];
9854 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9855 "Front Playback Volume",
9856 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9859 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9860 "Front Playback Switch",
9861 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9866 nid = cfg->speaker_pins[0];
9869 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9870 "Speaker Playback Volume",
9871 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9875 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9876 "Speaker Playback Switch",
9877 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9882 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9883 "Speaker Playback Switch",
9884 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9890 nid = cfg->hp_pins[0];
9892 /* spec->multiout.hp_nid = 2; */
9894 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9895 "Headphone Playback Volume",
9896 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9900 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9901 "Headphone Playback Switch",
9902 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9907 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9908 "Headphone Playback Switch",
9909 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9918 /* identical with ALC880 */
9919 #define alc262_auto_create_analog_input_ctls \
9920 alc880_auto_create_analog_input_ctls
9923 * generic initialization of ADC, input mixers and output mixers
9925 static struct hda_verb alc262_volume_init_verbs[] = {
9927 * Unmute ADC0-2 and set the default input to mic-in
9929 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9930 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9931 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9932 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9933 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9934 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9936 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9938 * Note: PASD motherboards uses the Line In 2 as the input for
9939 * front panel mic (mic 2)
9941 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9943 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9944 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9945 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9949 * Set up output mixers (0x0c - 0x0f)
9951 /* set vol=0 to output mixers */
9952 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9953 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9954 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9956 /* set up input amps for analog loopback */
9957 /* Amp Indices: DAC = 0, mixer = 1 */
9958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9965 /* FIXME: use matrix-type input source selection */
9966 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9967 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9973 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9974 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9975 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9976 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9980 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9986 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9988 * Unmute ADC0-2 and set the default input to mic-in
9990 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9992 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9993 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9994 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9995 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9997 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9999 * Note: PASD motherboards uses the Line In 2 as the input for
10000 * front panel mic (mic 2)
10002 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10003 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10005 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10012 * Set up output mixers (0x0c - 0x0e)
10014 /* set vol=0 to output mixers */
10015 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10016 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10017 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10019 /* set up input amps for analog loopback */
10020 /* Amp Indices: DAC = 0, mixer = 1 */
10021 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10023 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10024 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10025 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10026 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10030 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10032 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10035 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10036 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10038 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10039 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10040 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10041 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10042 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10044 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10045 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10047 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10048 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10049 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10052 /* FIXME: use matrix-type input source selection */
10053 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10054 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10055 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10060 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10070 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10075 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10077 * Unmute ADC0-2 and set the default input to mic-in
10079 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10081 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10082 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10083 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10084 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10086 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10088 * Note: PASD motherboards uses the Line In 2 as the input for front
10089 * panel mic (mic 2)
10091 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10101 * Set up output mixers (0x0c - 0x0e)
10103 /* set vol=0 to output mixers */
10104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10108 /* set up input amps for analog loopback */
10109 /* Amp Indices: DAC = 0, mixer = 1 */
10110 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10114 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10119 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10120 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10121 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10122 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10123 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10124 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10126 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10129 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10130 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10132 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10134 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10136 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10137 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10139 /* FIXME: use matrix-type input source selection */
10140 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10141 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10142 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10145 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10147 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10150 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10155 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10160 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10161 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10163 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10164 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10166 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10171 #ifdef CONFIG_SND_HDA_POWER_SAVE
10172 #define alc262_loopbacks alc880_loopbacks
10175 /* pcm configuration: identiacal with ALC880 */
10176 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10177 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10178 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10179 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10182 * BIOS auto configuration
10184 static int alc262_parse_auto_config(struct hda_codec *codec)
10186 struct alc_spec *spec = codec->spec;
10188 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10190 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10194 if (!spec->autocfg.line_outs)
10195 return 0; /* can't find valid BIOS pin config */
10196 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10199 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10203 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10205 if (spec->autocfg.dig_out_pin)
10206 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10207 if (spec->autocfg.dig_in_pin)
10208 spec->dig_in_nid = ALC262_DIGIN_NID;
10210 if (spec->kctl_alloc)
10211 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10213 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10214 spec->num_mux_defs = 1;
10215 spec->input_mux = &spec->private_imux;
10217 err = alc_auto_add_mic_boost(codec);
10224 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10225 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10226 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10227 #define alc262_auto_init_input_src alc882_auto_init_input_src
10230 /* init callback for auto-configuration model -- overriding the default init */
10231 static void alc262_auto_init(struct hda_codec *codec)
10233 struct alc_spec *spec = codec->spec;
10234 alc262_auto_init_multi_out(codec);
10235 alc262_auto_init_hp_out(codec);
10236 alc262_auto_init_analog_input(codec);
10237 alc262_auto_init_input_src(codec);
10238 if (spec->unsol_event)
10239 alc_sku_automute(codec);
10243 * configuration and preset
10245 static const char *alc262_models[ALC262_MODEL_LAST] = {
10246 [ALC262_BASIC] = "basic",
10247 [ALC262_HIPPO] = "hippo",
10248 [ALC262_HIPPO_1] = "hippo_1",
10249 [ALC262_FUJITSU] = "fujitsu",
10250 [ALC262_HP_BPC] = "hp-bpc",
10251 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10252 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10253 [ALC262_HP_RP5700] = "hp-rp5700",
10254 [ALC262_BENQ_ED8] = "benq",
10255 [ALC262_BENQ_T31] = "benq-t31",
10256 [ALC262_SONY_ASSAMD] = "sony-assamd",
10257 [ALC262_ULTRA] = "ultra",
10258 [ALC262_LENOVO_3000] = "lenovo-3000",
10259 [ALC262_NEC] = "nec",
10260 [ALC262_AUTO] = "auto",
10263 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10264 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10265 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10266 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10267 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10268 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10269 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10270 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10271 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10272 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10273 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10274 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10275 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10276 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10277 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10278 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10279 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10280 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10281 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10282 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10283 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10284 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10285 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10286 ALC262_HP_TC_T5735),
10287 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10288 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10289 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10290 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10291 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10292 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10293 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10294 ALC262_SONY_ASSAMD),
10295 SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
10296 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10297 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10298 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10299 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10300 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10301 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10302 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10303 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10307 static struct alc_config_preset alc262_presets[] = {
10309 .mixers = { alc262_base_mixer },
10310 .init_verbs = { alc262_init_verbs },
10311 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10312 .dac_nids = alc262_dac_nids,
10314 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10315 .channel_mode = alc262_modes,
10316 .input_mux = &alc262_capture_source,
10319 .mixers = { alc262_base_mixer },
10320 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10321 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10322 .dac_nids = alc262_dac_nids,
10324 .dig_out_nid = ALC262_DIGOUT_NID,
10325 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10326 .channel_mode = alc262_modes,
10327 .input_mux = &alc262_capture_source,
10328 .unsol_event = alc262_hippo_unsol_event,
10329 .init_hook = alc262_hippo_automute,
10331 [ALC262_HIPPO_1] = {
10332 .mixers = { alc262_hippo1_mixer },
10333 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10334 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10335 .dac_nids = alc262_dac_nids,
10337 .dig_out_nid = ALC262_DIGOUT_NID,
10338 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10339 .channel_mode = alc262_modes,
10340 .input_mux = &alc262_capture_source,
10341 .unsol_event = alc262_hippo1_unsol_event,
10342 .init_hook = alc262_hippo1_automute,
10344 [ALC262_FUJITSU] = {
10345 .mixers = { alc262_fujitsu_mixer },
10346 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10347 alc262_fujitsu_unsol_verbs },
10348 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10349 .dac_nids = alc262_dac_nids,
10351 .dig_out_nid = ALC262_DIGOUT_NID,
10352 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10353 .channel_mode = alc262_modes,
10354 .input_mux = &alc262_fujitsu_capture_source,
10355 .unsol_event = alc262_fujitsu_unsol_event,
10356 .init_hook = alc262_fujitsu_init_hook,
10358 [ALC262_HP_BPC] = {
10359 .mixers = { alc262_HP_BPC_mixer },
10360 .init_verbs = { alc262_HP_BPC_init_verbs },
10361 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10362 .dac_nids = alc262_dac_nids,
10364 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10365 .channel_mode = alc262_modes,
10366 .input_mux = &alc262_HP_capture_source,
10367 .unsol_event = alc262_hp_bpc_unsol_event,
10368 .init_hook = alc262_hp_bpc_automute,
10370 [ALC262_HP_BPC_D7000_WF] = {
10371 .mixers = { alc262_HP_BPC_WildWest_mixer },
10372 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10373 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10374 .dac_nids = alc262_dac_nids,
10376 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10377 .channel_mode = alc262_modes,
10378 .input_mux = &alc262_HP_D7000_capture_source,
10379 .unsol_event = alc262_hp_wildwest_unsol_event,
10380 .init_hook = alc262_hp_wildwest_automute,
10382 [ALC262_HP_BPC_D7000_WL] = {
10383 .mixers = { alc262_HP_BPC_WildWest_mixer,
10384 alc262_HP_BPC_WildWest_option_mixer },
10385 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10386 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10387 .dac_nids = alc262_dac_nids,
10389 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10390 .channel_mode = alc262_modes,
10391 .input_mux = &alc262_HP_D7000_capture_source,
10392 .unsol_event = alc262_hp_wildwest_unsol_event,
10393 .init_hook = alc262_hp_wildwest_automute,
10395 [ALC262_HP_TC_T5735] = {
10396 .mixers = { alc262_hp_t5735_mixer },
10397 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10398 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10399 .dac_nids = alc262_dac_nids,
10401 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10402 .channel_mode = alc262_modes,
10403 .input_mux = &alc262_capture_source,
10404 .unsol_event = alc262_hp_t5735_unsol_event,
10405 .init_hook = alc262_hp_t5735_init_hook,
10407 [ALC262_HP_RP5700] = {
10408 .mixers = { alc262_hp_rp5700_mixer },
10409 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10410 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10411 .dac_nids = alc262_dac_nids,
10412 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10413 .channel_mode = alc262_modes,
10414 .input_mux = &alc262_hp_rp5700_capture_source,
10416 [ALC262_BENQ_ED8] = {
10417 .mixers = { alc262_base_mixer },
10418 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10419 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10420 .dac_nids = alc262_dac_nids,
10422 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10423 .channel_mode = alc262_modes,
10424 .input_mux = &alc262_capture_source,
10426 [ALC262_SONY_ASSAMD] = {
10427 .mixers = { alc262_sony_mixer },
10428 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10429 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10430 .dac_nids = alc262_dac_nids,
10432 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10433 .channel_mode = alc262_modes,
10434 .input_mux = &alc262_capture_source,
10435 .unsol_event = alc262_hippo_unsol_event,
10436 .init_hook = alc262_hippo_automute,
10438 [ALC262_BENQ_T31] = {
10439 .mixers = { alc262_benq_t31_mixer },
10440 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10441 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10442 .dac_nids = alc262_dac_nids,
10444 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10445 .channel_mode = alc262_modes,
10446 .input_mux = &alc262_capture_source,
10447 .unsol_event = alc262_hippo_unsol_event,
10448 .init_hook = alc262_hippo_automute,
10451 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10452 .init_verbs = { alc262_ultra_verbs },
10453 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10454 .dac_nids = alc262_dac_nids,
10455 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10456 .channel_mode = alc262_modes,
10457 .input_mux = &alc262_ultra_capture_source,
10458 .adc_nids = alc262_adc_nids, /* ADC0 */
10459 .capsrc_nids = alc262_capsrc_nids,
10460 .num_adc_nids = 1, /* single ADC */
10461 .unsol_event = alc262_ultra_unsol_event,
10462 .init_hook = alc262_ultra_automute,
10464 [ALC262_LENOVO_3000] = {
10465 .mixers = { alc262_lenovo_3000_mixer },
10466 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10467 alc262_lenovo_3000_unsol_verbs },
10468 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10469 .dac_nids = alc262_dac_nids,
10471 .dig_out_nid = ALC262_DIGOUT_NID,
10472 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10473 .channel_mode = alc262_modes,
10474 .input_mux = &alc262_fujitsu_capture_source,
10475 .unsol_event = alc262_lenovo_3000_unsol_event,
10478 .mixers = { alc262_nec_mixer },
10479 .init_verbs = { alc262_nec_verbs },
10480 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10481 .dac_nids = alc262_dac_nids,
10483 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10484 .channel_mode = alc262_modes,
10485 .input_mux = &alc262_capture_source,
10487 [ALC262_TOSHIBA_S06] = {
10488 .mixers = { alc262_toshiba_s06_mixer },
10489 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10490 alc262_eapd_verbs },
10491 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10492 .capsrc_nids = alc262_dmic_capsrc_nids,
10493 .dac_nids = alc262_dac_nids,
10494 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10495 .dig_out_nid = ALC262_DIGOUT_NID,
10496 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10497 .channel_mode = alc262_modes,
10498 .input_mux = &alc262_dmic_capture_source,
10499 .unsol_event = alc262_toshiba_s06_unsol_event,
10500 .init_hook = alc262_toshiba_s06_init_hook,
10504 static int patch_alc262(struct hda_codec *codec)
10506 struct alc_spec *spec;
10510 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10514 codec->spec = spec;
10516 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10521 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10522 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10523 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10524 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10528 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10530 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10534 if (board_config < 0) {
10535 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10536 "trying auto-probe from BIOS...\n");
10537 board_config = ALC262_AUTO;
10540 if (board_config == ALC262_AUTO) {
10541 /* automatic parse from the BIOS config */
10542 err = alc262_parse_auto_config(codec);
10548 "hda_codec: Cannot set up configuration "
10549 "from BIOS. Using base mode...\n");
10550 board_config = ALC262_BASIC;
10554 if (board_config != ALC262_AUTO)
10555 setup_preset(spec, &alc262_presets[board_config]);
10557 spec->stream_name_analog = "ALC262 Analog";
10558 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10559 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10561 spec->stream_name_digital = "ALC262 Digital";
10562 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10563 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10565 if (!spec->adc_nids && spec->input_mux) {
10566 /* check whether NID 0x07 is valid */
10567 unsigned int wcap = get_wcaps(codec, 0x07);
10570 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10571 if (wcap != AC_WID_AUD_IN) {
10572 spec->adc_nids = alc262_adc_nids_alt;
10573 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10574 spec->capsrc_nids = alc262_capsrc_nids_alt;
10575 spec->mixers[spec->num_mixers] =
10576 alc262_capture_alt_mixer;
10577 spec->num_mixers++;
10579 spec->adc_nids = alc262_adc_nids;
10580 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10581 spec->capsrc_nids = alc262_capsrc_nids;
10582 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10583 spec->num_mixers++;
10587 spec->vmaster_nid = 0x0c;
10589 codec->patch_ops = alc_patch_ops;
10590 if (board_config == ALC262_AUTO)
10591 spec->init_hook = alc262_auto_init;
10592 #ifdef CONFIG_SND_HDA_POWER_SAVE
10593 if (!spec->loopback.amplist)
10594 spec->loopback.amplist = alc262_loopbacks;
10601 * ALC268 channel source setting (2 channel)
10603 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10604 #define alc268_modes alc260_modes
10606 static hda_nid_t alc268_dac_nids[2] = {
10611 static hda_nid_t alc268_adc_nids[2] = {
10616 static hda_nid_t alc268_adc_nids_alt[1] = {
10621 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10623 static struct snd_kcontrol_new alc268_base_mixer[] = {
10624 /* output mixer control */
10625 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10626 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10627 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10628 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10629 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10630 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10631 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10635 /* bind Beep switches of both NID 0x0f and 0x10 */
10636 static struct hda_bind_ctls alc268_bind_beep_sw = {
10637 .ops = &snd_hda_bind_sw,
10639 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10640 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10645 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10646 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10647 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10651 static struct hda_verb alc268_eapd_verbs[] = {
10652 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10653 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10657 /* Toshiba specific */
10658 #define alc268_toshiba_automute alc262_hippo_automute
10660 static struct hda_verb alc268_toshiba_verbs[] = {
10661 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10665 static struct hda_input_mux alc268_acer_lc_capture_source = {
10673 /* Acer specific */
10674 /* bind volumes of both NID 0x02 and 0x03 */
10675 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10676 .ops = &snd_hda_bind_vol,
10678 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10679 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10684 /* mute/unmute internal speaker according to the hp jack and mute state */
10685 static void alc268_acer_automute(struct hda_codec *codec, int force)
10687 struct alc_spec *spec = codec->spec;
10690 if (force || !spec->sense_updated) {
10691 unsigned int present;
10692 present = snd_hda_codec_read(codec, 0x14, 0,
10693 AC_VERB_GET_PIN_SENSE, 0);
10694 spec->jack_present = (present & 0x80000000) != 0;
10695 spec->sense_updated = 1;
10697 if (spec->jack_present)
10698 mute = HDA_AMP_MUTE; /* mute internal speaker */
10699 else /* unmute internal speaker if necessary */
10700 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10701 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10702 HDA_AMP_MUTE, mute);
10706 /* bind hp and internal speaker mute (with plug check) */
10707 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10708 struct snd_ctl_elem_value *ucontrol)
10710 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10711 long *valp = ucontrol->value.integer.value;
10714 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10716 valp[0] ? 0 : HDA_AMP_MUTE);
10717 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10719 valp[1] ? 0 : HDA_AMP_MUTE);
10721 alc268_acer_automute(codec, 0);
10725 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10726 /* output mixer control */
10727 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10730 .name = "Master Playback Switch",
10731 .info = snd_hda_mixer_amp_switch_info,
10732 .get = snd_hda_mixer_amp_switch_get,
10733 .put = alc268_acer_master_sw_put,
10734 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10736 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10740 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10741 /* output mixer control */
10742 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10745 .name = "Master Playback Switch",
10746 .info = snd_hda_mixer_amp_switch_info,
10747 .get = snd_hda_mixer_amp_switch_get,
10748 .put = alc268_acer_master_sw_put,
10749 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10751 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10752 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10753 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10757 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10758 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10759 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10760 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10761 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10762 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10767 static struct hda_verb alc268_acer_verbs[] = {
10768 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10769 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10771 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10772 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10774 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10778 /* unsolicited event for HP jack sensing */
10779 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10782 if ((res >> 26) != ALC880_HP_EVENT)
10784 alc268_toshiba_automute(codec);
10787 static void alc268_acer_unsol_event(struct hda_codec *codec,
10790 if ((res >> 26) != ALC880_HP_EVENT)
10792 alc268_acer_automute(codec, 1);
10795 static void alc268_acer_init_hook(struct hda_codec *codec)
10797 alc268_acer_automute(codec, 1);
10800 /* toggle speaker-output according to the hp-jack state */
10801 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10803 unsigned int present;
10804 unsigned char bits;
10806 present = snd_hda_codec_read(codec, 0x15, 0,
10807 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10808 bits = present ? AMP_IN_MUTE(0) : 0;
10809 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10810 AMP_IN_MUTE(0), bits);
10811 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10812 AMP_IN_MUTE(0), bits);
10816 static void alc268_acer_mic_automute(struct hda_codec *codec)
10818 unsigned int present;
10820 present = snd_hda_codec_read(codec, 0x18, 0,
10821 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10822 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10823 present ? 0x0 : 0x6);
10826 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10829 if ((res >> 26) == ALC880_HP_EVENT)
10830 alc268_aspire_one_speaker_automute(codec);
10831 if ((res >> 26) == ALC880_MIC_EVENT)
10832 alc268_acer_mic_automute(codec);
10835 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10837 alc268_aspire_one_speaker_automute(codec);
10838 alc268_acer_mic_automute(codec);
10841 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10842 /* output mixer control */
10843 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10844 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10845 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10847 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10848 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10852 static struct hda_verb alc268_dell_verbs[] = {
10853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10855 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10859 /* mute/unmute internal speaker according to the hp jack and mute state */
10860 static void alc268_dell_automute(struct hda_codec *codec)
10862 unsigned int present;
10865 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10866 if (present & 0x80000000)
10867 mute = HDA_AMP_MUTE;
10869 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10870 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10871 HDA_AMP_MUTE, mute);
10874 static void alc268_dell_unsol_event(struct hda_codec *codec,
10877 if ((res >> 26) != ALC880_HP_EVENT)
10879 alc268_dell_automute(codec);
10882 #define alc268_dell_init_hook alc268_dell_automute
10884 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10885 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10886 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10887 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10888 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10889 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10890 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10891 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10892 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10896 static struct hda_verb alc267_quanta_il1_verbs[] = {
10897 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10898 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10902 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10904 unsigned int present;
10906 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10907 & AC_PINSENSE_PRESENCE;
10908 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10909 present ? 0 : PIN_OUT);
10912 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10914 unsigned int present;
10916 present = snd_hda_codec_read(codec, 0x18, 0,
10917 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10918 snd_hda_codec_write(codec, 0x23, 0,
10919 AC_VERB_SET_CONNECT_SEL,
10920 present ? 0x00 : 0x01);
10923 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10925 alc267_quanta_il1_hp_automute(codec);
10926 alc267_quanta_il1_mic_automute(codec);
10929 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10932 switch (res >> 26) {
10933 case ALC880_HP_EVENT:
10934 alc267_quanta_il1_hp_automute(codec);
10936 case ALC880_MIC_EVENT:
10937 alc267_quanta_il1_mic_automute(codec);
10943 * generic initialization of ADC, input mixers and output mixers
10945 static struct hda_verb alc268_base_init_verbs[] = {
10946 /* Unmute DAC0-1 and set vol = 0 */
10947 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10948 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10949 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10950 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10951 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10952 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10955 * Set up output mixers (0x0c - 0x0e)
10957 /* set vol=0 to output mixers */
10958 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10959 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10960 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10961 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10964 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10966 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10972 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10973 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10977 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10978 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10979 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10980 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10981 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10983 /* set PCBEEP vol = 0, mute connections */
10984 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10985 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10986 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10988 /* Unmute Selector 23h,24h and set the default input to mic-in */
10990 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10991 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10992 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10999 * generic initialization of ADC, input mixers and output mixers
11001 static struct hda_verb alc268_volume_init_verbs[] = {
11002 /* set output DAC */
11003 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11004 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11005 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11006 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11008 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11009 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11010 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11012 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11014 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11015 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11018 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11020 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11021 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11022 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11023 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11025 /* set PCBEEP vol = 0, mute connections */
11026 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11027 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11028 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11033 #define alc268_mux_enum_info alc_mux_enum_info
11034 #define alc268_mux_enum_get alc_mux_enum_get
11035 #define alc268_mux_enum_put alc_mux_enum_put
11037 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11038 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11039 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11042 /* The multiple "Capture Source" controls confuse alsamixer
11043 * So call somewhat different..
11045 /* .name = "Capture Source", */
11046 .name = "Input Source",
11048 .info = alc268_mux_enum_info,
11049 .get = alc268_mux_enum_get,
11050 .put = alc268_mux_enum_put,
11055 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11056 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11057 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11058 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11059 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11062 /* The multiple "Capture Source" controls confuse alsamixer
11063 * So call somewhat different..
11065 /* .name = "Capture Source", */
11066 .name = "Input Source",
11068 .info = alc268_mux_enum_info,
11069 .get = alc268_mux_enum_get,
11070 .put = alc268_mux_enum_put,
11075 static struct hda_input_mux alc268_capture_source = {
11079 { "Front Mic", 0x1 },
11085 static struct hda_input_mux alc268_acer_capture_source = {
11089 { "Internal Mic", 0x6 },
11094 #ifdef CONFIG_SND_DEBUG
11095 static struct snd_kcontrol_new alc268_test_mixer[] = {
11096 /* Volume widgets */
11097 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11098 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11099 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11100 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11101 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11102 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11103 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11104 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11105 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11106 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11107 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11108 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11109 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11110 /* The below appears problematic on some hardwares */
11111 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11112 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11113 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11114 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11115 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11117 /* Modes for retasking pin widgets */
11118 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11119 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11120 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11121 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11123 /* Controls for GPIO pins, assuming they are configured as outputs */
11124 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11125 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11126 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11127 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11129 /* Switches to allow the digital SPDIF output pin to be enabled.
11130 * The ALC268 does not have an SPDIF input.
11132 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11134 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11135 * this output to turn on an external amplifier.
11137 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11138 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11144 /* create input playback/capture controls for the given pin */
11145 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11146 const char *ctlname, int idx)
11151 sprintf(name, "%s Playback Volume", ctlname);
11153 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11154 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11158 } else if (nid == 0x15) {
11159 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11160 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11166 sprintf(name, "%s Playback Switch", ctlname);
11167 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11168 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11174 /* add playback controls from the parsed DAC table */
11175 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11176 const struct auto_pin_cfg *cfg)
11181 spec->multiout.num_dacs = 2; /* only use one dac */
11182 spec->multiout.dac_nids = spec->private_dac_nids;
11183 spec->multiout.dac_nids[0] = 2;
11184 spec->multiout.dac_nids[1] = 3;
11186 nid = cfg->line_out_pins[0];
11188 alc268_new_analog_output(spec, nid, "Front", 0);
11190 nid = cfg->speaker_pins[0];
11192 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11193 "Speaker Playback Volume",
11194 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11198 nid = cfg->hp_pins[0];
11200 alc268_new_analog_output(spec, nid, "Headphone", 0);
11202 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11204 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11205 "Mono Playback Switch",
11206 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11213 /* create playback/capture controls for input pins */
11214 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11215 const struct auto_pin_cfg *cfg)
11217 struct hda_input_mux *imux = &spec->private_imux;
11220 for (i = 0; i < AUTO_PIN_LAST; i++) {
11221 switch(cfg->input_pins[i]) {
11223 idx1 = 0; /* Mic 1 */
11226 idx1 = 1; /* Mic 2 */
11229 idx1 = 2; /* Line In */
11236 idx1 = 6; /* digital mics */
11241 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11242 imux->items[imux->num_items].index = idx1;
11248 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11250 struct alc_spec *spec = codec->spec;
11251 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11252 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11253 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11254 unsigned int dac_vol1, dac_vol2;
11257 snd_hda_codec_write(codec, speaker_nid, 0,
11258 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11259 snd_hda_codec_write(codec, 0x0f, 0,
11260 AC_VERB_SET_AMP_GAIN_MUTE,
11262 snd_hda_codec_write(codec, 0x10, 0,
11263 AC_VERB_SET_AMP_GAIN_MUTE,
11266 snd_hda_codec_write(codec, 0x0f, 0,
11267 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11268 snd_hda_codec_write(codec, 0x10, 0,
11269 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11272 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11273 if (line_nid == 0x14)
11274 dac_vol2 = AMP_OUT_ZERO;
11275 else if (line_nid == 0x15)
11276 dac_vol1 = AMP_OUT_ZERO;
11277 if (hp_nid == 0x14)
11278 dac_vol2 = AMP_OUT_ZERO;
11279 else if (hp_nid == 0x15)
11280 dac_vol1 = AMP_OUT_ZERO;
11281 if (line_nid != 0x16 || hp_nid != 0x16 ||
11282 spec->autocfg.line_out_pins[1] != 0x16 ||
11283 spec->autocfg.line_out_pins[2] != 0x16)
11284 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11286 snd_hda_codec_write(codec, 0x02, 0,
11287 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11288 snd_hda_codec_write(codec, 0x03, 0,
11289 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11292 /* pcm configuration: identiacal with ALC880 */
11293 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11294 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11295 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11296 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11299 * BIOS auto configuration
11301 static int alc268_parse_auto_config(struct hda_codec *codec)
11303 struct alc_spec *spec = codec->spec;
11305 static hda_nid_t alc268_ignore[] = { 0 };
11307 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11311 if (!spec->autocfg.line_outs)
11312 return 0; /* can't find valid BIOS pin config */
11314 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11317 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11321 spec->multiout.max_channels = 2;
11323 /* digital only support output */
11324 if (spec->autocfg.dig_out_pin)
11325 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11327 if (spec->kctl_alloc)
11328 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11330 if (spec->autocfg.speaker_pins[0] != 0x1d)
11331 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11333 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11334 spec->num_mux_defs = 1;
11335 spec->input_mux = &spec->private_imux;
11337 err = alc_auto_add_mic_boost(codec);
11344 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11345 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11346 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11348 /* init callback for auto-configuration model -- overriding the default init */
11349 static void alc268_auto_init(struct hda_codec *codec)
11351 struct alc_spec *spec = codec->spec;
11352 alc268_auto_init_multi_out(codec);
11353 alc268_auto_init_hp_out(codec);
11354 alc268_auto_init_mono_speaker_out(codec);
11355 alc268_auto_init_analog_input(codec);
11356 if (spec->unsol_event)
11357 alc_sku_automute(codec);
11361 * configuration and preset
11363 static const char *alc268_models[ALC268_MODEL_LAST] = {
11364 [ALC267_QUANTA_IL1] = "quanta-il1",
11365 [ALC268_3ST] = "3stack",
11366 [ALC268_TOSHIBA] = "toshiba",
11367 [ALC268_ACER] = "acer",
11368 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11369 [ALC268_DELL] = "dell",
11370 [ALC268_ZEPTO] = "zepto",
11371 #ifdef CONFIG_SND_DEBUG
11372 [ALC268_TEST] = "test",
11374 [ALC268_AUTO] = "auto",
11377 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11378 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11379 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11380 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11381 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11382 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11383 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11384 ALC268_ACER_ASPIRE_ONE),
11385 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11386 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11387 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11388 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11389 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11390 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11391 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11392 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11393 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11397 static struct alc_config_preset alc268_presets[] = {
11398 [ALC267_QUANTA_IL1] = {
11399 .mixers = { alc267_quanta_il1_mixer },
11400 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11401 alc267_quanta_il1_verbs },
11402 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11403 .dac_nids = alc268_dac_nids,
11404 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11405 .adc_nids = alc268_adc_nids_alt,
11407 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11408 .channel_mode = alc268_modes,
11409 .input_mux = &alc268_capture_source,
11410 .unsol_event = alc267_quanta_il1_unsol_event,
11411 .init_hook = alc267_quanta_il1_automute,
11414 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11415 alc268_beep_mixer },
11416 .init_verbs = { alc268_base_init_verbs },
11417 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11418 .dac_nids = alc268_dac_nids,
11419 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11420 .adc_nids = alc268_adc_nids_alt,
11421 .capsrc_nids = alc268_capsrc_nids,
11423 .dig_out_nid = ALC268_DIGOUT_NID,
11424 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11425 .channel_mode = alc268_modes,
11426 .input_mux = &alc268_capture_source,
11428 [ALC268_TOSHIBA] = {
11429 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11430 alc268_beep_mixer },
11431 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11432 alc268_toshiba_verbs },
11433 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11434 .dac_nids = alc268_dac_nids,
11435 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11436 .adc_nids = alc268_adc_nids_alt,
11437 .capsrc_nids = alc268_capsrc_nids,
11439 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11440 .channel_mode = alc268_modes,
11441 .input_mux = &alc268_capture_source,
11442 .unsol_event = alc268_toshiba_unsol_event,
11443 .init_hook = alc268_toshiba_automute,
11446 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11447 alc268_beep_mixer },
11448 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11449 alc268_acer_verbs },
11450 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11451 .dac_nids = alc268_dac_nids,
11452 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11453 .adc_nids = alc268_adc_nids_alt,
11454 .capsrc_nids = alc268_capsrc_nids,
11456 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11457 .channel_mode = alc268_modes,
11458 .input_mux = &alc268_acer_capture_source,
11459 .unsol_event = alc268_acer_unsol_event,
11460 .init_hook = alc268_acer_init_hook,
11462 [ALC268_ACER_ASPIRE_ONE] = {
11463 .mixers = { alc268_acer_aspire_one_mixer,
11464 alc268_capture_alt_mixer },
11465 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11466 alc268_acer_aspire_one_verbs },
11467 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11468 .dac_nids = alc268_dac_nids,
11469 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11470 .adc_nids = alc268_adc_nids_alt,
11471 .capsrc_nids = alc268_capsrc_nids,
11473 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11474 .channel_mode = alc268_modes,
11475 .input_mux = &alc268_acer_lc_capture_source,
11476 .unsol_event = alc268_acer_lc_unsol_event,
11477 .init_hook = alc268_acer_lc_init_hook,
11480 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11481 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11482 alc268_dell_verbs },
11483 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11484 .dac_nids = alc268_dac_nids,
11486 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11487 .channel_mode = alc268_modes,
11488 .unsol_event = alc268_dell_unsol_event,
11489 .init_hook = alc268_dell_init_hook,
11490 .input_mux = &alc268_capture_source,
11493 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11494 alc268_beep_mixer },
11495 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11496 alc268_toshiba_verbs },
11497 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11498 .dac_nids = alc268_dac_nids,
11499 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11500 .adc_nids = alc268_adc_nids_alt,
11501 .capsrc_nids = alc268_capsrc_nids,
11503 .dig_out_nid = ALC268_DIGOUT_NID,
11504 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11505 .channel_mode = alc268_modes,
11506 .input_mux = &alc268_capture_source,
11507 .unsol_event = alc268_toshiba_unsol_event,
11508 .init_hook = alc268_toshiba_automute
11510 #ifdef CONFIG_SND_DEBUG
11512 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11513 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11514 alc268_volume_init_verbs },
11515 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11516 .dac_nids = alc268_dac_nids,
11517 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11518 .adc_nids = alc268_adc_nids_alt,
11519 .capsrc_nids = alc268_capsrc_nids,
11521 .dig_out_nid = ALC268_DIGOUT_NID,
11522 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11523 .channel_mode = alc268_modes,
11524 .input_mux = &alc268_capture_source,
11529 static int patch_alc268(struct hda_codec *codec)
11531 struct alc_spec *spec;
11535 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11539 codec->spec = spec;
11541 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11545 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11546 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11547 "trying auto-probe from BIOS...\n");
11548 board_config = ALC268_AUTO;
11551 if (board_config == ALC268_AUTO) {
11552 /* automatic parse from the BIOS config */
11553 err = alc268_parse_auto_config(codec);
11559 "hda_codec: Cannot set up configuration "
11560 "from BIOS. Using base mode...\n");
11561 board_config = ALC268_3ST;
11565 if (board_config != ALC268_AUTO)
11566 setup_preset(spec, &alc268_presets[board_config]);
11568 if (codec->vendor_id == 0x10ec0267) {
11569 spec->stream_name_analog = "ALC267 Analog";
11570 spec->stream_name_digital = "ALC267 Digital";
11572 spec->stream_name_analog = "ALC268 Analog";
11573 spec->stream_name_digital = "ALC268 Digital";
11576 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11577 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11578 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11580 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11582 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11583 /* override the amp caps for beep generator */
11584 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11585 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11586 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11587 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11588 (0 << AC_AMPCAP_MUTE_SHIFT));
11590 if (!spec->adc_nids && spec->input_mux) {
11591 /* check whether NID 0x07 is valid */
11592 unsigned int wcap = get_wcaps(codec, 0x07);
11596 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11597 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11598 spec->adc_nids = alc268_adc_nids_alt;
11599 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11600 spec->mixers[spec->num_mixers] =
11601 alc268_capture_alt_mixer;
11602 spec->num_mixers++;
11604 spec->adc_nids = alc268_adc_nids;
11605 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11606 spec->mixers[spec->num_mixers] =
11607 alc268_capture_mixer;
11608 spec->num_mixers++;
11610 spec->capsrc_nids = alc268_capsrc_nids;
11611 /* set default input source */
11612 for (i = 0; i < spec->num_adc_nids; i++)
11613 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11614 0, AC_VERB_SET_CONNECT_SEL,
11615 spec->input_mux->items[0].index);
11618 spec->vmaster_nid = 0x02;
11620 codec->patch_ops = alc_patch_ops;
11621 if (board_config == ALC268_AUTO)
11622 spec->init_hook = alc268_auto_init;
11628 * ALC269 channel source setting (2 channel)
11630 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11632 #define alc269_dac_nids alc260_dac_nids
11634 static hda_nid_t alc269_adc_nids[1] = {
11639 static hda_nid_t alc269_capsrc_nids[1] = {
11643 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11647 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11655 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11663 #define alc269_modes alc260_modes
11664 #define alc269_capture_source alc880_lg_lw_capture_source
11666 static struct snd_kcontrol_new alc269_base_mixer[] = {
11667 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11668 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11669 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11670 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11673 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11674 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11675 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11676 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11677 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11678 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11680 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11684 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11685 /* output mixer control */
11686 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11689 .name = "Master Playback Switch",
11690 .info = snd_hda_mixer_amp_switch_info,
11691 .get = snd_hda_mixer_amp_switch_get,
11692 .put = alc268_acer_master_sw_put,
11693 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11698 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11699 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11700 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11701 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11702 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11706 /* bind volumes of both NID 0x0c and 0x0d */
11707 static struct hda_bind_ctls alc269_epc_bind_vol = {
11708 .ops = &snd_hda_bind_vol,
11710 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11711 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11716 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11717 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11718 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11719 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11723 /* capture mixer elements */
11724 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11725 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11726 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11729 /* The multiple "Capture Source" controls confuse alsamixer
11730 * So call somewhat different..
11732 /* .name = "Capture Source", */
11733 .name = "Input Source",
11735 .info = alc_mux_enum_info,
11736 .get = alc_mux_enum_get,
11737 .put = alc_mux_enum_put,
11742 /* capture mixer elements */
11743 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11744 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11745 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11750 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11751 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11752 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11756 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11758 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11759 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11760 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11761 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11762 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11766 /* toggle speaker-output according to the hp-jack state */
11767 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11769 unsigned int present;
11770 unsigned char bits;
11772 present = snd_hda_codec_read(codec, 0x15, 0,
11773 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11774 bits = present ? AMP_IN_MUTE(0) : 0;
11775 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11776 AMP_IN_MUTE(0), bits);
11777 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11778 AMP_IN_MUTE(0), bits);
11780 snd_hda_codec_write(codec, 0x20, 0,
11781 AC_VERB_SET_COEF_INDEX, 0x0c);
11782 snd_hda_codec_write(codec, 0x20, 0,
11783 AC_VERB_SET_PROC_COEF, 0x680);
11785 snd_hda_codec_write(codec, 0x20, 0,
11786 AC_VERB_SET_COEF_INDEX, 0x0c);
11787 snd_hda_codec_write(codec, 0x20, 0,
11788 AC_VERB_SET_PROC_COEF, 0x480);
11791 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11793 unsigned int present;
11795 present = snd_hda_codec_read(codec, 0x18, 0,
11796 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11797 snd_hda_codec_write(codec, 0x23, 0,
11798 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11801 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11804 if ((res >> 26) == ALC880_HP_EVENT)
11805 alc269_quanta_fl1_speaker_automute(codec);
11806 if ((res >> 26) == ALC880_MIC_EVENT)
11807 alc269_quanta_fl1_mic_automute(codec);
11810 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11812 alc269_quanta_fl1_speaker_automute(codec);
11813 alc269_quanta_fl1_mic_automute(codec);
11816 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11817 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11818 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11819 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11820 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11821 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11822 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11823 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11827 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11829 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11830 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11831 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11832 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11833 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11837 /* toggle speaker-output according to the hp-jack state */
11838 static void alc269_speaker_automute(struct hda_codec *codec)
11840 unsigned int present;
11841 unsigned char bits;
11843 present = snd_hda_codec_read(codec, 0x15, 0,
11844 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11845 bits = present ? AMP_IN_MUTE(0) : 0;
11846 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11847 AMP_IN_MUTE(0), bits);
11848 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11849 AMP_IN_MUTE(0), bits);
11852 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11854 unsigned int present;
11856 present = snd_hda_codec_read(codec, 0x18, 0,
11857 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11858 snd_hda_codec_write(codec, 0x23, 0,
11859 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11862 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11864 unsigned int present;
11866 present = snd_hda_codec_read(codec, 0x18, 0,
11867 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11868 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11869 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11870 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11871 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11874 /* unsolicited event for HP jack sensing */
11875 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11878 if ((res >> 26) == ALC880_HP_EVENT)
11879 alc269_speaker_automute(codec);
11881 if ((res >> 26) == ALC880_MIC_EVENT)
11882 alc269_eeepc_dmic_automute(codec);
11885 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11887 alc269_speaker_automute(codec);
11888 alc269_eeepc_dmic_automute(codec);
11891 /* unsolicited event for HP jack sensing */
11892 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11895 if ((res >> 26) == ALC880_HP_EVENT)
11896 alc269_speaker_automute(codec);
11898 if ((res >> 26) == ALC880_MIC_EVENT)
11899 alc269_eeepc_amic_automute(codec);
11902 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11904 alc269_speaker_automute(codec);
11905 alc269_eeepc_amic_automute(codec);
11909 * generic initialization of ADC, input mixers and output mixers
11911 static struct hda_verb alc269_init_verbs[] = {
11913 * Unmute ADC0 and set the default input to mic-in
11915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11917 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11918 * analog-loopback mixer widget
11919 * Note: PASD motherboards uses the Line In 2 as the input for
11920 * front panel mic (mic 2)
11922 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11930 * Set up output mixers (0x0c - 0x0e)
11932 /* set vol=0 to output mixers */
11933 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11934 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11936 /* set up input amps for analog loopback */
11937 /* Amp Indices: DAC = 0, mixer = 1 */
11938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11939 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11940 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11941 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11942 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11943 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11948 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11949 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11950 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11951 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11955 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11956 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11957 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11959 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11961 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11962 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11964 /* FIXME: use matrix-type input source selection */
11965 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11966 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11967 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11973 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11974 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11978 /* add playback controls from the parsed DAC table */
11979 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11980 const struct auto_pin_cfg *cfg)
11985 spec->multiout.num_dacs = 1; /* only use one dac */
11986 spec->multiout.dac_nids = spec->private_dac_nids;
11987 spec->multiout.dac_nids[0] = 2;
11989 nid = cfg->line_out_pins[0];
11991 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11992 "Front Playback Volume",
11993 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11996 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11997 "Front Playback Switch",
11998 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12003 nid = cfg->speaker_pins[0];
12005 if (!cfg->line_out_pins[0]) {
12006 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12007 "Speaker Playback Volume",
12008 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12014 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12015 "Speaker Playback Switch",
12016 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12021 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12022 "Speaker Playback Switch",
12023 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12029 nid = cfg->hp_pins[0];
12031 /* spec->multiout.hp_nid = 2; */
12032 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12033 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12034 "Headphone Playback Volume",
12035 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12041 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12042 "Headphone Playback Switch",
12043 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12048 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12049 "Headphone Playback Switch",
12050 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12059 #define alc269_auto_create_analog_input_ctls \
12060 alc880_auto_create_analog_input_ctls
12062 #ifdef CONFIG_SND_HDA_POWER_SAVE
12063 #define alc269_loopbacks alc880_loopbacks
12066 /* pcm configuration: identiacal with ALC880 */
12067 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12068 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12069 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12070 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12073 * BIOS auto configuration
12075 static int alc269_parse_auto_config(struct hda_codec *codec)
12077 struct alc_spec *spec = codec->spec;
12079 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12081 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12086 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12089 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12093 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12095 if (spec->autocfg.dig_out_pin)
12096 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12098 if (spec->kctl_alloc)
12099 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12101 /* create a beep mixer control if the pin 0x1d isn't assigned */
12102 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12103 if (spec->autocfg.input_pins[i] == 0x1d)
12105 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12106 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12108 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12109 spec->num_mux_defs = 1;
12110 spec->input_mux = &spec->private_imux;
12111 /* set default input source */
12112 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12113 0, AC_VERB_SET_CONNECT_SEL,
12114 spec->input_mux->items[0].index);
12116 err = alc_auto_add_mic_boost(codec);
12120 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12121 spec->num_mixers++;
12126 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12127 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12128 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12131 /* init callback for auto-configuration model -- overriding the default init */
12132 static void alc269_auto_init(struct hda_codec *codec)
12134 struct alc_spec *spec = codec->spec;
12135 alc269_auto_init_multi_out(codec);
12136 alc269_auto_init_hp_out(codec);
12137 alc269_auto_init_analog_input(codec);
12138 if (spec->unsol_event)
12139 alc_sku_automute(codec);
12143 * configuration and preset
12145 static const char *alc269_models[ALC269_MODEL_LAST] = {
12146 [ALC269_BASIC] = "basic",
12147 [ALC269_QUANTA_FL1] = "Quanta",
12148 [ALC269_ASUS_EEEPC_P901] = "Asus_Epc_Dmic"
12151 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12152 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12153 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12154 ALC269_ASUS_EEEPC_P703),
12155 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12156 ALC269_ASUS_EEEPC_P901),
12157 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12158 ALC269_ASUS_EEEPC_P901),
12162 static struct alc_config_preset alc269_presets[] = {
12164 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12165 .init_verbs = { alc269_init_verbs },
12166 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12167 .dac_nids = alc269_dac_nids,
12169 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12170 .channel_mode = alc269_modes,
12171 .input_mux = &alc269_capture_source,
12173 [ALC269_QUANTA_FL1] = {
12174 .mixers = { alc269_quanta_fl1_mixer },
12175 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12176 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12177 .dac_nids = alc269_dac_nids,
12179 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12180 .channel_mode = alc269_modes,
12181 .input_mux = &alc269_capture_source,
12182 .unsol_event = alc269_quanta_fl1_unsol_event,
12183 .init_hook = alc269_quanta_fl1_init_hook,
12185 [ALC269_ASUS_EEEPC_P703] = {
12186 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12187 .init_verbs = { alc269_init_verbs,
12188 alc269_eeepc_amic_init_verbs },
12189 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12190 .dac_nids = alc269_dac_nids,
12192 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12193 .channel_mode = alc269_modes,
12194 .input_mux = &alc269_eeepc_amic_capture_source,
12195 .unsol_event = alc269_eeepc_amic_unsol_event,
12196 .init_hook = alc269_eeepc_amic_inithook,
12198 [ALC269_ASUS_EEEPC_P901] = {
12199 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12200 .init_verbs = { alc269_init_verbs,
12201 alc269_eeepc_dmic_init_verbs },
12202 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12203 .dac_nids = alc269_dac_nids,
12205 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12206 .channel_mode = alc269_modes,
12207 .input_mux = &alc269_eeepc_dmic_capture_source,
12208 .unsol_event = alc269_eeepc_dmic_unsol_event,
12209 .init_hook = alc269_eeepc_dmic_inithook,
12213 static int patch_alc269(struct hda_codec *codec)
12215 struct alc_spec *spec;
12219 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12223 codec->spec = spec;
12225 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12227 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12231 if (board_config < 0) {
12232 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12233 "trying auto-probe from BIOS...\n");
12234 board_config = ALC269_AUTO;
12237 if (board_config == ALC269_AUTO) {
12238 /* automatic parse from the BIOS config */
12239 err = alc269_parse_auto_config(codec);
12245 "hda_codec: Cannot set up configuration "
12246 "from BIOS. Using base mode...\n");
12247 board_config = ALC269_BASIC;
12251 if (board_config != ALC269_AUTO)
12252 setup_preset(spec, &alc269_presets[board_config]);
12254 spec->stream_name_analog = "ALC269 Analog";
12255 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12256 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12258 spec->stream_name_digital = "ALC269 Digital";
12259 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12260 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12262 spec->adc_nids = alc269_adc_nids;
12263 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12264 spec->capsrc_nids = alc269_capsrc_nids;
12266 codec->patch_ops = alc_patch_ops;
12267 if (board_config == ALC269_AUTO)
12268 spec->init_hook = alc269_auto_init;
12269 #ifdef CONFIG_SND_HDA_POWER_SAVE
12270 if (!spec->loopback.amplist)
12271 spec->loopback.amplist = alc269_loopbacks;
12278 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12282 * set the path ways for 2 channel output
12283 * need to set the codec line out and mic 1 pin widgets to inputs
12285 static struct hda_verb alc861_threestack_ch2_init[] = {
12286 /* set pin widget 1Ah (line in) for input */
12287 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12288 /* set pin widget 18h (mic1/2) for input, for mic also enable
12291 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12293 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12295 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12296 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12302 * need to set the codec line out and mic 1 pin widgets to outputs
12304 static struct hda_verb alc861_threestack_ch6_init[] = {
12305 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12306 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12307 /* set pin widget 18h (mic1) for output (CLFE)*/
12308 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12310 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12311 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12313 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12315 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12316 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12321 static struct hda_channel_mode alc861_threestack_modes[2] = {
12322 { 2, alc861_threestack_ch2_init },
12323 { 6, alc861_threestack_ch6_init },
12325 /* Set mic1 as input and unmute the mixer */
12326 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12327 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12328 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12331 /* Set mic1 as output and mute mixer */
12332 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12333 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12334 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12338 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12339 { 2, alc861_uniwill_m31_ch2_init },
12340 { 4, alc861_uniwill_m31_ch4_init },
12343 /* Set mic1 and line-in as input and unmute the mixer */
12344 static struct hda_verb alc861_asus_ch2_init[] = {
12345 /* set pin widget 1Ah (line in) for input */
12346 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12347 /* set pin widget 18h (mic1/2) for input, for mic also enable
12350 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12352 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12354 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12355 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12359 /* Set mic1 nad line-in as output and mute mixer */
12360 static struct hda_verb alc861_asus_ch6_init[] = {
12361 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12362 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12363 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12364 /* set pin widget 18h (mic1) for output (CLFE)*/
12365 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12366 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12367 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12368 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12370 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12373 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12378 static struct hda_channel_mode alc861_asus_modes[2] = {
12379 { 2, alc861_asus_ch2_init },
12380 { 6, alc861_asus_ch6_init },
12385 static struct snd_kcontrol_new alc861_base_mixer[] = {
12386 /* output mixer control */
12387 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12388 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12389 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12390 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12391 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12393 /*Input mixer control */
12394 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12395 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12396 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12397 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12398 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12399 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12400 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12401 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12402 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12405 /* Capture mixer control */
12406 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12407 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12409 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12410 .name = "Capture Source",
12412 .info = alc_mux_enum_info,
12413 .get = alc_mux_enum_get,
12414 .put = alc_mux_enum_put,
12419 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12420 /* output mixer control */
12421 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12422 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12423 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12424 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12425 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12427 /* Input mixer control */
12428 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12429 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12430 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12431 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12433 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12435 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12439 /* Capture mixer control */
12440 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12441 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12444 .name = "Capture Source",
12446 .info = alc_mux_enum_info,
12447 .get = alc_mux_enum_get,
12448 .put = alc_mux_enum_put,
12451 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12452 .name = "Channel Mode",
12453 .info = alc_ch_mode_info,
12454 .get = alc_ch_mode_get,
12455 .put = alc_ch_mode_put,
12456 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12461 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12462 /* output mixer control */
12463 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12465 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12467 /*Capture mixer control */
12468 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12469 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12472 .name = "Capture Source",
12474 .info = alc_mux_enum_info,
12475 .get = alc_mux_enum_get,
12476 .put = alc_mux_enum_put,
12482 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12483 /* output mixer control */
12484 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12485 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12486 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12487 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12488 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12490 /* Input mixer control */
12491 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12492 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12493 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12494 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12495 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12496 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12498 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12499 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12502 /* Capture mixer control */
12503 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12504 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12507 .name = "Capture Source",
12509 .info = alc_mux_enum_info,
12510 .get = alc_mux_enum_get,
12511 .put = alc_mux_enum_put,
12514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12515 .name = "Channel Mode",
12516 .info = alc_ch_mode_info,
12517 .get = alc_ch_mode_get,
12518 .put = alc_ch_mode_put,
12519 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12524 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12525 /* output mixer control */
12526 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12527 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12528 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12529 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12530 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12532 /* Input mixer control */
12533 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12534 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12535 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12536 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12537 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12538 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12540 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12541 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12544 /* Capture mixer control */
12545 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12546 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12549 .name = "Capture Source",
12551 .info = alc_mux_enum_info,
12552 .get = alc_mux_enum_get,
12553 .put = alc_mux_enum_put,
12556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12557 .name = "Channel Mode",
12558 .info = alc_ch_mode_info,
12559 .get = alc_ch_mode_get,
12560 .put = alc_ch_mode_put,
12561 .private_value = ARRAY_SIZE(alc861_asus_modes),
12566 /* additional mixer */
12567 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12568 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12569 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12570 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12571 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12576 * generic initialization of ADC, input mixers and output mixers
12578 static struct hda_verb alc861_base_init_verbs[] = {
12580 * Unmute ADC0 and set the default input to mic-in
12582 /* port-A for surround (rear panel) */
12583 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12584 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12585 /* port-B for mic-in (rear panel) with vref */
12586 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12587 /* port-C for line-in (rear panel) */
12588 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12589 /* port-D for Front */
12590 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12591 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12592 /* port-E for HP out (front panel) */
12593 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12594 /* route front PCM to HP */
12595 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12596 /* port-F for mic-in (front panel) with vref */
12597 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12598 /* port-G for CLFE (rear panel) */
12599 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12600 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12601 /* port-H for side (rear panel) */
12602 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12603 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12605 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12606 /* route front mic to ADC1*/
12607 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12608 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12610 /* Unmute DAC0~3 & spdif out*/
12611 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12612 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12613 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12614 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12617 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12618 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12619 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12620 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12621 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12623 /* Unmute Stereo Mixer 15 */
12624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12630 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12631 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12632 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12634 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12636 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12637 /* hp used DAC 3 (Front) */
12638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12644 static struct hda_verb alc861_threestack_init_verbs[] = {
12646 * Unmute ADC0 and set the default input to mic-in
12648 /* port-A for surround (rear panel) */
12649 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12650 /* port-B for mic-in (rear panel) with vref */
12651 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12652 /* port-C for line-in (rear panel) */
12653 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12654 /* port-D for Front */
12655 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12656 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12657 /* port-E for HP out (front panel) */
12658 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12659 /* route front PCM to HP */
12660 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12661 /* port-F for mic-in (front panel) with vref */
12662 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12663 /* port-G for CLFE (rear panel) */
12664 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12665 /* port-H for side (rear panel) */
12666 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12668 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12669 /* route front mic to ADC1*/
12670 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12671 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12672 /* Unmute DAC0~3 & spdif out*/
12673 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12674 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12675 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12676 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12679 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12680 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12681 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12682 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12683 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12685 /* Unmute Stereo Mixer 15 */
12686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12691 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12692 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12694 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12695 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12696 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12697 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12699 /* hp used DAC 3 (Front) */
12700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12705 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12707 * Unmute ADC0 and set the default input to mic-in
12709 /* port-A for surround (rear panel) */
12710 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12711 /* port-B for mic-in (rear panel) with vref */
12712 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12713 /* port-C for line-in (rear panel) */
12714 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12715 /* port-D for Front */
12716 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12717 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12718 /* port-E for HP out (front panel) */
12719 /* this has to be set to VREF80 */
12720 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12721 /* route front PCM to HP */
12722 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12723 /* port-F for mic-in (front panel) with vref */
12724 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12725 /* port-G for CLFE (rear panel) */
12726 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12727 /* port-H for side (rear panel) */
12728 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12730 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12731 /* route front mic to ADC1*/
12732 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12733 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12734 /* Unmute DAC0~3 & spdif out*/
12735 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12736 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12737 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12738 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12741 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12742 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12743 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12744 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12745 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12747 /* Unmute Stereo Mixer 15 */
12748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12754 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12756 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12760 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12761 /* hp used DAC 3 (Front) */
12762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12763 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12767 static struct hda_verb alc861_asus_init_verbs[] = {
12769 * Unmute ADC0 and set the default input to mic-in
12771 /* port-A for surround (rear panel)
12772 * according to codec#0 this is the HP jack
12774 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12775 /* route front PCM to HP */
12776 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12777 /* port-B for mic-in (rear panel) with vref */
12778 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12779 /* port-C for line-in (rear panel) */
12780 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12781 /* port-D for Front */
12782 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12783 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12784 /* port-E for HP out (front panel) */
12785 /* this has to be set to VREF80 */
12786 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12787 /* route front PCM to HP */
12788 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12789 /* port-F for mic-in (front panel) with vref */
12790 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12791 /* port-G for CLFE (rear panel) */
12792 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12793 /* port-H for side (rear panel) */
12794 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12796 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12797 /* route front mic to ADC1*/
12798 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12799 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12800 /* Unmute DAC0~3 & spdif out*/
12801 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12802 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12803 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12804 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12805 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12806 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12807 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12808 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12809 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12810 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12812 /* Unmute Stereo Mixer 15 */
12813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12820 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12821 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12823 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12825 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12826 /* hp used DAC 3 (Front) */
12827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12832 /* additional init verbs for ASUS laptops */
12833 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12834 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12835 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12840 * generic initialization of ADC, input mixers and output mixers
12842 static struct hda_verb alc861_auto_init_verbs[] = {
12844 * Unmute ADC0 and set the default input to mic-in
12846 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12847 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12849 /* Unmute DAC0~3 & spdif out*/
12850 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12851 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12852 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12853 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12854 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12856 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12857 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12858 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12859 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12860 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12862 /* Unmute Stereo Mixer 15 */
12863 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12868 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12869 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12870 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12871 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12874 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12875 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12880 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12882 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12883 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12884 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12886 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12891 static struct hda_verb alc861_toshiba_init_verbs[] = {
12892 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12897 /* toggle speaker-output according to the hp-jack state */
12898 static void alc861_toshiba_automute(struct hda_codec *codec)
12900 unsigned int present;
12902 present = snd_hda_codec_read(codec, 0x0f, 0,
12903 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12904 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12905 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12906 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12907 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12910 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12913 if ((res >> 26) == ALC880_HP_EVENT)
12914 alc861_toshiba_automute(codec);
12917 /* pcm configuration: identiacal with ALC880 */
12918 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
12919 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
12920 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
12921 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
12924 #define ALC861_DIGOUT_NID 0x07
12926 static struct hda_channel_mode alc861_8ch_modes[1] = {
12930 static hda_nid_t alc861_dac_nids[4] = {
12931 /* front, surround, clfe, side */
12932 0x03, 0x06, 0x05, 0x04
12935 static hda_nid_t alc660_dac_nids[3] = {
12936 /* front, clfe, surround */
12940 static hda_nid_t alc861_adc_nids[1] = {
12945 static struct hda_input_mux alc861_capture_source = {
12949 { "Front Mic", 0x3 },
12956 /* fill in the dac_nids table from the parsed pin configuration */
12957 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12958 const struct auto_pin_cfg *cfg)
12963 spec->multiout.dac_nids = spec->private_dac_nids;
12964 for (i = 0; i < cfg->line_outs; i++) {
12965 nid = cfg->line_out_pins[i];
12967 if (i >= ARRAY_SIZE(alc861_dac_nids))
12969 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12972 spec->multiout.num_dacs = cfg->line_outs;
12976 /* add playback controls from the parsed DAC table */
12977 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12978 const struct auto_pin_cfg *cfg)
12981 static const char *chname[4] = {
12982 "Front", "Surround", NULL /*CLFE*/, "Side"
12987 for (i = 0; i < cfg->line_outs; i++) {
12988 nid = spec->multiout.dac_nids[i];
12993 err = add_control(spec, ALC_CTL_BIND_MUTE,
12994 "Center Playback Switch",
12995 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12999 err = add_control(spec, ALC_CTL_BIND_MUTE,
13000 "LFE Playback Switch",
13001 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13006 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13008 if (nid == alc861_dac_nids[idx])
13010 sprintf(name, "%s Playback Switch", chname[idx]);
13011 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13012 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13021 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13029 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13031 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13032 "Headphone Playback Switch",
13033 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13036 spec->multiout.hp_nid = nid;
13041 /* create playback/capture controls for input pins */
13042 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13043 const struct auto_pin_cfg *cfg)
13045 struct hda_input_mux *imux = &spec->private_imux;
13046 int i, err, idx, idx1;
13048 for (i = 0; i < AUTO_PIN_LAST; i++) {
13049 switch (cfg->input_pins[i]) {
13052 idx = 2; /* Line In */
13056 idx = 2; /* Line In */
13060 idx = 1; /* Mic In */
13064 idx = 1; /* Mic In */
13074 err = new_analog_input(spec, cfg->input_pins[i],
13075 auto_pin_cfg_labels[i], idx, 0x15);
13079 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13080 imux->items[imux->num_items].index = idx1;
13086 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13087 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13088 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13091 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13092 /* The multiple "Capture Source" controls confuse alsamixer
13093 * So call somewhat different..
13095 /* .name = "Capture Source", */
13096 .name = "Input Source",
13098 .info = alc_mux_enum_info,
13099 .get = alc_mux_enum_get,
13100 .put = alc_mux_enum_put,
13105 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13107 int pin_type, int dac_idx)
13109 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13111 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13115 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13117 struct alc_spec *spec = codec->spec;
13120 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13121 for (i = 0; i < spec->autocfg.line_outs; i++) {
13122 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13123 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13125 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13126 spec->multiout.dac_nids[i]);
13130 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13132 struct alc_spec *spec = codec->spec;
13135 pin = spec->autocfg.hp_pins[0];
13136 if (pin) /* connect to front */
13137 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13138 spec->multiout.dac_nids[0]);
13139 pin = spec->autocfg.speaker_pins[0];
13141 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13144 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13146 struct alc_spec *spec = codec->spec;
13149 for (i = 0; i < AUTO_PIN_LAST; i++) {
13150 hda_nid_t nid = spec->autocfg.input_pins[i];
13151 if (nid >= 0x0c && nid <= 0x11) {
13152 snd_hda_codec_write(codec, nid, 0,
13153 AC_VERB_SET_PIN_WIDGET_CONTROL,
13154 i <= AUTO_PIN_FRONT_MIC ?
13155 PIN_VREF80 : PIN_IN);
13160 /* parse the BIOS configuration and set up the alc_spec */
13161 /* return 1 if successful, 0 if the proper config is not found,
13162 * or a negative error code
13164 static int alc861_parse_auto_config(struct hda_codec *codec)
13166 struct alc_spec *spec = codec->spec;
13168 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13170 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13174 if (!spec->autocfg.line_outs)
13175 return 0; /* can't find valid BIOS pin config */
13177 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13180 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13183 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13186 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13190 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13192 if (spec->autocfg.dig_out_pin)
13193 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13195 if (spec->kctl_alloc)
13196 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13198 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13200 spec->num_mux_defs = 1;
13201 spec->input_mux = &spec->private_imux;
13203 spec->adc_nids = alc861_adc_nids;
13204 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13205 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13206 spec->num_mixers++;
13211 /* additional initialization for auto-configuration model */
13212 static void alc861_auto_init(struct hda_codec *codec)
13214 struct alc_spec *spec = codec->spec;
13215 alc861_auto_init_multi_out(codec);
13216 alc861_auto_init_hp_out(codec);
13217 alc861_auto_init_analog_input(codec);
13218 if (spec->unsol_event)
13219 alc_sku_automute(codec);
13222 #ifdef CONFIG_SND_HDA_POWER_SAVE
13223 static struct hda_amp_list alc861_loopbacks[] = {
13224 { 0x15, HDA_INPUT, 0 },
13225 { 0x15, HDA_INPUT, 1 },
13226 { 0x15, HDA_INPUT, 2 },
13227 { 0x15, HDA_INPUT, 3 },
13234 * configuration and preset
13236 static const char *alc861_models[ALC861_MODEL_LAST] = {
13237 [ALC861_3ST] = "3stack",
13238 [ALC660_3ST] = "3stack-660",
13239 [ALC861_3ST_DIG] = "3stack-dig",
13240 [ALC861_6ST_DIG] = "6stack-dig",
13241 [ALC861_UNIWILL_M31] = "uniwill-m31",
13242 [ALC861_TOSHIBA] = "toshiba",
13243 [ALC861_ASUS] = "asus",
13244 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13245 [ALC861_AUTO] = "auto",
13248 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13249 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13250 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13251 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13252 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13253 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13254 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13255 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13256 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13257 * Any other models that need this preset?
13259 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13260 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13261 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13262 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13263 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13264 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13265 /* FIXME: the below seems conflict */
13266 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13267 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13268 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13272 static struct alc_config_preset alc861_presets[] = {
13274 .mixers = { alc861_3ST_mixer },
13275 .init_verbs = { alc861_threestack_init_verbs },
13276 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13277 .dac_nids = alc861_dac_nids,
13278 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13279 .channel_mode = alc861_threestack_modes,
13281 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13282 .adc_nids = alc861_adc_nids,
13283 .input_mux = &alc861_capture_source,
13285 [ALC861_3ST_DIG] = {
13286 .mixers = { alc861_base_mixer },
13287 .init_verbs = { alc861_threestack_init_verbs },
13288 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13289 .dac_nids = alc861_dac_nids,
13290 .dig_out_nid = ALC861_DIGOUT_NID,
13291 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13292 .channel_mode = alc861_threestack_modes,
13294 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13295 .adc_nids = alc861_adc_nids,
13296 .input_mux = &alc861_capture_source,
13298 [ALC861_6ST_DIG] = {
13299 .mixers = { alc861_base_mixer },
13300 .init_verbs = { alc861_base_init_verbs },
13301 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13302 .dac_nids = alc861_dac_nids,
13303 .dig_out_nid = ALC861_DIGOUT_NID,
13304 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13305 .channel_mode = alc861_8ch_modes,
13306 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13307 .adc_nids = alc861_adc_nids,
13308 .input_mux = &alc861_capture_source,
13311 .mixers = { alc861_3ST_mixer },
13312 .init_verbs = { alc861_threestack_init_verbs },
13313 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13314 .dac_nids = alc660_dac_nids,
13315 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13316 .channel_mode = alc861_threestack_modes,
13318 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13319 .adc_nids = alc861_adc_nids,
13320 .input_mux = &alc861_capture_source,
13322 [ALC861_UNIWILL_M31] = {
13323 .mixers = { alc861_uniwill_m31_mixer },
13324 .init_verbs = { alc861_uniwill_m31_init_verbs },
13325 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13326 .dac_nids = alc861_dac_nids,
13327 .dig_out_nid = ALC861_DIGOUT_NID,
13328 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13329 .channel_mode = alc861_uniwill_m31_modes,
13331 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13332 .adc_nids = alc861_adc_nids,
13333 .input_mux = &alc861_capture_source,
13335 [ALC861_TOSHIBA] = {
13336 .mixers = { alc861_toshiba_mixer },
13337 .init_verbs = { alc861_base_init_verbs,
13338 alc861_toshiba_init_verbs },
13339 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13340 .dac_nids = alc861_dac_nids,
13341 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13342 .channel_mode = alc883_3ST_2ch_modes,
13343 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13344 .adc_nids = alc861_adc_nids,
13345 .input_mux = &alc861_capture_source,
13346 .unsol_event = alc861_toshiba_unsol_event,
13347 .init_hook = alc861_toshiba_automute,
13350 .mixers = { alc861_asus_mixer },
13351 .init_verbs = { alc861_asus_init_verbs },
13352 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13353 .dac_nids = alc861_dac_nids,
13354 .dig_out_nid = ALC861_DIGOUT_NID,
13355 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13356 .channel_mode = alc861_asus_modes,
13359 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13360 .adc_nids = alc861_adc_nids,
13361 .input_mux = &alc861_capture_source,
13363 [ALC861_ASUS_LAPTOP] = {
13364 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13365 .init_verbs = { alc861_asus_init_verbs,
13366 alc861_asus_laptop_init_verbs },
13367 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13368 .dac_nids = alc861_dac_nids,
13369 .dig_out_nid = ALC861_DIGOUT_NID,
13370 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13371 .channel_mode = alc883_3ST_2ch_modes,
13373 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13374 .adc_nids = alc861_adc_nids,
13375 .input_mux = &alc861_capture_source,
13380 static int patch_alc861(struct hda_codec *codec)
13382 struct alc_spec *spec;
13386 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13390 codec->spec = spec;
13392 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13396 if (board_config < 0) {
13397 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13398 "trying auto-probe from BIOS...\n");
13399 board_config = ALC861_AUTO;
13402 if (board_config == ALC861_AUTO) {
13403 /* automatic parse from the BIOS config */
13404 err = alc861_parse_auto_config(codec);
13410 "hda_codec: Cannot set up configuration "
13411 "from BIOS. Using base mode...\n");
13412 board_config = ALC861_3ST_DIG;
13416 if (board_config != ALC861_AUTO)
13417 setup_preset(spec, &alc861_presets[board_config]);
13419 spec->stream_name_analog = "ALC861 Analog";
13420 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13421 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13423 spec->stream_name_digital = "ALC861 Digital";
13424 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13425 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13427 spec->vmaster_nid = 0x03;
13429 codec->patch_ops = alc_patch_ops;
13430 if (board_config == ALC861_AUTO)
13431 spec->init_hook = alc861_auto_init;
13432 #ifdef CONFIG_SND_HDA_POWER_SAVE
13433 if (!spec->loopback.amplist)
13434 spec->loopback.amplist = alc861_loopbacks;
13441 * ALC861-VD support
13445 * In addition, an independent DAC
13447 #define ALC861VD_DIGOUT_NID 0x06
13449 static hda_nid_t alc861vd_dac_nids[4] = {
13450 /* front, surr, clfe, side surr */
13451 0x02, 0x03, 0x04, 0x05
13454 /* dac_nids for ALC660vd are in a different order - according to
13455 * Realtek's driver.
13456 * This should probably tesult in a different mixer for 6stack models
13457 * of ALC660vd codecs, but for now there is only 3stack mixer
13458 * - and it is the same as in 861vd.
13459 * adc_nids in ALC660vd are (is) the same as in 861vd
13461 static hda_nid_t alc660vd_dac_nids[3] = {
13462 /* front, rear, clfe, rear_surr */
13466 static hda_nid_t alc861vd_adc_nids[1] = {
13471 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13474 /* FIXME: should be a matrix-type input source selection */
13475 static struct hda_input_mux alc861vd_capture_source = {
13479 { "Front Mic", 0x1 },
13485 static struct hda_input_mux alc861vd_dallas_capture_source = {
13488 { "Ext Mic", 0x0 },
13489 { "Int Mic", 0x1 },
13493 static struct hda_input_mux alc861vd_hp_capture_source = {
13496 { "Front Mic", 0x0 },
13497 { "ATAPI Mic", 0x1 },
13501 #define alc861vd_mux_enum_info alc_mux_enum_info
13502 #define alc861vd_mux_enum_get alc_mux_enum_get
13503 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13504 #define alc861vd_mux_enum_put alc882_mux_enum_put
13509 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13516 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13517 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13518 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13519 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13520 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13527 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13528 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13529 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13530 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13531 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13535 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13536 { 6, alc861vd_6stack_ch6_init },
13537 { 8, alc861vd_6stack_ch8_init },
13540 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13543 .name = "Channel Mode",
13544 .info = alc_ch_mode_info,
13545 .get = alc_ch_mode_get,
13546 .put = alc_ch_mode_put,
13551 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13552 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13553 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13557 /* The multiple "Capture Source" controls confuse alsamixer
13558 * So call somewhat different..
13560 /* .name = "Capture Source", */
13561 .name = "Input Source",
13563 .info = alc861vd_mux_enum_info,
13564 .get = alc861vd_mux_enum_get,
13565 .put = alc861vd_mux_enum_put,
13570 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13571 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13573 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13574 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13575 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13577 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13578 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13580 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13582 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13584 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13585 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13587 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13588 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13593 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13594 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13596 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13597 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13598 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13603 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13604 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13606 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13607 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13612 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13613 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13614 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13618 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13619 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13620 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13622 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13623 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13624 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13626 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13627 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13629 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13630 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13632 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13633 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13638 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13639 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13640 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13641 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13643 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13645 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13647 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13649 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13653 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13654 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13659 /* Pin assignment: Speaker=0x14, HP = 0x15,
13660 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13662 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13663 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13664 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13665 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13666 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13667 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13668 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13669 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13670 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13671 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13672 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13673 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13674 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13678 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13679 * Front Mic=0x18, ATAPI Mic = 0x19,
13681 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13682 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13685 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13686 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13687 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13688 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13689 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13695 * generic initialization of ADC, input mixers and output mixers
13697 static struct hda_verb alc861vd_volume_init_verbs[] = {
13699 * Unmute ADC0 and set the default input to mic-in
13701 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13704 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13705 * the analog-loopback mixer widget
13707 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13714 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13721 * Set up output mixers (0x02 - 0x05)
13723 /* set vol=0 to output mixers */
13724 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13725 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13726 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13727 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13729 /* set up input amps for analog loopback */
13730 /* Amp Indices: DAC = 0, mixer = 1 */
13731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13733 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13734 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13736 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13737 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13738 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13744 * 3-stack pin configuration:
13745 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13747 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13749 * Set pin mode and muting
13751 /* set front pin widgets 0x14 for output */
13752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13754 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13756 /* Mic (rear) pin: input vref at 80% */
13757 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13759 /* Front Mic pin: input vref at 80% */
13760 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13761 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13762 /* Line In pin: input */
13763 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13764 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13765 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13766 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13767 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13768 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13769 /* CD pin widget for input */
13770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13776 * 6-stack pin configuration:
13778 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13780 * Set pin mode and muting
13782 /* set front pin widgets 0x14 for output */
13783 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13784 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13785 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13787 /* Rear Pin: output 1 (0x0d) */
13788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13789 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13790 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13791 /* CLFE Pin: output 2 (0x0e) */
13792 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13794 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13795 /* Side Pin: output 3 (0x0f) */
13796 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13798 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13800 /* Mic (rear) pin: input vref at 80% */
13801 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13802 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13803 /* Front Mic pin: input vref at 80% */
13804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13806 /* Line In pin: input */
13807 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13809 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13811 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13812 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13813 /* CD pin widget for input */
13814 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13819 static struct hda_verb alc861vd_eapd_verbs[] = {
13820 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13824 static struct hda_verb alc660vd_eapd_verbs[] = {
13825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13830 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13834 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13835 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13839 /* toggle speaker-output according to the hp-jack state */
13840 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13842 unsigned int present;
13843 unsigned char bits;
13845 present = snd_hda_codec_read(codec, 0x1b, 0,
13846 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13847 bits = present ? HDA_AMP_MUTE : 0;
13848 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13849 HDA_AMP_MUTE, bits);
13852 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13854 unsigned int present;
13855 unsigned char bits;
13857 present = snd_hda_codec_read(codec, 0x18, 0,
13858 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13859 bits = present ? HDA_AMP_MUTE : 0;
13860 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13861 HDA_AMP_MUTE, bits);
13864 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13866 alc861vd_lenovo_hp_automute(codec);
13867 alc861vd_lenovo_mic_automute(codec);
13870 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13873 switch (res >> 26) {
13874 case ALC880_HP_EVENT:
13875 alc861vd_lenovo_hp_automute(codec);
13877 case ALC880_MIC_EVENT:
13878 alc861vd_lenovo_mic_automute(codec);
13883 static struct hda_verb alc861vd_dallas_verbs[] = {
13884 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13885 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13886 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13887 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13891 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13892 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13893 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13894 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13895 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13896 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13900 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13901 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13902 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13903 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13904 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13905 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13909 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13910 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13911 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13912 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13913 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13914 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13918 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13919 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13921 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13922 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13923 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13928 /* toggle speaker-output according to the hp-jack state */
13929 static void alc861vd_dallas_automute(struct hda_codec *codec)
13931 unsigned int present;
13933 present = snd_hda_codec_read(codec, 0x15, 0,
13934 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13935 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13936 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13939 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13941 if ((res >> 26) == ALC880_HP_EVENT)
13942 alc861vd_dallas_automute(codec);
13945 #ifdef CONFIG_SND_HDA_POWER_SAVE
13946 #define alc861vd_loopbacks alc880_loopbacks
13949 /* pcm configuration: identiacal with ALC880 */
13950 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
13951 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
13952 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
13953 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
13956 * configuration and preset
13958 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13959 [ALC660VD_3ST] = "3stack-660",
13960 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13961 [ALC861VD_3ST] = "3stack",
13962 [ALC861VD_3ST_DIG] = "3stack-digout",
13963 [ALC861VD_6ST_DIG] = "6stack-digout",
13964 [ALC861VD_LENOVO] = "lenovo",
13965 [ALC861VD_DALLAS] = "dallas",
13966 [ALC861VD_HP] = "hp",
13967 [ALC861VD_AUTO] = "auto",
13970 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13971 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13972 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13973 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13974 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13975 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13976 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13977 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13978 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13979 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13980 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13981 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13982 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13983 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13984 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13985 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13986 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13987 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13991 static struct alc_config_preset alc861vd_presets[] = {
13993 .mixers = { alc861vd_3st_mixer },
13994 .init_verbs = { alc861vd_volume_init_verbs,
13995 alc861vd_3stack_init_verbs },
13996 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13997 .dac_nids = alc660vd_dac_nids,
13998 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13999 .channel_mode = alc861vd_3stack_2ch_modes,
14000 .input_mux = &alc861vd_capture_source,
14002 [ALC660VD_3ST_DIG] = {
14003 .mixers = { alc861vd_3st_mixer },
14004 .init_verbs = { alc861vd_volume_init_verbs,
14005 alc861vd_3stack_init_verbs },
14006 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14007 .dac_nids = alc660vd_dac_nids,
14008 .dig_out_nid = ALC861VD_DIGOUT_NID,
14009 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14010 .channel_mode = alc861vd_3stack_2ch_modes,
14011 .input_mux = &alc861vd_capture_source,
14014 .mixers = { alc861vd_3st_mixer },
14015 .init_verbs = { alc861vd_volume_init_verbs,
14016 alc861vd_3stack_init_verbs },
14017 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14018 .dac_nids = alc861vd_dac_nids,
14019 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14020 .channel_mode = alc861vd_3stack_2ch_modes,
14021 .input_mux = &alc861vd_capture_source,
14023 [ALC861VD_3ST_DIG] = {
14024 .mixers = { alc861vd_3st_mixer },
14025 .init_verbs = { alc861vd_volume_init_verbs,
14026 alc861vd_3stack_init_verbs },
14027 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14028 .dac_nids = alc861vd_dac_nids,
14029 .dig_out_nid = ALC861VD_DIGOUT_NID,
14030 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14031 .channel_mode = alc861vd_3stack_2ch_modes,
14032 .input_mux = &alc861vd_capture_source,
14034 [ALC861VD_6ST_DIG] = {
14035 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14036 .init_verbs = { alc861vd_volume_init_verbs,
14037 alc861vd_6stack_init_verbs },
14038 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14039 .dac_nids = alc861vd_dac_nids,
14040 .dig_out_nid = ALC861VD_DIGOUT_NID,
14041 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14042 .channel_mode = alc861vd_6stack_modes,
14043 .input_mux = &alc861vd_capture_source,
14045 [ALC861VD_LENOVO] = {
14046 .mixers = { alc861vd_lenovo_mixer },
14047 .init_verbs = { alc861vd_volume_init_verbs,
14048 alc861vd_3stack_init_verbs,
14049 alc861vd_eapd_verbs,
14050 alc861vd_lenovo_unsol_verbs },
14051 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14052 .dac_nids = alc660vd_dac_nids,
14053 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14054 .channel_mode = alc861vd_3stack_2ch_modes,
14055 .input_mux = &alc861vd_capture_source,
14056 .unsol_event = alc861vd_lenovo_unsol_event,
14057 .init_hook = alc861vd_lenovo_automute,
14059 [ALC861VD_DALLAS] = {
14060 .mixers = { alc861vd_dallas_mixer },
14061 .init_verbs = { alc861vd_dallas_verbs },
14062 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14063 .dac_nids = alc861vd_dac_nids,
14064 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14065 .channel_mode = alc861vd_3stack_2ch_modes,
14066 .input_mux = &alc861vd_dallas_capture_source,
14067 .unsol_event = alc861vd_dallas_unsol_event,
14068 .init_hook = alc861vd_dallas_automute,
14071 .mixers = { alc861vd_hp_mixer },
14072 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14073 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14074 .dac_nids = alc861vd_dac_nids,
14075 .dig_out_nid = ALC861VD_DIGOUT_NID,
14076 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14077 .channel_mode = alc861vd_3stack_2ch_modes,
14078 .input_mux = &alc861vd_hp_capture_source,
14079 .unsol_event = alc861vd_dallas_unsol_event,
14080 .init_hook = alc861vd_dallas_automute,
14085 * BIOS auto configuration
14087 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14088 hda_nid_t nid, int pin_type, int dac_idx)
14090 alc_set_pin_output(codec, nid, pin_type);
14093 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14095 struct alc_spec *spec = codec->spec;
14098 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14099 for (i = 0; i <= HDA_SIDE; i++) {
14100 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14101 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14103 alc861vd_auto_set_output_and_unmute(codec, nid,
14109 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14111 struct alc_spec *spec = codec->spec;
14114 pin = spec->autocfg.hp_pins[0];
14115 if (pin) /* connect to front and use dac 0 */
14116 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14117 pin = spec->autocfg.speaker_pins[0];
14119 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14122 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14123 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14125 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14127 struct alc_spec *spec = codec->spec;
14130 for (i = 0; i < AUTO_PIN_LAST; i++) {
14131 hda_nid_t nid = spec->autocfg.input_pins[i];
14132 if (alc861vd_is_input_pin(nid)) {
14133 snd_hda_codec_write(codec, nid, 0,
14134 AC_VERB_SET_PIN_WIDGET_CONTROL,
14135 i <= AUTO_PIN_FRONT_MIC ?
14136 PIN_VREF80 : PIN_IN);
14137 if (nid != ALC861VD_PIN_CD_NID)
14138 snd_hda_codec_write(codec, nid, 0,
14139 AC_VERB_SET_AMP_GAIN_MUTE,
14145 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14147 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14148 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14150 /* add playback controls from the parsed DAC table */
14151 /* Based on ALC880 version. But ALC861VD has separate,
14152 * different NIDs for mute/unmute switch and volume control */
14153 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14154 const struct auto_pin_cfg *cfg)
14157 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14158 hda_nid_t nid_v, nid_s;
14161 for (i = 0; i < cfg->line_outs; i++) {
14162 if (!spec->multiout.dac_nids[i])
14164 nid_v = alc861vd_idx_to_mixer_vol(
14166 spec->multiout.dac_nids[i]));
14167 nid_s = alc861vd_idx_to_mixer_switch(
14169 spec->multiout.dac_nids[i]));
14173 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14174 "Center Playback Volume",
14175 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14179 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14180 "LFE Playback Volume",
14181 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14185 err = add_control(spec, ALC_CTL_BIND_MUTE,
14186 "Center Playback Switch",
14187 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14191 err = add_control(spec, ALC_CTL_BIND_MUTE,
14192 "LFE Playback Switch",
14193 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14198 sprintf(name, "%s Playback Volume", chname[i]);
14199 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14200 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14204 sprintf(name, "%s Playback Switch", chname[i]);
14205 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14206 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14215 /* add playback controls for speaker and HP outputs */
14216 /* Based on ALC880 version. But ALC861VD has separate,
14217 * different NIDs for mute/unmute switch and volume control */
14218 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14219 hda_nid_t pin, const char *pfx)
14221 hda_nid_t nid_v, nid_s;
14228 if (alc880_is_fixed_pin(pin)) {
14229 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14230 /* specify the DAC as the extra output */
14231 if (!spec->multiout.hp_nid)
14232 spec->multiout.hp_nid = nid_v;
14234 spec->multiout.extra_out_nid[0] = nid_v;
14235 /* control HP volume/switch on the output mixer amp */
14236 nid_v = alc861vd_idx_to_mixer_vol(
14237 alc880_fixed_pin_idx(pin));
14238 nid_s = alc861vd_idx_to_mixer_switch(
14239 alc880_fixed_pin_idx(pin));
14241 sprintf(name, "%s Playback Volume", pfx);
14242 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14243 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14246 sprintf(name, "%s Playback Switch", pfx);
14247 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14248 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14251 } else if (alc880_is_multi_pin(pin)) {
14252 /* set manual connection */
14253 /* we have only a switch on HP-out PIN */
14254 sprintf(name, "%s Playback Switch", pfx);
14255 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14256 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14263 /* parse the BIOS configuration and set up the alc_spec
14264 * return 1 if successful, 0 if the proper config is not found,
14265 * or a negative error code
14266 * Based on ALC880 version - had to change it to override
14267 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14268 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14270 struct alc_spec *spec = codec->spec;
14272 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14274 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14278 if (!spec->autocfg.line_outs)
14279 return 0; /* can't find valid BIOS pin config */
14281 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14284 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14287 err = alc861vd_auto_create_extra_out(spec,
14288 spec->autocfg.speaker_pins[0],
14292 err = alc861vd_auto_create_extra_out(spec,
14293 spec->autocfg.hp_pins[0],
14297 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14301 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14303 if (spec->autocfg.dig_out_pin)
14304 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14306 if (spec->kctl_alloc)
14307 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14309 spec->init_verbs[spec->num_init_verbs++]
14310 = alc861vd_volume_init_verbs;
14312 spec->num_mux_defs = 1;
14313 spec->input_mux = &spec->private_imux;
14315 err = alc_auto_add_mic_boost(codec);
14322 /* additional initialization for auto-configuration model */
14323 static void alc861vd_auto_init(struct hda_codec *codec)
14325 struct alc_spec *spec = codec->spec;
14326 alc861vd_auto_init_multi_out(codec);
14327 alc861vd_auto_init_hp_out(codec);
14328 alc861vd_auto_init_analog_input(codec);
14329 alc861vd_auto_init_input_src(codec);
14330 if (spec->unsol_event)
14331 alc_sku_automute(codec);
14334 static int patch_alc861vd(struct hda_codec *codec)
14336 struct alc_spec *spec;
14337 int err, board_config;
14339 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14343 codec->spec = spec;
14345 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14349 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14350 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14351 "ALC861VD, trying auto-probe from BIOS...\n");
14352 board_config = ALC861VD_AUTO;
14355 if (board_config == ALC861VD_AUTO) {
14356 /* automatic parse from the BIOS config */
14357 err = alc861vd_parse_auto_config(codec);
14363 "hda_codec: Cannot set up configuration "
14364 "from BIOS. Using base mode...\n");
14365 board_config = ALC861VD_3ST;
14369 if (board_config != ALC861VD_AUTO)
14370 setup_preset(spec, &alc861vd_presets[board_config]);
14372 if (codec->vendor_id == 0x10ec0660) {
14373 spec->stream_name_analog = "ALC660-VD Analog";
14374 spec->stream_name_digital = "ALC660-VD Digital";
14375 /* always turn on EAPD */
14376 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14378 spec->stream_name_analog = "ALC861VD Analog";
14379 spec->stream_name_digital = "ALC861VD Digital";
14382 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14383 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14385 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14386 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14388 spec->adc_nids = alc861vd_adc_nids;
14389 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14390 spec->capsrc_nids = alc861vd_capsrc_nids;
14392 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14393 spec->num_mixers++;
14395 spec->vmaster_nid = 0x02;
14397 codec->patch_ops = alc_patch_ops;
14399 if (board_config == ALC861VD_AUTO)
14400 spec->init_hook = alc861vd_auto_init;
14401 #ifdef CONFIG_SND_HDA_POWER_SAVE
14402 if (!spec->loopback.amplist)
14403 spec->loopback.amplist = alc861vd_loopbacks;
14412 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14413 * configuration. Each pin widget can choose any input DACs and a mixer.
14414 * Each ADC is connected from a mixer of all inputs. This makes possible
14415 * 6-channel independent captures.
14417 * In addition, an independent DAC for the multi-playback (not used in this
14420 #define ALC662_DIGOUT_NID 0x06
14421 #define ALC662_DIGIN_NID 0x0a
14423 static hda_nid_t alc662_dac_nids[4] = {
14424 /* front, rear, clfe, rear_surr */
14428 static hda_nid_t alc662_adc_nids[1] = {
14433 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14436 /* FIXME: should be a matrix-type input source selection */
14437 static struct hda_input_mux alc662_capture_source = {
14441 { "Front Mic", 0x1 },
14447 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14455 static struct hda_input_mux alc662_eeepc_capture_source = {
14463 static struct hda_input_mux alc663_capture_source = {
14467 { "Front Mic", 0x1 },
14472 static struct hda_input_mux alc663_m51va_capture_source = {
14475 { "Ext-Mic", 0x0 },
14480 #define alc662_mux_enum_info alc_mux_enum_info
14481 #define alc662_mux_enum_get alc_mux_enum_get
14482 #define alc662_mux_enum_put alc882_mux_enum_put
14487 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14494 static struct hda_verb alc662_3ST_ch2_init[] = {
14495 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14496 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14497 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14498 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14505 static struct hda_verb alc662_3ST_ch6_init[] = {
14506 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14507 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14508 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14509 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14510 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14511 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14515 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14516 { 2, alc662_3ST_ch2_init },
14517 { 6, alc662_3ST_ch6_init },
14523 static struct hda_verb alc662_sixstack_ch6_init[] = {
14524 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14525 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14526 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14533 static struct hda_verb alc662_sixstack_ch8_init[] = {
14534 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14535 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14536 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14540 static struct hda_channel_mode alc662_5stack_modes[2] = {
14541 { 2, alc662_sixstack_ch6_init },
14542 { 6, alc662_sixstack_ch8_init },
14545 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14546 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14549 static struct snd_kcontrol_new alc662_base_mixer[] = {
14550 /* output mixer control */
14551 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14552 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14553 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14554 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14555 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14556 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14557 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14558 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14561 /*Input mixer control */
14562 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14563 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14564 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14565 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14566 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14567 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14568 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14569 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14573 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14574 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14575 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14579 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14580 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14581 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14583 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14584 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14585 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14586 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14590 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14591 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14592 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14593 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14594 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14595 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14596 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14597 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14598 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14599 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14600 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14601 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14602 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14603 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14604 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14605 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14606 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14607 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14608 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14609 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14613 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14614 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14615 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14616 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14617 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14618 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14622 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14626 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14627 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14629 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14630 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14632 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14633 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14634 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14636 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14637 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14638 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14642 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14643 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14644 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14645 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14646 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14647 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14648 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14649 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14650 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14651 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14652 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14660 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14661 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14662 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14663 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14665 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14666 HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT),
14670 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14671 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14672 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14673 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14674 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14679 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14680 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14684 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14685 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14686 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14687 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14691 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14692 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14693 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14694 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14698 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14701 .name = "Channel Mode",
14702 .info = alc_ch_mode_info,
14703 .get = alc_ch_mode_get,
14704 .put = alc_ch_mode_put,
14709 static struct hda_verb alc662_init_verbs[] = {
14710 /* ADC: mute amp left and right */
14711 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14712 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14713 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14724 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14726 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14728 /* Front Pin: output 0 (0x0c) */
14729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14732 /* Rear Pin: output 1 (0x0d) */
14733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14736 /* CLFE Pin: output 2 (0x0e) */
14737 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14740 /* Mic (rear) pin: input vref at 80% */
14741 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14743 /* Front Mic pin: input vref at 80% */
14744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14746 /* Line In pin: input */
14747 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14749 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14750 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14751 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14752 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14753 /* CD pin widget for input */
14754 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14756 /* FIXME: use matrix-type input source selection */
14757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14769 /* always trun on EAPD */
14770 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14771 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14776 static struct hda_verb alc662_sue_init_verbs[] = {
14777 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14778 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14782 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14784 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14788 /* Set Unsolicited Event*/
14789 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14791 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14796 * generic initialization of ADC, input mixers and output mixers
14798 static struct hda_verb alc662_auto_init_verbs[] = {
14800 * Unmute ADC and set the default input to mic-in
14802 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14803 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14805 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14807 * Note: PASD motherboards uses the Line In 2 as the input for front
14808 * panel mic (mic 2)
14810 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14812 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14818 * Set up output mixers (0x0c - 0x0f)
14820 /* set vol=0 to output mixers */
14821 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14822 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14823 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14825 /* set up input amps for analog loopback */
14826 /* Amp Indices: DAC = 0, mixer = 1 */
14827 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14829 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14830 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14831 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14832 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14835 /* FIXME: use matrix-type input source selection */
14836 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14843 /* additional verbs for ALC663 */
14844 static struct hda_verb alc663_auto_init_verbs[] = {
14845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14846 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14850 static struct hda_verb alc663_m51va_init_verbs[] = {
14851 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14852 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14853 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14855 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14857 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14858 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14862 static struct hda_verb alc663_g71v_init_verbs[] = {
14863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14864 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14865 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14867 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14868 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14869 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14871 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14872 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14873 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14877 static struct hda_verb alc663_g50v_init_verbs[] = {
14878 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14879 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14880 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14882 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14883 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14887 /* capture mixer elements */
14888 static struct snd_kcontrol_new alc662_capture_mixer[] = {
14889 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14890 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14893 /* The multiple "Capture Source" controls confuse alsamixer
14894 * So call somewhat different..
14896 /* .name = "Capture Source", */
14897 .name = "Input Source",
14899 .info = alc662_mux_enum_info,
14900 .get = alc662_mux_enum_get,
14901 .put = alc662_mux_enum_put,
14906 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14908 unsigned int present;
14909 unsigned char bits;
14911 present = snd_hda_codec_read(codec, 0x14, 0,
14912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14913 bits = present ? HDA_AMP_MUTE : 0;
14914 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14915 HDA_AMP_MUTE, bits);
14918 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
14920 unsigned int present;
14921 unsigned char bits;
14923 present = snd_hda_codec_read(codec, 0x1b, 0,
14924 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14925 bits = present ? HDA_AMP_MUTE : 0;
14926 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14927 HDA_AMP_MUTE, bits);
14928 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14929 HDA_AMP_MUTE, bits);
14932 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
14935 if ((res >> 26) == ALC880_HP_EVENT)
14936 alc662_lenovo_101e_all_automute(codec);
14937 if ((res >> 26) == ALC880_FRONT_EVENT)
14938 alc662_lenovo_101e_ispeaker_automute(codec);
14941 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
14943 unsigned int present;
14945 present = snd_hda_codec_read(codec, 0x18, 0,
14946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14947 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14948 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14949 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14950 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14951 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14952 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14953 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14954 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14957 /* unsolicited event for HP jack sensing */
14958 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
14961 if ((res >> 26) == ALC880_HP_EVENT)
14962 alc262_hippo1_automute( codec );
14964 if ((res >> 26) == ALC880_MIC_EVENT)
14965 alc662_eeepc_mic_automute(codec);
14968 static void alc662_eeepc_inithook(struct hda_codec *codec)
14970 alc262_hippo1_automute( codec );
14971 alc662_eeepc_mic_automute(codec);
14974 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
14977 unsigned int present;
14979 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
14980 present = snd_hda_codec_read(codec, 0x14, 0,
14981 AC_VERB_GET_PIN_SENSE, 0);
14982 present = (present & 0x80000000) != 0;
14984 /* mute internal speaker */
14985 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14986 HDA_AMP_MUTE, HDA_AMP_MUTE);
14988 /* unmute internal speaker if necessary */
14989 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
14990 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14991 HDA_AMP_MUTE, mute);
14995 /* unsolicited event for HP jack sensing */
14996 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
14999 if ((res >> 26) == ALC880_HP_EVENT)
15000 alc662_eeepc_ep20_automute(codec);
15003 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15005 alc662_eeepc_ep20_automute(codec);
15008 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15010 unsigned int present;
15011 unsigned char bits;
15013 present = snd_hda_codec_read(codec, 0x21, 0,
15014 AC_VERB_GET_PIN_SENSE, 0)
15015 & AC_PINSENSE_PRESENCE;
15016 bits = present ? HDA_AMP_MUTE : 0;
15017 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15018 HDA_AMP_MUTE, bits);
15021 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15023 unsigned int present;
15025 present = snd_hda_codec_read(codec, 0x18, 0,
15026 AC_VERB_GET_PIN_SENSE, 0)
15027 & AC_PINSENSE_PRESENCE;
15028 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15029 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15030 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15031 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15032 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15033 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15034 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15035 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15038 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15041 switch (res >> 26) {
15042 case ALC880_HP_EVENT:
15043 alc663_m51va_speaker_automute(codec);
15045 case ALC880_MIC_EVENT:
15046 alc663_m51va_mic_automute(codec);
15051 static void alc663_m51va_inithook(struct hda_codec *codec)
15053 alc663_m51va_speaker_automute(codec);
15054 alc663_m51va_mic_automute(codec);
15057 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15059 unsigned int present;
15060 unsigned char bits;
15062 present = snd_hda_codec_read(codec, 0x21, 0,
15063 AC_VERB_GET_PIN_SENSE, 0)
15064 & AC_PINSENSE_PRESENCE;
15065 bits = present ? HDA_AMP_MUTE : 0;
15066 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15067 HDA_AMP_MUTE, bits);
15068 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15069 HDA_AMP_MUTE, bits);
15072 static void alc663_g71v_front_automute(struct hda_codec *codec)
15074 unsigned int present;
15075 unsigned char bits;
15077 present = snd_hda_codec_read(codec, 0x15, 0,
15078 AC_VERB_GET_PIN_SENSE, 0)
15079 & AC_PINSENSE_PRESENCE;
15080 bits = present ? HDA_AMP_MUTE : 0;
15081 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15082 HDA_AMP_MUTE, bits);
15085 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15088 switch (res >> 26) {
15089 case ALC880_HP_EVENT:
15090 alc663_g71v_hp_automute(codec);
15092 case ALC880_FRONT_EVENT:
15093 alc663_g71v_front_automute(codec);
15095 case ALC880_MIC_EVENT:
15096 alc662_eeepc_mic_automute(codec);
15101 static void alc663_g71v_inithook(struct hda_codec *codec)
15103 alc663_g71v_front_automute(codec);
15104 alc663_g71v_hp_automute(codec);
15105 alc662_eeepc_mic_automute(codec);
15108 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15111 switch (res >> 26) {
15112 case ALC880_HP_EVENT:
15113 alc663_m51va_speaker_automute(codec);
15115 case ALC880_MIC_EVENT:
15116 alc662_eeepc_mic_automute(codec);
15121 static void alc663_g50v_inithook(struct hda_codec *codec)
15123 alc663_m51va_speaker_automute(codec);
15124 alc662_eeepc_mic_automute(codec);
15127 #ifdef CONFIG_SND_HDA_POWER_SAVE
15128 #define alc662_loopbacks alc880_loopbacks
15132 /* pcm configuration: identiacal with ALC880 */
15133 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15134 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15135 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15136 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15139 * configuration and preset
15141 static const char *alc662_models[ALC662_MODEL_LAST] = {
15142 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15143 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15144 [ALC662_3ST_6ch] = "3stack-6ch",
15145 [ALC662_5ST_DIG] = "6stack-dig",
15146 [ALC662_LENOVO_101E] = "lenovo-101e",
15147 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15148 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15149 [ALC663_ASUS_M51VA] = "m51va",
15150 [ALC663_ASUS_G71V] = "g71v",
15151 [ALC663_ASUS_H13] = "h13",
15152 [ALC663_ASUS_G50V] = "g50v",
15153 [ALC662_AUTO] = "auto",
15156 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15157 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
15158 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15159 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
15160 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15161 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15162 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15163 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15164 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15165 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15166 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15170 static struct alc_config_preset alc662_presets[] = {
15171 [ALC662_3ST_2ch_DIG] = {
15172 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15173 .init_verbs = { alc662_init_verbs },
15174 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15175 .dac_nids = alc662_dac_nids,
15176 .dig_out_nid = ALC662_DIGOUT_NID,
15177 .dig_in_nid = ALC662_DIGIN_NID,
15178 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15179 .channel_mode = alc662_3ST_2ch_modes,
15180 .input_mux = &alc662_capture_source,
15182 [ALC662_3ST_6ch_DIG] = {
15183 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15184 alc662_capture_mixer },
15185 .init_verbs = { alc662_init_verbs },
15186 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15187 .dac_nids = alc662_dac_nids,
15188 .dig_out_nid = ALC662_DIGOUT_NID,
15189 .dig_in_nid = ALC662_DIGIN_NID,
15190 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15191 .channel_mode = alc662_3ST_6ch_modes,
15193 .input_mux = &alc662_capture_source,
15195 [ALC662_3ST_6ch] = {
15196 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15197 alc662_capture_mixer },
15198 .init_verbs = { alc662_init_verbs },
15199 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15200 .dac_nids = alc662_dac_nids,
15201 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15202 .channel_mode = alc662_3ST_6ch_modes,
15204 .input_mux = &alc662_capture_source,
15206 [ALC662_5ST_DIG] = {
15207 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15208 alc662_capture_mixer },
15209 .init_verbs = { alc662_init_verbs },
15210 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15211 .dac_nids = alc662_dac_nids,
15212 .dig_out_nid = ALC662_DIGOUT_NID,
15213 .dig_in_nid = ALC662_DIGIN_NID,
15214 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15215 .channel_mode = alc662_5stack_modes,
15216 .input_mux = &alc662_capture_source,
15218 [ALC662_LENOVO_101E] = {
15219 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15220 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15221 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15222 .dac_nids = alc662_dac_nids,
15223 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15224 .channel_mode = alc662_3ST_2ch_modes,
15225 .input_mux = &alc662_lenovo_101e_capture_source,
15226 .unsol_event = alc662_lenovo_101e_unsol_event,
15227 .init_hook = alc662_lenovo_101e_all_automute,
15229 [ALC662_ASUS_EEEPC_P701] = {
15230 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15231 .init_verbs = { alc662_init_verbs,
15232 alc662_eeepc_sue_init_verbs },
15233 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15234 .dac_nids = alc662_dac_nids,
15235 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15236 .channel_mode = alc662_3ST_2ch_modes,
15237 .input_mux = &alc662_eeepc_capture_source,
15238 .unsol_event = alc662_eeepc_unsol_event,
15239 .init_hook = alc662_eeepc_inithook,
15241 [ALC662_ASUS_EEEPC_EP20] = {
15242 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15243 alc662_chmode_mixer },
15244 .init_verbs = { alc662_init_verbs,
15245 alc662_eeepc_ep20_sue_init_verbs },
15246 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15247 .dac_nids = alc662_dac_nids,
15248 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15249 .channel_mode = alc662_3ST_6ch_modes,
15250 .input_mux = &alc662_lenovo_101e_capture_source,
15251 .unsol_event = alc662_eeepc_ep20_unsol_event,
15252 .init_hook = alc662_eeepc_ep20_inithook,
15254 [ALC663_ASUS_M51VA] = {
15255 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15256 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15257 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15258 .dac_nids = alc662_dac_nids,
15259 .dig_out_nid = ALC662_DIGOUT_NID,
15260 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15261 .channel_mode = alc662_3ST_2ch_modes,
15262 .input_mux = &alc663_m51va_capture_source,
15263 .unsol_event = alc663_m51va_unsol_event,
15264 .init_hook = alc663_m51va_inithook,
15266 [ALC663_ASUS_G71V] = {
15267 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15268 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15269 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15270 .dac_nids = alc662_dac_nids,
15271 .dig_out_nid = ALC662_DIGOUT_NID,
15272 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15273 .channel_mode = alc662_3ST_2ch_modes,
15274 .input_mux = &alc662_eeepc_capture_source,
15275 .unsol_event = alc663_g71v_unsol_event,
15276 .init_hook = alc663_g71v_inithook,
15278 [ALC663_ASUS_H13] = {
15279 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15280 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15281 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15282 .dac_nids = alc662_dac_nids,
15283 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15284 .channel_mode = alc662_3ST_2ch_modes,
15285 .input_mux = &alc663_m51va_capture_source,
15286 .unsol_event = alc663_m51va_unsol_event,
15287 .init_hook = alc663_m51va_inithook,
15289 [ALC663_ASUS_G50V] = {
15290 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15291 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15292 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15293 .dac_nids = alc662_dac_nids,
15294 .dig_out_nid = ALC662_DIGOUT_NID,
15295 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15296 .channel_mode = alc662_3ST_6ch_modes,
15297 .input_mux = &alc663_capture_source,
15298 .unsol_event = alc663_g50v_unsol_event,
15299 .init_hook = alc663_g50v_inithook,
15305 * BIOS auto configuration
15308 /* add playback controls from the parsed DAC table */
15309 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15310 const struct auto_pin_cfg *cfg)
15313 static const char *chname[4] = {
15314 "Front", "Surround", NULL /*CLFE*/, "Side"
15319 for (i = 0; i < cfg->line_outs; i++) {
15320 if (!spec->multiout.dac_nids[i])
15322 nid = alc880_idx_to_dac(i);
15325 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15326 "Center Playback Volume",
15327 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15331 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15332 "LFE Playback Volume",
15333 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15337 err = add_control(spec, ALC_CTL_BIND_MUTE,
15338 "Center Playback Switch",
15339 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
15343 err = add_control(spec, ALC_CTL_BIND_MUTE,
15344 "LFE Playback Switch",
15345 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
15350 sprintf(name, "%s Playback Volume", chname[i]);
15351 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15352 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15356 sprintf(name, "%s Playback Switch", chname[i]);
15357 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15358 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
15367 /* add playback controls for speaker and HP outputs */
15368 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15379 /* ALC663 has a mono output pin on 0x17 */
15380 sprintf(name, "%s Playback Switch", pfx);
15381 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15382 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15386 if (alc880_is_fixed_pin(pin)) {
15387 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15388 /* printk("DAC nid=%x\n",nid); */
15389 /* specify the DAC as the extra output */
15390 if (!spec->multiout.hp_nid)
15391 spec->multiout.hp_nid = nid;
15393 spec->multiout.extra_out_nid[0] = nid;
15394 /* control HP volume/switch on the output mixer amp */
15395 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15396 sprintf(name, "%s Playback Volume", pfx);
15397 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15398 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15401 sprintf(name, "%s Playback Switch", pfx);
15402 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15403 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15406 } else if (alc880_is_multi_pin(pin)) {
15407 /* set manual connection */
15408 /* we have only a switch on HP-out PIN */
15409 sprintf(name, "%s Playback Switch", pfx);
15410 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15411 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15418 /* create playback/capture controls for input pins */
15419 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
15420 const struct auto_pin_cfg *cfg)
15422 struct hda_input_mux *imux = &spec->private_imux;
15425 for (i = 0; i < AUTO_PIN_LAST; i++) {
15426 if (alc880_is_input_pin(cfg->input_pins[i])) {
15427 idx = alc880_input_pin_idx(cfg->input_pins[i]);
15428 err = new_analog_input(spec, cfg->input_pins[i],
15429 auto_pin_cfg_labels[i],
15433 imux->items[imux->num_items].label =
15434 auto_pin_cfg_labels[i];
15435 imux->items[imux->num_items].index =
15436 alc880_input_pin_idx(cfg->input_pins[i]);
15443 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
15444 hda_nid_t nid, int pin_type,
15447 alc_set_pin_output(codec, nid, pin_type);
15448 /* need the manual connection? */
15449 if (alc880_is_multi_pin(nid)) {
15450 struct alc_spec *spec = codec->spec;
15451 int idx = alc880_multi_pin_idx(nid);
15452 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
15453 AC_VERB_SET_CONNECT_SEL,
15454 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
15458 static void alc662_auto_init_multi_out(struct hda_codec *codec)
15460 struct alc_spec *spec = codec->spec;
15463 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
15464 for (i = 0; i <= HDA_SIDE; i++) {
15465 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15466 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15468 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
15473 static void alc662_auto_init_hp_out(struct hda_codec *codec)
15475 struct alc_spec *spec = codec->spec;
15478 pin = spec->autocfg.hp_pins[0];
15479 if (pin) /* connect to front */
15481 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15482 pin = spec->autocfg.speaker_pins[0];
15484 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15487 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
15488 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
15490 static void alc662_auto_init_analog_input(struct hda_codec *codec)
15492 struct alc_spec *spec = codec->spec;
15495 for (i = 0; i < AUTO_PIN_LAST; i++) {
15496 hda_nid_t nid = spec->autocfg.input_pins[i];
15497 if (alc662_is_input_pin(nid)) {
15498 snd_hda_codec_write(codec, nid, 0,
15499 AC_VERB_SET_PIN_WIDGET_CONTROL,
15500 (i <= AUTO_PIN_FRONT_MIC ?
15501 PIN_VREF80 : PIN_IN));
15502 if (nid != ALC662_PIN_CD_NID)
15503 snd_hda_codec_write(codec, nid, 0,
15504 AC_VERB_SET_AMP_GAIN_MUTE,
15510 #define alc662_auto_init_input_src alc882_auto_init_input_src
15512 static int alc662_parse_auto_config(struct hda_codec *codec)
15514 struct alc_spec *spec = codec->spec;
15516 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
15518 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15522 if (!spec->autocfg.line_outs)
15523 return 0; /* can't find valid BIOS pin config */
15525 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15528 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
15531 err = alc662_auto_create_extra_out(spec,
15532 spec->autocfg.speaker_pins[0],
15536 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
15540 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
15544 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15546 if (spec->autocfg.dig_out_pin)
15547 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
15549 if (spec->kctl_alloc)
15550 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
15552 spec->num_mux_defs = 1;
15553 spec->input_mux = &spec->private_imux;
15555 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
15556 if (codec->vendor_id == 0x10ec0663)
15557 spec->init_verbs[spec->num_init_verbs++] =
15558 alc663_auto_init_verbs;
15560 err = alc_auto_add_mic_boost(codec);
15564 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
15565 spec->num_mixers++;
15569 /* additional initialization for auto-configuration model */
15570 static void alc662_auto_init(struct hda_codec *codec)
15572 struct alc_spec *spec = codec->spec;
15573 alc662_auto_init_multi_out(codec);
15574 alc662_auto_init_hp_out(codec);
15575 alc662_auto_init_analog_input(codec);
15576 alc662_auto_init_input_src(codec);
15577 if (spec->unsol_event)
15578 alc_sku_automute(codec);
15581 static int patch_alc662(struct hda_codec *codec)
15583 struct alc_spec *spec;
15584 int err, board_config;
15586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15590 codec->spec = spec;
15592 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15594 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
15597 if (board_config < 0) {
15598 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
15599 "trying auto-probe from BIOS...\n");
15600 board_config = ALC662_AUTO;
15603 if (board_config == ALC662_AUTO) {
15604 /* automatic parse from the BIOS config */
15605 err = alc662_parse_auto_config(codec);
15611 "hda_codec: Cannot set up configuration "
15612 "from BIOS. Using base mode...\n");
15613 board_config = ALC662_3ST_2ch_DIG;
15617 if (board_config != ALC662_AUTO)
15618 setup_preset(spec, &alc662_presets[board_config]);
15620 if (codec->vendor_id == 0x10ec0663) {
15621 spec->stream_name_analog = "ALC663 Analog";
15622 spec->stream_name_digital = "ALC663 Digital";
15624 spec->stream_name_analog = "ALC662 Analog";
15625 spec->stream_name_digital = "ALC662 Digital";
15628 spec->stream_analog_playback = &alc662_pcm_analog_playback;
15629 spec->stream_analog_capture = &alc662_pcm_analog_capture;
15631 spec->stream_digital_playback = &alc662_pcm_digital_playback;
15632 spec->stream_digital_capture = &alc662_pcm_digital_capture;
15634 spec->adc_nids = alc662_adc_nids;
15635 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
15636 spec->capsrc_nids = alc662_capsrc_nids;
15638 spec->vmaster_nid = 0x02;
15640 codec->patch_ops = alc_patch_ops;
15641 if (board_config == ALC662_AUTO)
15642 spec->init_hook = alc662_auto_init;
15643 #ifdef CONFIG_SND_HDA_POWER_SAVE
15644 if (!spec->loopback.amplist)
15645 spec->loopback.amplist = alc662_loopbacks;
15654 struct hda_codec_preset snd_hda_preset_realtek[] = {
15655 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
15656 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
15657 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
15658 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
15659 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
15660 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
15661 .patch = patch_alc861 },
15662 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
15663 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
15664 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
15665 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
15666 .patch = patch_alc883 },
15667 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
15668 .patch = patch_alc662 },
15669 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
15670 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
15671 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
15672 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
15673 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
15674 .patch = patch_alc882 }, /* should be patch_alc883() in future */
15675 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
15676 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
15677 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
15678 {} /* terminator */