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 <sound/jack.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
36 #define ALC880_FRONT_EVENT 0x01
37 #define ALC880_DCVOL_EVENT 0x02
38 #define ALC880_HP_EVENT 0x04
39 #define ALC880_MIC_EVENT 0x08
41 /* ALC880 board config type */
65 #ifdef CONFIG_SND_DEBUG
69 ALC880_MODEL_LAST /* last tag */
83 #ifdef CONFIG_SND_DEBUG
87 ALC260_MODEL_LAST /* last tag */
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
111 ALC262_MODEL_LAST /* last tag */
121 ALC268_ACER_ASPIRE_ONE,
124 #ifdef CONFIG_SND_DEBUG
128 ALC268_MODEL_LAST /* last tag */
143 ALC269_MODEL_LAST /* last tag */
160 /* ALC861-VD models */
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
234 ALC883_MEDION_WIM2160,
236 ALC883_LENOVO_101E_2ch,
237 ALC883_LENOVO_NB0763,
238 ALC888_LENOVO_MS7195_DIG,
246 ALC883_FUJITSU_PI2515,
247 ALC888_FUJITSU_XA3530,
248 ALC883_3ST_6ch_INTEL,
268 #define GPIO_MASK 0x03
270 /* extra amp-initialization sequence types */
279 struct alc_mic_route {
281 unsigned char mux_idx;
282 unsigned char amix_idx;
285 #define MUX_IDX_UNDEF ((unsigned char)-1)
287 struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
296 unsigned int override:1;
297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
302 struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
315 /* codec parameterization */
316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
317 unsigned int num_mixers;
318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
321 const struct hda_verb *init_verbs[10]; /* initialization verbs
325 unsigned int num_init_verbs;
327 char stream_name_analog[32]; /* analog PCM stream */
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
333 char stream_name_digital[32]; /* digital PCM stream */
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
342 hda_nid_t alt_dac_nid;
343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
347 unsigned int num_adc_nids;
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
351 hda_nid_t mixer_nid; /* analog-mixer NID */
353 /* capture setup for dynamic dual-adc switch */
354 unsigned int cur_adc_idx;
356 unsigned int cur_adc_stream_tag;
357 unsigned int cur_adc_format;
360 unsigned int num_mux_defs;
361 const struct hda_input_mux *input_mux;
362 unsigned int cur_mux[3];
363 struct alc_mic_route ext_mic;
364 struct alc_mic_route dock_mic;
365 struct alc_mic_route int_mic;
368 const struct hda_channel_mode *channel_mode;
369 int num_channel_mode;
371 int const_channel_count;
372 int ext_channel_count;
374 /* PCM information */
375 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
377 /* dynamic controls, init_verbs and input_mux */
378 struct auto_pin_cfg autocfg;
379 struct alc_customize_define cdefine;
380 struct snd_array kctls;
381 struct hda_input_mux private_imux[3];
382 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
384 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
387 void (*init_hook)(struct hda_codec *codec);
388 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
389 #ifdef CONFIG_SND_HDA_POWER_SAVE
390 void (*power_hook)(struct hda_codec *codec);
392 void (*shutup)(struct hda_codec *codec);
394 /* for pin sensing */
395 unsigned int jack_present: 1;
396 unsigned int line_jack_present:1;
397 unsigned int master_mute:1;
398 unsigned int auto_mic:1;
399 unsigned int automute:1; /* HP automute enabled */
400 unsigned int detect_line:1; /* Line-out detection enabled */
401 unsigned int automute_lines:1; /* automute line-out as well */
402 unsigned int automute_hp_lo:1; /* both HP and LO available */
405 unsigned int no_analog :1; /* digital I/O only */
406 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
407 unsigned int single_input_src:1;
408 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
410 /* auto-mute control */
412 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
415 int codec_variant; /* flag for other variants */
417 /* for virtual master */
418 hda_nid_t vmaster_nid;
419 #ifdef CONFIG_SND_HDA_POWER_SAVE
420 struct hda_loopback_check loopback;
425 unsigned int pll_coef_idx, pll_coef_bit;
429 const struct alc_fixup *fixup_list;
430 const char *fixup_name;
434 struct alc_multi_io multi_io[4];
438 * configuration template - to be copied to the spec instance
440 struct alc_config_preset {
441 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
444 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
445 const struct hda_verb *init_verbs[5];
446 unsigned int num_dacs;
447 const hda_nid_t *dac_nids;
448 hda_nid_t dig_out_nid; /* optional */
449 hda_nid_t hp_nid; /* optional */
450 const hda_nid_t *slave_dig_outs;
451 unsigned int num_adc_nids;
452 const hda_nid_t *adc_nids;
453 const hda_nid_t *capsrc_nids;
454 hda_nid_t dig_in_nid;
455 unsigned int num_channel_mode;
456 const struct hda_channel_mode *channel_mode;
458 int const_channel_count;
459 unsigned int num_mux_defs;
460 const struct hda_input_mux *input_mux;
461 void (*unsol_event)(struct hda_codec *, unsigned int);
462 void (*setup)(struct hda_codec *);
463 void (*init_hook)(struct hda_codec *);
464 #ifdef CONFIG_SND_HDA_POWER_SAVE
465 const struct hda_amp_list *loopbacks;
466 void (*power_hook)(struct hda_codec *codec);
474 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
475 struct snd_ctl_elem_info *uinfo)
477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
478 struct alc_spec *spec = codec->spec;
479 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
480 if (mux_idx >= spec->num_mux_defs)
482 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
484 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
487 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
488 struct snd_ctl_elem_value *ucontrol)
490 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
491 struct alc_spec *spec = codec->spec;
492 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
494 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
498 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502 struct alc_spec *spec = codec->spec;
503 const struct hda_input_mux *imux;
504 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
505 unsigned int mux_idx;
506 hda_nid_t nid = spec->capsrc_nids ?
507 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
510 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
511 imux = &spec->input_mux[mux_idx];
512 if (!imux->num_items && mux_idx > 0)
513 imux = &spec->input_mux[0];
515 type = get_wcaps_type(get_wcaps(codec, nid));
516 if (type == AC_WID_AUD_MIX) {
517 /* Matrix-mixer style (e.g. ALC882) */
518 unsigned int *cur_val = &spec->cur_mux[adc_idx];
521 idx = ucontrol->value.enumerated.item[0];
522 if (idx >= imux->num_items)
523 idx = imux->num_items - 1;
526 for (i = 0; i < imux->num_items; i++) {
527 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
528 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
529 imux->items[i].index,
535 /* MUX style (e.g. ALC880) */
536 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
537 &spec->cur_mux[adc_idx]);
542 * channel mode setting
544 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_info *uinfo)
547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548 struct alc_spec *spec = codec->spec;
549 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
550 spec->num_channel_mode);
553 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_value *ucontrol)
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 struct alc_spec *spec = codec->spec;
558 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
559 spec->num_channel_mode,
560 spec->ext_channel_count);
563 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
566 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
567 struct alc_spec *spec = codec->spec;
568 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
569 spec->num_channel_mode,
570 &spec->ext_channel_count);
571 if (err >= 0 && !spec->const_channel_count) {
572 spec->multiout.max_channels = spec->ext_channel_count;
573 if (spec->need_dac_fix)
574 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
580 * Control the mode of pin widget settings via the mixer. "pc" is used
581 * instead of "%" to avoid consequences of accidentally treating the % as
582 * being part of a format specifier. Maximum allowed length of a value is
583 * 63 characters plus NULL terminator.
585 * Note: some retasking pin complexes seem to ignore requests for input
586 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
587 * are requested. Therefore order this list so that this behaviour will not
588 * cause problems when mixer clients move through the enum sequentially.
589 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
592 static const char * const alc_pin_mode_names[] = {
593 "Mic 50pc bias", "Mic 80pc bias",
594 "Line in", "Line out", "Headphone out",
596 static const unsigned char alc_pin_mode_values[] = {
597 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
599 /* The control can present all 5 options, or it can limit the options based
600 * in the pin being assumed to be exclusively an input or an output pin. In
601 * addition, "input" pins may or may not process the mic bias option
602 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
603 * accept requests for bias as of chip versions up to March 2006) and/or
604 * wiring in the computer.
606 #define ALC_PIN_DIR_IN 0x00
607 #define ALC_PIN_DIR_OUT 0x01
608 #define ALC_PIN_DIR_INOUT 0x02
609 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
610 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
612 /* Info about the pin modes supported by the different pin direction modes.
613 * For each direction the minimum and maximum values are given.
615 static const signed char alc_pin_mode_dir_info[5][2] = {
616 { 0, 2 }, /* ALC_PIN_DIR_IN */
617 { 3, 4 }, /* ALC_PIN_DIR_OUT */
618 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
619 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
620 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
622 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
623 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
624 #define alc_pin_mode_n_items(_dir) \
625 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
627 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_info *uinfo)
630 unsigned int item_num = uinfo->value.enumerated.item;
631 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
633 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
635 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
637 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
638 item_num = alc_pin_mode_min(dir);
639 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
643 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol)
647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
648 hda_nid_t nid = kcontrol->private_value & 0xffff;
649 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
650 long *valp = ucontrol->value.integer.value;
651 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
652 AC_VERB_GET_PIN_WIDGET_CONTROL,
655 /* Find enumerated value for current pinctl setting */
656 i = alc_pin_mode_min(dir);
657 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
659 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
663 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
664 struct snd_ctl_elem_value *ucontrol)
667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
668 hda_nid_t nid = kcontrol->private_value & 0xffff;
669 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
670 long val = *ucontrol->value.integer.value;
671 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_PIN_WIDGET_CONTROL,
675 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
676 val = alc_pin_mode_min(dir);
678 change = pinctl != alc_pin_mode_values[val];
680 /* Set pin mode to that requested */
681 snd_hda_codec_write_cache(codec, nid, 0,
682 AC_VERB_SET_PIN_WIDGET_CONTROL,
683 alc_pin_mode_values[val]);
685 /* Also enable the retasking pin's input/output as required
686 * for the requested pin mode. Enum values of 2 or less are
689 * Dynamically switching the input/output buffers probably
690 * reduces noise slightly (particularly on input) so we'll
691 * do it. However, having both input and output buffers
692 * enabled simultaneously doesn't seem to be problematic if
693 * this turns out to be necessary in the future.
696 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
697 HDA_AMP_MUTE, HDA_AMP_MUTE);
698 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
701 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
702 HDA_AMP_MUTE, HDA_AMP_MUTE);
703 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
710 #define ALC_PIN_MODE(xname, nid, dir) \
711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
712 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
713 .info = alc_pin_mode_info, \
714 .get = alc_pin_mode_get, \
715 .put = alc_pin_mode_put, \
716 .private_value = nid | (dir<<16) }
718 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
719 * together using a mask with more than one bit set. This control is
720 * currently used only by the ALC260 test model. At this stage they are not
721 * needed for any "production" models.
723 #ifdef CONFIG_SND_DEBUG
724 #define alc_gpio_data_info snd_ctl_boolean_mono_info
726 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
730 hda_nid_t nid = kcontrol->private_value & 0xffff;
731 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
732 long *valp = ucontrol->value.integer.value;
733 unsigned int val = snd_hda_codec_read(codec, nid, 0,
734 AC_VERB_GET_GPIO_DATA, 0x00);
736 *valp = (val & mask) != 0;
739 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
740 struct snd_ctl_elem_value *ucontrol)
743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 hda_nid_t nid = kcontrol->private_value & 0xffff;
745 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
746 long val = *ucontrol->value.integer.value;
747 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
748 AC_VERB_GET_GPIO_DATA,
751 /* Set/unset the masked GPIO bit(s) as needed */
752 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
757 snd_hda_codec_write_cache(codec, nid, 0,
758 AC_VERB_SET_GPIO_DATA, gpio_data);
762 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
764 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
765 .info = alc_gpio_data_info, \
766 .get = alc_gpio_data_get, \
767 .put = alc_gpio_data_put, \
768 .private_value = nid | (mask<<16) }
769 #endif /* CONFIG_SND_DEBUG */
771 /* A switch control to allow the enabling of the digital IO pins on the
772 * ALC260. This is incredibly simplistic; the intention of this control is
773 * to provide something in the test model allowing digital outputs to be
774 * identified if present. If models are found which can utilise these
775 * outputs a more complete mixer control can be devised for those models if
778 #ifdef CONFIG_SND_DEBUG
779 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
781 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
782 struct snd_ctl_elem_value *ucontrol)
784 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
785 hda_nid_t nid = kcontrol->private_value & 0xffff;
786 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
787 long *valp = ucontrol->value.integer.value;
788 unsigned int val = snd_hda_codec_read(codec, nid, 0,
789 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
791 *valp = (val & mask) != 0;
794 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
795 struct snd_ctl_elem_value *ucontrol)
798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
799 hda_nid_t nid = kcontrol->private_value & 0xffff;
800 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
801 long val = *ucontrol->value.integer.value;
802 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
803 AC_VERB_GET_DIGI_CONVERT_1,
806 /* Set/unset the masked control bit(s) as needed */
807 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
812 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
817 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
818 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
819 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
820 .info = alc_spdif_ctrl_info, \
821 .get = alc_spdif_ctrl_get, \
822 .put = alc_spdif_ctrl_put, \
823 .private_value = nid | (mask<<16) }
824 #endif /* CONFIG_SND_DEBUG */
826 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
827 * Again, this is only used in the ALC26x test models to help identify when
828 * the EAPD line must be asserted for features to work.
830 #ifdef CONFIG_SND_DEBUG
831 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
833 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
834 struct snd_ctl_elem_value *ucontrol)
836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
837 hda_nid_t nid = kcontrol->private_value & 0xffff;
838 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
839 long *valp = ucontrol->value.integer.value;
840 unsigned int val = snd_hda_codec_read(codec, nid, 0,
841 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
843 *valp = (val & mask) != 0;
847 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
848 struct snd_ctl_elem_value *ucontrol)
851 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
852 hda_nid_t nid = kcontrol->private_value & 0xffff;
853 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
854 long val = *ucontrol->value.integer.value;
855 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
856 AC_VERB_GET_EAPD_BTLENABLE,
859 /* Set/unset the masked control bit(s) as needed */
860 change = (!val ? 0 : mask) != (ctrl_data & mask);
865 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
871 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
872 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
873 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
874 .info = alc_eapd_ctrl_info, \
875 .get = alc_eapd_ctrl_get, \
876 .put = alc_eapd_ctrl_put, \
877 .private_value = nid | (mask<<16) }
878 #endif /* CONFIG_SND_DEBUG */
881 * set up the input pin config (depending on the given auto-pin type)
883 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
886 unsigned int val = PIN_IN;
888 if (auto_pin_type == AUTO_PIN_MIC) {
891 oldval = snd_hda_codec_read(codec, nid, 0,
892 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
893 pincap = snd_hda_query_pin_caps(codec, nid);
894 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
895 /* if the default pin setup is vref50, we give it priority */
896 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
898 else if (pincap & AC_PINCAP_VREF_50)
900 else if (pincap & AC_PINCAP_VREF_100)
902 else if (pincap & AC_PINCAP_VREF_GRD)
905 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
908 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
910 struct alc_spec *spec = codec->spec;
911 struct auto_pin_cfg *cfg = &spec->autocfg;
913 if (!cfg->line_outs) {
914 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
915 cfg->line_out_pins[cfg->line_outs])
918 if (!cfg->speaker_outs) {
919 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
920 cfg->speaker_pins[cfg->speaker_outs])
924 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
925 cfg->hp_pins[cfg->hp_outs])
932 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
934 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
936 spec->mixers[spec->num_mixers++] = mix;
939 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
941 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
943 spec->init_verbs[spec->num_init_verbs++] = verb;
947 * set up from the preset table
949 static void setup_preset(struct hda_codec *codec,
950 const struct alc_config_preset *preset)
952 struct alc_spec *spec = codec->spec;
955 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
956 add_mixer(spec, preset->mixers[i]);
957 spec->cap_mixer = preset->cap_mixer;
958 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
960 add_verb(spec, preset->init_verbs[i]);
962 spec->channel_mode = preset->channel_mode;
963 spec->num_channel_mode = preset->num_channel_mode;
964 spec->need_dac_fix = preset->need_dac_fix;
965 spec->const_channel_count = preset->const_channel_count;
967 if (preset->const_channel_count)
968 spec->multiout.max_channels = preset->const_channel_count;
970 spec->multiout.max_channels = spec->channel_mode[0].channels;
971 spec->ext_channel_count = spec->channel_mode[0].channels;
973 spec->multiout.num_dacs = preset->num_dacs;
974 spec->multiout.dac_nids = preset->dac_nids;
975 spec->multiout.dig_out_nid = preset->dig_out_nid;
976 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
977 spec->multiout.hp_nid = preset->hp_nid;
979 spec->num_mux_defs = preset->num_mux_defs;
980 if (!spec->num_mux_defs)
981 spec->num_mux_defs = 1;
982 spec->input_mux = preset->input_mux;
984 spec->num_adc_nids = preset->num_adc_nids;
985 spec->adc_nids = preset->adc_nids;
986 spec->capsrc_nids = preset->capsrc_nids;
987 spec->dig_in_nid = preset->dig_in_nid;
989 spec->unsol_event = preset->unsol_event;
990 spec->init_hook = preset->init_hook;
991 #ifdef CONFIG_SND_HDA_POWER_SAVE
992 spec->power_hook = preset->power_hook;
993 spec->loopback.amplist = preset->loopbacks;
997 preset->setup(codec);
999 alc_fixup_autocfg_pin_nums(codec);
1002 /* Enable GPIO mask and set output */
1003 static const struct hda_verb alc_gpio1_init_verbs[] = {
1004 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1006 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1010 static const struct hda_verb alc_gpio2_init_verbs[] = {
1011 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1013 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1017 static const struct hda_verb alc_gpio3_init_verbs[] = {
1018 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1020 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1025 * Fix hardware PLL issue
1026 * On some codecs, the analog PLL gating control must be off while
1027 * the default value is 1.
1029 static void alc_fix_pll(struct hda_codec *codec)
1031 struct alc_spec *spec = codec->spec;
1036 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1037 spec->pll_coef_idx);
1038 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1039 AC_VERB_GET_PROC_COEF, 0);
1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1041 spec->pll_coef_idx);
1042 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1043 val & ~(1 << spec->pll_coef_bit));
1046 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1047 unsigned int coef_idx, unsigned int coef_bit)
1049 struct alc_spec *spec = codec->spec;
1050 spec->pll_nid = nid;
1051 spec->pll_coef_idx = coef_idx;
1052 spec->pll_coef_bit = coef_bit;
1056 static int alc_init_jacks(struct hda_codec *codec)
1058 #ifdef CONFIG_SND_HDA_INPUT_JACK
1059 struct alc_spec *spec = codec->spec;
1061 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1062 unsigned int mic_nid = spec->ext_mic.pin;
1063 unsigned int dock_nid = spec->dock_mic.pin;
1066 err = snd_hda_input_jack_add(codec, hp_nid,
1067 SND_JACK_HEADPHONE, NULL);
1070 snd_hda_input_jack_report(codec, hp_nid);
1074 err = snd_hda_input_jack_add(codec, mic_nid,
1075 SND_JACK_MICROPHONE, NULL);
1078 snd_hda_input_jack_report(codec, mic_nid);
1081 err = snd_hda_input_jack_add(codec, dock_nid,
1082 SND_JACK_MICROPHONE, NULL);
1085 snd_hda_input_jack_report(codec, dock_nid);
1087 #endif /* CONFIG_SND_HDA_INPUT_JACK */
1091 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1095 for (i = 0; i < num_pins; i++) {
1096 hda_nid_t nid = pins[i];
1099 snd_hda_input_jack_report(codec, nid);
1100 present |= snd_hda_jack_detect(codec, nid);
1105 static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1106 bool mute, bool hp_out)
1108 struct alc_spec *spec = codec->spec;
1109 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1110 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1113 for (i = 0; i < num_pins; i++) {
1114 hda_nid_t nid = pins[i];
1117 switch (spec->automute_mode) {
1118 case ALC_AUTOMUTE_PIN:
1119 snd_hda_codec_write(codec, nid, 0,
1120 AC_VERB_SET_PIN_WIDGET_CONTROL,
1123 case ALC_AUTOMUTE_AMP:
1124 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1125 HDA_AMP_MUTE, mute_bits);
1127 case ALC_AUTOMUTE_MIXER:
1128 nid = spec->automute_mixer_nid[i];
1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1132 HDA_AMP_MUTE, mute_bits);
1133 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1134 HDA_AMP_MUTE, mute_bits);
1140 /* Toggle internal speakers muting */
1141 static void update_speakers(struct hda_codec *codec)
1143 struct alc_spec *spec = codec->spec;
1146 /* Control HP pins/amps depending on master_mute state;
1147 * in general, HP pins/amps control should be enabled in all cases,
1148 * but currently set only for master_mute, just to be safe
1150 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1151 spec->autocfg.hp_pins, spec->master_mute, true);
1153 if (!spec->automute)
1156 on = spec->jack_present | spec->line_jack_present;
1157 on |= spec->master_mute;
1158 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1159 spec->autocfg.speaker_pins, on, false);
1161 /* toggle line-out mutes if needed, too */
1162 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1163 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1164 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1166 if (!spec->automute_lines || !spec->automute)
1169 on = spec->jack_present;
1170 on |= spec->master_mute;
1171 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1172 spec->autocfg.line_out_pins, on, false);
1175 static void alc_hp_automute(struct hda_codec *codec)
1177 struct alc_spec *spec = codec->spec;
1179 if (!spec->automute)
1181 spec->jack_present =
1182 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1183 spec->autocfg.hp_pins);
1184 update_speakers(codec);
1187 static void alc_line_automute(struct hda_codec *codec)
1189 struct alc_spec *spec = codec->spec;
1191 if (!spec->automute || !spec->detect_line)
1193 spec->line_jack_present =
1194 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1195 spec->autocfg.line_out_pins);
1196 update_speakers(codec);
1199 #define get_connection_index(codec, mux, nid) \
1200 snd_hda_get_conn_index(codec, mux, nid, 0)
1202 /* switch the current ADC according to the jack state */
1203 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1205 struct alc_spec *spec = codec->spec;
1206 unsigned int present;
1209 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1211 spec->cur_adc_idx = 1;
1213 spec->cur_adc_idx = 0;
1214 new_adc = spec->adc_nids[spec->cur_adc_idx];
1215 if (spec->cur_adc && spec->cur_adc != new_adc) {
1216 /* stream is running, let's swap the current ADC */
1217 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1218 spec->cur_adc = new_adc;
1219 snd_hda_codec_setup_stream(codec, new_adc,
1220 spec->cur_adc_stream_tag, 0,
1221 spec->cur_adc_format);
1225 static void alc_mic_automute(struct hda_codec *codec)
1227 struct alc_spec *spec = codec->spec;
1228 struct alc_mic_route *dead1, *dead2, *alive;
1229 unsigned int present, type;
1232 if (!spec->auto_mic)
1234 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1236 if (snd_BUG_ON(!spec->adc_nids))
1239 if (spec->dual_adc_switch) {
1240 alc_dual_mic_adc_auto_switch(codec);
1244 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1246 alive = &spec->int_mic;
1247 dead1 = &spec->ext_mic;
1248 dead2 = &spec->dock_mic;
1250 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1252 alive = &spec->ext_mic;
1253 dead1 = &spec->int_mic;
1254 dead2 = &spec->dock_mic;
1256 if (!present && spec->dock_mic.pin > 0) {
1257 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1259 alive = &spec->dock_mic;
1260 dead1 = &spec->int_mic;
1261 dead2 = &spec->ext_mic;
1263 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1266 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1267 if (type == AC_WID_AUD_MIX) {
1268 /* Matrix-mixer style (e.g. ALC882) */
1269 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1273 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1275 HDA_AMP_MUTE, HDA_AMP_MUTE);
1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 HDA_AMP_MUTE, HDA_AMP_MUTE);
1281 /* MUX style (e.g. ALC880) */
1282 snd_hda_codec_write_cache(codec, cap_nid, 0,
1283 AC_VERB_SET_CONNECT_SEL,
1286 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1288 /* FIXME: analog mixer */
1291 /* unsolicited event for HP jack sensing */
1292 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1294 if (codec->vendor_id == 0x10ec0880)
1299 case ALC880_HP_EVENT:
1300 alc_hp_automute(codec);
1302 case ALC880_FRONT_EVENT:
1303 alc_line_automute(codec);
1305 case ALC880_MIC_EVENT:
1306 alc_mic_automute(codec);
1311 static void alc_inithook(struct hda_codec *codec)
1313 alc_hp_automute(codec);
1314 alc_line_automute(codec);
1315 alc_mic_automute(codec);
1318 /* additional initialization for ALC888 variants */
1319 static void alc888_coef_init(struct hda_codec *codec)
1323 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1324 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1325 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1326 if ((tmp & 0xf0) == 0x20)
1328 snd_hda_codec_read(codec, 0x20, 0,
1329 AC_VERB_SET_PROC_COEF, 0x830);
1332 snd_hda_codec_read(codec, 0x20, 0,
1333 AC_VERB_SET_PROC_COEF, 0x3030);
1336 static void alc889_coef_init(struct hda_codec *codec)
1340 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1341 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1342 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1343 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1346 /* turn on/off EAPD control (only if available) */
1347 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1349 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1351 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1352 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1356 /* turn on/off EAPD controls of the codec */
1357 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1359 /* We currently only handle front, HP */
1360 static hda_nid_t pins[] = {
1361 0x0f, 0x10, 0x14, 0x15, 0
1364 for (p = pins; *p; p++)
1365 set_eapd(codec, *p, on);
1368 /* generic shutup callback;
1369 * just turning off EPAD and a little pause for avoiding pop-noise
1371 static void alc_eapd_shutup(struct hda_codec *codec)
1373 alc_auto_setup_eapd(codec, false);
1377 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1381 alc_auto_setup_eapd(codec, true);
1383 case ALC_INIT_GPIO1:
1384 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1386 case ALC_INIT_GPIO2:
1387 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1389 case ALC_INIT_GPIO3:
1390 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1392 case ALC_INIT_DEFAULT:
1393 switch (codec->vendor_id) {
1395 snd_hda_codec_write(codec, 0x1a, 0,
1396 AC_VERB_SET_COEF_INDEX, 7);
1397 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1398 AC_VERB_GET_PROC_COEF, 0);
1399 snd_hda_codec_write(codec, 0x1a, 0,
1400 AC_VERB_SET_COEF_INDEX, 7);
1401 snd_hda_codec_write(codec, 0x1a, 0,
1402 AC_VERB_SET_PROC_COEF,
1411 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1412 alc889_coef_init(codec);
1415 alc888_coef_init(codec);
1417 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1420 snd_hda_codec_write(codec, 0x20, 0,
1421 AC_VERB_SET_COEF_INDEX, 7);
1422 tmp = snd_hda_codec_read(codec, 0x20, 0,
1423 AC_VERB_GET_PROC_COEF, 0);
1424 snd_hda_codec_write(codec, 0x20, 0,
1425 AC_VERB_SET_COEF_INDEX, 7);
1426 snd_hda_codec_write(codec, 0x20, 0,
1427 AC_VERB_SET_PROC_COEF,
1436 static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1437 struct snd_ctl_elem_info *uinfo)
1439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1440 struct alc_spec *spec = codec->spec;
1441 static const char * const texts2[] = {
1442 "Disabled", "Enabled"
1444 static const char * const texts3[] = {
1445 "Disabled", "Speaker Only", "Line-Out+Speaker"
1447 const char * const *texts;
1449 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1451 if (spec->automute_hp_lo) {
1452 uinfo->value.enumerated.items = 3;
1455 uinfo->value.enumerated.items = 2;
1458 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1459 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1460 strcpy(uinfo->value.enumerated.name,
1461 texts[uinfo->value.enumerated.item]);
1465 static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1466 struct snd_ctl_elem_value *ucontrol)
1468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1469 struct alc_spec *spec = codec->spec;
1471 if (!spec->automute)
1473 else if (!spec->automute_lines)
1477 ucontrol->value.enumerated.item[0] = val;
1481 static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1482 struct snd_ctl_elem_value *ucontrol)
1484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1485 struct alc_spec *spec = codec->spec;
1487 switch (ucontrol->value.enumerated.item[0]) {
1489 if (!spec->automute)
1494 if (spec->automute && !spec->automute_lines)
1497 spec->automute_lines = 0;
1500 if (!spec->automute_hp_lo)
1502 if (spec->automute && spec->automute_lines)
1505 spec->automute_lines = 1;
1510 update_speakers(codec);
1514 static const struct snd_kcontrol_new alc_automute_mode_enum = {
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = "Auto-Mute Mode",
1517 .info = alc_automute_mode_info,
1518 .get = alc_automute_mode_get,
1519 .put = alc_automute_mode_put,
1522 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1524 static int alc_add_automute_mode_enum(struct hda_codec *codec)
1526 struct alc_spec *spec = codec->spec;
1527 struct snd_kcontrol_new *knew;
1529 knew = alc_kcontrol_new(spec);
1532 *knew = alc_automute_mode_enum;
1533 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1539 static void alc_init_auto_hp(struct hda_codec *codec)
1541 struct alc_spec *spec = codec->spec;
1542 struct auto_pin_cfg *cfg = &spec->autocfg;
1546 if (cfg->hp_pins[0])
1548 if (cfg->line_out_pins[0])
1550 if (cfg->speaker_pins[0])
1552 if (present < 2) /* need two different output types */
1555 spec->automute_hp_lo = 1; /* both HP and LO automute */
1557 if (!cfg->speaker_pins[0]) {
1558 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1559 sizeof(cfg->speaker_pins));
1560 cfg->speaker_outs = cfg->line_outs;
1563 if (!cfg->hp_pins[0]) {
1564 memcpy(cfg->hp_pins, cfg->line_out_pins,
1565 sizeof(cfg->hp_pins));
1566 cfg->hp_outs = cfg->line_outs;
1569 for (i = 0; i < cfg->hp_outs; i++) {
1570 hda_nid_t nid = cfg->hp_pins[i];
1571 if (!is_jack_detectable(codec, nid))
1573 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1575 snd_hda_codec_write_cache(codec, nid, 0,
1576 AC_VERB_SET_UNSOLICITED_ENABLE,
1577 AC_USRSP_EN | ALC880_HP_EVENT);
1579 spec->automute_mode = ALC_AUTOMUTE_PIN;
1581 if (spec->automute && cfg->line_out_pins[0] &&
1582 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1583 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1584 for (i = 0; i < cfg->line_outs; i++) {
1585 hda_nid_t nid = cfg->line_out_pins[i];
1586 if (!is_jack_detectable(codec, nid))
1588 snd_printdd("realtek: Enable Line-Out auto-muting "
1589 "on NID 0x%x\n", nid);
1590 snd_hda_codec_write_cache(codec, nid, 0,
1591 AC_VERB_SET_UNSOLICITED_ENABLE,
1592 AC_USRSP_EN | ALC880_FRONT_EVENT);
1593 spec->detect_line = 1;
1595 spec->automute_lines = spec->detect_line;
1598 if (spec->automute) {
1599 /* create a control for automute mode */
1600 alc_add_automute_mode_enum(codec);
1601 spec->unsol_event = alc_sku_unsol_event;
1605 static void alc_init_auto_mic(struct hda_codec *codec)
1607 struct alc_spec *spec = codec->spec;
1608 struct auto_pin_cfg *cfg = &spec->autocfg;
1609 hda_nid_t fixed, ext, dock;
1612 fixed = ext = dock = 0;
1613 for (i = 0; i < cfg->num_inputs; i++) {
1614 hda_nid_t nid = cfg->inputs[i].pin;
1615 unsigned int defcfg;
1616 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1617 switch (snd_hda_get_input_pin_attr(defcfg)) {
1618 case INPUT_PIN_ATTR_INT:
1620 return; /* already occupied */
1621 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1622 return; /* invalid type */
1625 case INPUT_PIN_ATTR_UNUSED:
1626 return; /* invalid entry */
1627 case INPUT_PIN_ATTR_DOCK:
1629 return; /* already occupied */
1630 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1631 return; /* invalid type */
1636 return; /* already occupied */
1637 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1638 return; /* invalid type */
1649 if (!is_jack_detectable(codec, ext))
1650 return; /* no unsol support */
1651 if (dock && !is_jack_detectable(codec, dock))
1652 return; /* no unsol support */
1653 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1655 spec->ext_mic.pin = ext;
1656 spec->dock_mic.pin = dock;
1657 spec->int_mic.pin = fixed;
1658 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1659 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1660 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1662 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1663 AC_VERB_SET_UNSOLICITED_ENABLE,
1664 AC_USRSP_EN | ALC880_MIC_EVENT);
1665 spec->unsol_event = alc_sku_unsol_event;
1668 /* Could be any non-zero and even value. When used as fixup, tells
1669 * the driver to ignore any present sku defines.
1671 #define ALC_FIXUP_SKU_IGNORE (2)
1673 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1675 unsigned int ass, tmp, i;
1677 struct alc_spec *spec = codec->spec;
1679 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1681 if (spec->cdefine.fixup) {
1682 ass = spec->cdefine.sku_cfg;
1683 if (ass == ALC_FIXUP_SKU_IGNORE)
1688 ass = codec->subsystem_id & 0xffff;
1689 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1693 if (codec->vendor_id == 0x10ec0260)
1695 ass = snd_hda_codec_get_pincfg(codec, nid);
1698 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1699 codec->chip_name, ass);
1705 for (i = 1; i < 16; i++) {
1709 if (((ass >> 16) & 0xf) != tmp)
1712 spec->cdefine.port_connectivity = ass >> 30;
1713 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1714 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1715 spec->cdefine.customization = ass >> 8;
1717 spec->cdefine.sku_cfg = ass;
1718 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1719 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1720 spec->cdefine.swap = (ass & 0x2) >> 1;
1721 spec->cdefine.override = ass & 0x1;
1723 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1724 nid, spec->cdefine.sku_cfg);
1725 snd_printd("SKU: port_connectivity=0x%x\n",
1726 spec->cdefine.port_connectivity);
1727 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1728 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1729 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1730 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1731 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1732 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1733 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1738 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1741 for (i = 0; i < nums; i++)
1747 /* check subsystem ID and set up device-specific initialization;
1748 * return 1 if initialized, 0 if invalid SSID
1750 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1751 * 31 ~ 16 : Manufacture ID
1753 * 7 ~ 0 : Assembly ID
1754 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1756 static int alc_subsystem_id(struct hda_codec *codec,
1757 hda_nid_t porta, hda_nid_t porte,
1758 hda_nid_t portd, hda_nid_t porti)
1760 unsigned int ass, tmp, i;
1762 struct alc_spec *spec = codec->spec;
1764 if (spec->cdefine.fixup) {
1765 ass = spec->cdefine.sku_cfg;
1766 if (ass == ALC_FIXUP_SKU_IGNORE)
1771 ass = codec->subsystem_id & 0xffff;
1772 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1775 /* invalid SSID, check the special NID pin defcfg instead */
1777 * 31~30 : port connectivity
1780 * 19~16 : Check sum (15:1)
1785 if (codec->vendor_id == 0x10ec0260)
1787 ass = snd_hda_codec_get_pincfg(codec, nid);
1788 snd_printd("realtek: No valid SSID, "
1789 "checking pincfg 0x%08x for NID 0x%x\n",
1793 if ((ass >> 30) != 1) /* no physical connection */
1798 for (i = 1; i < 16; i++) {
1802 if (((ass >> 16) & 0xf) != tmp)
1805 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1806 ass & 0xffff, codec->vendor_id);
1810 * 2 : 0 --> Desktop, 1 --> Laptop
1811 * 3~5 : External Amplifier control
1814 tmp = (ass & 0x38) >> 3; /* external Amp control */
1817 spec->init_amp = ALC_INIT_GPIO1;
1820 spec->init_amp = ALC_INIT_GPIO2;
1823 spec->init_amp = ALC_INIT_GPIO3;
1827 spec->init_amp = ALC_INIT_DEFAULT;
1831 /* is laptop or Desktop and enable the function "Mute internal speaker
1832 * when the external headphone out jack is plugged"
1834 if (!(ass & 0x8000))
1837 * 10~8 : Jack location
1838 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1840 * 15 : 1 --> enable the function "Mute internal speaker
1841 * when the external headphone out jack is plugged"
1843 if (!spec->autocfg.hp_pins[0]) {
1845 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1856 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1857 spec->autocfg.line_outs))
1859 spec->autocfg.hp_pins[0] = nid;
1864 static void alc_ssid_check(struct hda_codec *codec,
1865 hda_nid_t porta, hda_nid_t porte,
1866 hda_nid_t portd, hda_nid_t porti)
1868 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1869 struct alc_spec *spec = codec->spec;
1870 snd_printd("realtek: "
1871 "Enable default setup for auto mode as fallback\n");
1872 spec->init_amp = ALC_INIT_DEFAULT;
1875 alc_init_auto_hp(codec);
1876 alc_init_auto_mic(codec);
1880 * Fix-up pin default configurations and add default verbs
1888 struct alc_model_fixup {
1899 const struct alc_pincfg *pins;
1900 const struct hda_verb *verbs;
1901 void (*func)(struct hda_codec *codec,
1902 const struct alc_fixup *fix,
1916 ALC_FIXUP_ACT_PRE_PROBE,
1917 ALC_FIXUP_ACT_PROBE,
1921 static void alc_apply_fixup(struct hda_codec *codec, int action)
1923 struct alc_spec *spec = codec->spec;
1924 int id = spec->fixup_id;
1925 #ifdef CONFIG_SND_DEBUG_VERBOSE
1926 const char *modelname = spec->fixup_name;
1930 if (!spec->fixup_list)
1934 const struct alc_fixup *fix = spec->fixup_list + id;
1935 const struct alc_pincfg *cfg;
1937 switch (fix->type) {
1939 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1941 snd_printdd(KERN_INFO "hda_codec: %s: "
1942 "Apply sku override for %s\n",
1943 codec->chip_name, modelname);
1944 spec->cdefine.sku_cfg = fix->v.sku;
1945 spec->cdefine.fixup = 1;
1947 case ALC_FIXUP_PINS:
1949 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1951 snd_printdd(KERN_INFO "hda_codec: %s: "
1952 "Apply pincfg for %s\n",
1953 codec->chip_name, modelname);
1954 for (; cfg->nid; cfg++)
1955 snd_hda_codec_set_pincfg(codec, cfg->nid,
1958 case ALC_FIXUP_VERBS:
1959 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1961 snd_printdd(KERN_INFO "hda_codec: %s: "
1962 "Apply fix-verbs for %s\n",
1963 codec->chip_name, modelname);
1964 add_verb(codec->spec, fix->v.verbs);
1966 case ALC_FIXUP_FUNC:
1969 snd_printdd(KERN_INFO "hda_codec: %s: "
1970 "Apply fix-func for %s\n",
1971 codec->chip_name, modelname);
1972 fix->v.func(codec, fix, action);
1975 snd_printk(KERN_ERR "hda_codec: %s: "
1976 "Invalid fixup type %d\n",
1977 codec->chip_name, fix->type);
1988 static void alc_pick_fixup(struct hda_codec *codec,
1989 const struct alc_model_fixup *models,
1990 const struct snd_pci_quirk *quirk,
1991 const struct alc_fixup *fixlist)
1993 struct alc_spec *spec = codec->spec;
1995 const char *name = NULL;
1997 if (codec->modelname && models) {
1998 while (models->name) {
1999 if (!strcmp(codec->modelname, models->name)) {
2001 name = models->name;
2008 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2011 #ifdef CONFIG_SND_DEBUG_VERBOSE
2017 spec->fixup_id = id;
2019 spec->fixup_list = fixlist;
2020 spec->fixup_name = name;
2024 static int alc_read_coef_idx(struct hda_codec *codec,
2025 unsigned int coef_idx)
2028 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2030 val = snd_hda_codec_read(codec, 0x20, 0,
2031 AC_VERB_GET_PROC_COEF, 0);
2035 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2036 unsigned int coef_val)
2038 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2040 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2044 /* set right pin controls for digital I/O */
2045 static void alc_auto_init_digital(struct hda_codec *codec)
2047 struct alc_spec *spec = codec->spec;
2051 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2052 pin = spec->autocfg.dig_out_pins[i];
2055 snd_hda_codec_write(codec, pin, 0,
2056 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2058 dac = spec->multiout.dig_out_nid;
2060 dac = spec->slave_dig_outs[i - 1];
2061 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2063 snd_hda_codec_write(codec, dac, 0,
2064 AC_VERB_SET_AMP_GAIN_MUTE,
2067 pin = spec->autocfg.dig_in_pin;
2069 snd_hda_codec_write(codec, pin, 0,
2070 AC_VERB_SET_PIN_WIDGET_CONTROL,
2074 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2075 static void alc_auto_parse_digital(struct hda_codec *codec)
2077 struct alc_spec *spec = codec->spec;
2081 /* support multiple SPDIFs; the secondary is set up as a slave */
2082 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2083 err = snd_hda_get_connections(codec,
2084 spec->autocfg.dig_out_pins[i],
2089 spec->multiout.dig_out_nid = dig_nid;
2090 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2092 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2093 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2095 spec->slave_dig_outs[i - 1] = dig_nid;
2099 if (spec->autocfg.dig_in_pin) {
2100 dig_nid = codec->start_nid;
2101 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2102 unsigned int wcaps = get_wcaps(codec, dig_nid);
2103 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2105 if (!(wcaps & AC_WCAP_DIGITAL))
2107 if (!(wcaps & AC_WCAP_CONN_LIST))
2109 err = get_connection_index(codec, dig_nid,
2110 spec->autocfg.dig_in_pin);
2112 spec->dig_in_nid = dig_nid;
2126 static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2127 /* Mic-in jack as mic in */
2128 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2129 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2130 /* Line-in jack as Line in */
2131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2133 /* Line-Out as Front */
2134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2141 static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2142 /* Mic-in jack as mic in */
2143 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2144 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2145 /* Line-in jack as Surround */
2146 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2147 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2148 /* Line-Out as Front */
2149 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2156 static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2157 /* Mic-in jack as CLFE */
2158 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2159 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2160 /* Line-in jack as Surround */
2161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2163 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2164 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2171 static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2172 /* Mic-in jack as CLFE */
2173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2175 /* Line-in jack as Surround */
2176 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2177 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2178 /* Line-Out as Side */
2179 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2183 static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2184 { 2, alc888_4ST_ch2_intel_init },
2185 { 4, alc888_4ST_ch4_intel_init },
2186 { 6, alc888_4ST_ch6_intel_init },
2187 { 8, alc888_4ST_ch8_intel_init },
2191 * ALC888 Fujitsu Siemens Amillo xa3530
2194 static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2195 /* Front Mic: set to PIN_IN (empty by default) */
2196 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2197 /* Connect Internal HP to Front */
2198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2200 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2201 /* Connect Bass HP to Front */
2202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2205 /* Connect Line-Out side jack (SPDIF) to Side */
2206 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2207 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2208 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2209 /* Connect Mic jack to CLFE */
2210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2212 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2213 /* Connect Line-in jack to Surround */
2214 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2215 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2216 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2217 /* Connect HP out jack to Front */
2218 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2221 /* Enable unsolicited event for HP jack and Line-out jack */
2222 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2223 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2227 static void alc889_automute_setup(struct hda_codec *codec)
2229 struct alc_spec *spec = codec->spec;
2231 spec->autocfg.hp_pins[0] = 0x15;
2232 spec->autocfg.speaker_pins[0] = 0x14;
2233 spec->autocfg.speaker_pins[1] = 0x16;
2234 spec->autocfg.speaker_pins[2] = 0x17;
2235 spec->autocfg.speaker_pins[3] = 0x19;
2236 spec->autocfg.speaker_pins[4] = 0x1a;
2238 spec->automute_mode = ALC_AUTOMUTE_AMP;
2241 static void alc889_intel_init_hook(struct hda_codec *codec)
2243 alc889_coef_init(codec);
2244 alc_hp_automute(codec);
2247 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2249 struct alc_spec *spec = codec->spec;
2251 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2252 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2253 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2254 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2256 spec->automute_mode = ALC_AUTOMUTE_AMP;
2260 * ALC888 Acer Aspire 4930G model
2263 static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2264 /* Front Mic: set to PIN_IN (empty by default) */
2265 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2266 /* Unselect Front Mic by default in input mixer 3 */
2267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2268 /* Enable unsolicited event for HP jack */
2269 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2270 /* Connect Internal HP to front */
2271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2274 /* Connect HP out to front */
2275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2278 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2283 * ALC888 Acer Aspire 6530G model
2286 static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2287 /* Route to built-in subwoofer as well as speakers */
2288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2290 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2291 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2292 /* Bias voltage on for external mic port */
2293 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2294 /* Front Mic: set to PIN_IN (empty by default) */
2295 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2296 /* Unselect Front Mic by default in input mixer 3 */
2297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2298 /* Enable unsolicited event for HP jack */
2299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2300 /* Enable speaker output */
2301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2302 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2304 /* Enable headphone output */
2305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2313 *ALC888 Acer Aspire 7730G model
2316 static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2317 /* Bias voltage on for external mic port */
2318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2319 /* Front Mic: set to PIN_IN (empty by default) */
2320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2321 /* Unselect Front Mic by default in input mixer 3 */
2322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2323 /* Enable unsolicited event for HP jack */
2324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2325 /* Enable speaker output */
2326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329 /* Enable headphone output */
2330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2333 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2334 /*Enable internal subwoofer */
2335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2338 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2343 * ALC889 Acer Aspire 8930G model
2346 static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2347 /* Front Mic: set to PIN_IN (empty by default) */
2348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2349 /* Unselect Front Mic by default in input mixer 3 */
2350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2351 /* Enable unsolicited event for HP jack */
2352 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2353 /* Connect Internal Front to Front */
2354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2356 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2357 /* Connect Internal Rear to Rear */
2358 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2359 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2360 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2361 /* Connect Internal CLFE to CLFE */
2362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2363 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2365 /* Connect HP out to Front */
2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2369 /* Enable all DACs */
2370 /* DAC DISABLE/MUTE 1? */
2371 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2372 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2373 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2374 /* DAC DISABLE/MUTE 2? */
2375 /* some bit here disables the other DACs. Init=0x4900 */
2376 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2377 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2379 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2380 * which makes the stereo useless. However, either the mic or the ALC889
2381 * makes the signal become a difference/sum signal instead of standard
2382 * stereo, which is annoying. So instead we flip this bit which makes the
2383 * codec replicate the sum signal to both channels, turning it into a
2386 /* DMIC_CONTROL? Init value = 0x0001 */
2387 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2388 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2392 static const struct hda_input_mux alc888_2_capture_sources[2] = {
2393 /* Front mic only available on one ADC */
2400 { "Front Mic", 0xb },
2413 static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2414 /* Interal mic only available on one ADC */
2421 { "Input Mix", 0xa },
2422 { "Internal Mic", 0xb },
2431 { "Input Mix", 0xa },
2436 static const struct hda_input_mux alc889_capture_sources[3] = {
2437 /* Digital mic only available on first "ADC" */
2444 { "Front Mic", 0xb },
2445 { "Input Mix", 0xa },
2454 { "Input Mix", 0xa },
2463 { "Input Mix", 0xa },
2468 static const struct snd_kcontrol_new alc888_base_mixer[] = {
2469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2471 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2472 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2473 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2475 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2490 static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2492 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2494 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2498 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2503 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2504 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2505 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2507 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2512 static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2514 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2516 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2517 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2519 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2521 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2523 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2525 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2526 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2531 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2533 struct alc_spec *spec = codec->spec;
2535 spec->autocfg.hp_pins[0] = 0x15;
2536 spec->autocfg.speaker_pins[0] = 0x14;
2537 spec->autocfg.speaker_pins[1] = 0x16;
2538 spec->autocfg.speaker_pins[2] = 0x17;
2540 spec->automute_mode = ALC_AUTOMUTE_AMP;
2543 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2545 struct alc_spec *spec = codec->spec;
2547 spec->autocfg.hp_pins[0] = 0x15;
2548 spec->autocfg.speaker_pins[0] = 0x14;
2549 spec->autocfg.speaker_pins[1] = 0x16;
2550 spec->autocfg.speaker_pins[2] = 0x17;
2552 spec->automute_mode = ALC_AUTOMUTE_AMP;
2555 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2557 struct alc_spec *spec = codec->spec;
2559 spec->autocfg.hp_pins[0] = 0x15;
2560 spec->autocfg.speaker_pins[0] = 0x14;
2561 spec->autocfg.speaker_pins[1] = 0x16;
2562 spec->autocfg.speaker_pins[2] = 0x17;
2564 spec->automute_mode = ALC_AUTOMUTE_AMP;
2567 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2569 struct alc_spec *spec = codec->spec;
2571 spec->autocfg.hp_pins[0] = 0x15;
2572 spec->autocfg.speaker_pins[0] = 0x14;
2573 spec->autocfg.speaker_pins[1] = 0x16;
2574 spec->autocfg.speaker_pins[2] = 0x1b;
2576 spec->automute_mode = ALC_AUTOMUTE_AMP;
2580 * ALC880 3-stack model
2582 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2583 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2584 * F-Mic = 0x1b, HP = 0x19
2587 static const hda_nid_t alc880_dac_nids[4] = {
2588 /* front, rear, clfe, rear_surr */
2589 0x02, 0x05, 0x04, 0x03
2592 static const hda_nid_t alc880_adc_nids[3] = {
2597 /* The datasheet says the node 0x07 is connected from inputs,
2598 * but it shows zero connection in the real implementation on some devices.
2599 * Note: this is a 915GAV bug, fixed on 915GLV
2601 static const hda_nid_t alc880_adc_nids_alt[2] = {
2606 #define ALC880_DIGOUT_NID 0x06
2607 #define ALC880_DIGIN_NID 0x0a
2609 static const struct hda_input_mux alc880_capture_source = {
2613 { "Front Mic", 0x3 },
2619 /* channel source setting (2/6 channel selection for 3-stack) */
2621 static const struct hda_verb alc880_threestack_ch2_init[] = {
2622 /* set line-in to input, mute it */
2623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2625 /* set mic-in to input vref 80%, mute it */
2626 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2627 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2632 static const struct hda_verb alc880_threestack_ch6_init[] = {
2633 /* set line-in to output, unmute it */
2634 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2635 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2636 /* set mic-in to output, unmute it */
2637 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2638 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2642 static const struct hda_channel_mode alc880_threestack_modes[2] = {
2643 { 2, alc880_threestack_ch2_init },
2644 { 6, alc880_threestack_ch6_init },
2647 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2651 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2653 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2654 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2655 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2656 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2657 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2659 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2667 .name = "Channel Mode",
2668 .info = alc_ch_mode_info,
2669 .get = alc_ch_mode_get,
2670 .put = alc_ch_mode_put,
2675 /* capture mixer elements */
2676 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2677 struct snd_ctl_elem_info *uinfo)
2679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2680 struct alc_spec *spec = codec->spec;
2684 mutex_lock(&codec->control_mutex);
2685 if (spec->vol_in_capsrc)
2686 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2688 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2689 kcontrol->private_value = val;
2690 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2691 mutex_unlock(&codec->control_mutex);
2695 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2696 unsigned int size, unsigned int __user *tlv)
2698 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2699 struct alc_spec *spec = codec->spec;
2703 mutex_lock(&codec->control_mutex);
2704 if (spec->vol_in_capsrc)
2705 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2707 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2708 kcontrol->private_value = val;
2709 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2710 mutex_unlock(&codec->control_mutex);
2714 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2715 struct snd_ctl_elem_value *ucontrol);
2717 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2718 struct snd_ctl_elem_value *ucontrol,
2719 getput_call_t func, bool check_adc_switch)
2721 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2722 struct alc_spec *spec = codec->spec;
2725 mutex_lock(&codec->control_mutex);
2726 if (check_adc_switch && spec->dual_adc_switch) {
2727 for (i = 0; i < spec->num_adc_nids; i++) {
2728 kcontrol->private_value =
2729 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2731 err = func(kcontrol, ucontrol);
2736 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2737 if (spec->vol_in_capsrc)
2738 kcontrol->private_value =
2739 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
2742 kcontrol->private_value =
2743 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2745 err = func(kcontrol, ucontrol);
2748 mutex_unlock(&codec->control_mutex);
2752 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2755 return alc_cap_getput_caller(kcontrol, ucontrol,
2756 snd_hda_mixer_amp_volume_get, false);
2759 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2760 struct snd_ctl_elem_value *ucontrol)
2762 return alc_cap_getput_caller(kcontrol, ucontrol,
2763 snd_hda_mixer_amp_volume_put, true);
2766 /* capture mixer elements */
2767 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2769 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2770 struct snd_ctl_elem_value *ucontrol)
2772 return alc_cap_getput_caller(kcontrol, ucontrol,
2773 snd_hda_mixer_amp_switch_get, false);
2776 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2777 struct snd_ctl_elem_value *ucontrol)
2779 return alc_cap_getput_caller(kcontrol, ucontrol,
2780 snd_hda_mixer_amp_switch_put, true);
2783 #define _DEFINE_CAPMIX(num) \
2785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2786 .name = "Capture Switch", \
2787 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2789 .info = alc_cap_sw_info, \
2790 .get = alc_cap_sw_get, \
2791 .put = alc_cap_sw_put, \
2794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2795 .name = "Capture Volume", \
2796 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2797 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2798 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2800 .info = alc_cap_vol_info, \
2801 .get = alc_cap_vol_get, \
2802 .put = alc_cap_vol_put, \
2803 .tlv = { .c = alc_cap_vol_tlv }, \
2806 #define _DEFINE_CAPSRC(num) \
2808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2809 /* .name = "Capture Source", */ \
2810 .name = "Input Source", \
2812 .info = alc_mux_enum_info, \
2813 .get = alc_mux_enum_get, \
2814 .put = alc_mux_enum_put, \
2817 #define DEFINE_CAPMIX(num) \
2818 static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2819 _DEFINE_CAPMIX(num), \
2820 _DEFINE_CAPSRC(num), \
2824 #define DEFINE_CAPMIX_NOSRC(num) \
2825 static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2826 _DEFINE_CAPMIX(num), \
2830 /* up to three ADCs */
2834 DEFINE_CAPMIX_NOSRC(1);
2835 DEFINE_CAPMIX_NOSRC(2);
2836 DEFINE_CAPMIX_NOSRC(3);
2839 * ALC880 5-stack model
2841 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2843 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2844 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2847 /* additional mixers to alc880_three_stack_mixer */
2848 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2849 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2850 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2854 /* channel source setting (6/8 channel selection for 5-stack) */
2856 static const struct hda_verb alc880_fivestack_ch6_init[] = {
2857 /* set line-in to input, mute it */
2858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2864 static const struct hda_verb alc880_fivestack_ch8_init[] = {
2865 /* set line-in to output, unmute it */
2866 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2867 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2871 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2872 { 6, alc880_fivestack_ch6_init },
2873 { 8, alc880_fivestack_ch8_init },
2878 * ALC880 6-stack model
2880 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2881 * Side = 0x05 (0x0f)
2882 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2883 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2886 static const hda_nid_t alc880_6st_dac_nids[4] = {
2887 /* front, rear, clfe, rear_surr */
2888 0x02, 0x03, 0x04, 0x05
2891 static const struct hda_input_mux alc880_6stack_capture_source = {
2895 { "Front Mic", 0x1 },
2901 /* fixed 8-channels */
2902 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2906 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2907 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2908 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2909 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2910 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2911 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2912 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2913 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2914 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2915 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2916 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2917 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2918 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2923 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2924 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2927 .name = "Channel Mode",
2928 .info = alc_ch_mode_info,
2929 .get = alc_ch_mode_get,
2930 .put = alc_ch_mode_put,
2939 * W810 has rear IO for:
2942 * Center/LFE (DAC 04)
2945 * The system also has a pair of internal speakers, and a headphone jack.
2946 * These are both connected to Line2 on the codec, hence to DAC 02.
2948 * There is a variable resistor to control the speaker or headphone
2949 * volume. This is a hardware-only device without a software API.
2951 * Plugging headphones in will disable the internal speakers. This is
2952 * implemented in hardware, not via the driver using jack sense. In
2953 * a similar fashion, plugging into the rear socket marked "front" will
2954 * disable both the speakers and headphones.
2956 * For input, there's a microphone jack, and an "audio in" jack.
2957 * These may not do anything useful with this driver yet, because I
2958 * haven't setup any initialization verbs for these yet...
2961 static const hda_nid_t alc880_w810_dac_nids[3] = {
2962 /* front, rear/surround, clfe */
2966 /* fixed 6 channels */
2967 static const struct hda_channel_mode alc880_w810_modes[1] = {
2971 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2972 static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2974 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2976 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2977 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2978 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2979 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2980 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2981 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2989 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2990 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2994 static const hda_nid_t alc880_z71v_dac_nids[1] = {
2997 #define ALC880_Z71V_HP_DAC 0x03
2999 /* fixed 2 channels */
3000 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
3004 static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
3005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3006 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3007 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3008 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3009 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3010 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3018 * ALC880 F1734 model
3020 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3021 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3024 static const hda_nid_t alc880_f1734_dac_nids[1] = {
3027 #define ALC880_F1734_HP_DAC 0x02
3029 static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3030 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3031 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3032 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3033 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3037 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3041 static const struct hda_input_mux alc880_f1734_capture_source = {
3053 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3054 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3055 * Mic = 0x18, Line = 0x1a
3058 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3059 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3061 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3063 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3064 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3065 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3066 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3067 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3068 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3069 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3070 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3071 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3072 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3073 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3078 .name = "Channel Mode",
3079 .info = alc_ch_mode_info,
3080 .get = alc_ch_mode_get,
3081 .put = alc_ch_mode_put,
3087 * ALC880 ASUS W1V model
3089 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3090 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3091 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3094 /* additional mixers to alc880_asus_mixer */
3095 static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3096 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3097 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3102 static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3103 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3104 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3105 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3106 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3107 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3111 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3116 static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3117 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3118 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3119 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3120 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3121 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3122 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3123 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3124 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3125 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3126 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3127 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3128 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3132 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3134 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3135 .name = "Channel Mode",
3136 .info = alc_ch_mode_info,
3137 .get = alc_ch_mode_get,
3138 .put = alc_ch_mode_put,
3143 static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3144 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3145 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3146 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3147 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3148 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3149 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3152 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3153 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3157 static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3158 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3159 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3160 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3161 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3168 * virtual master controls
3172 * slave controls for virtual master
3174 static const char * const alc_slave_vols[] = {
3175 "Front Playback Volume",
3176 "Surround Playback Volume",
3177 "Center Playback Volume",
3178 "LFE Playback Volume",
3179 "Side Playback Volume",
3180 "Headphone Playback Volume",
3181 "Speaker Playback Volume",
3182 "Mono Playback Volume",
3183 "Line-Out Playback Volume",
3187 static const char * const alc_slave_sws[] = {
3188 "Front Playback Switch",
3189 "Surround Playback Switch",
3190 "Center Playback Switch",
3191 "LFE Playback Switch",
3192 "Side Playback Switch",
3193 "Headphone Playback Switch",
3194 "Speaker Playback Switch",
3195 "Mono Playback Switch",
3196 "IEC958 Playback Switch",
3197 "Line-Out Playback Switch",
3202 * build control elements
3205 #define NID_MAPPING (-1)
3207 #define SUBDEV_SPEAKER_ (0 << 6)
3208 #define SUBDEV_HP_ (1 << 6)
3209 #define SUBDEV_LINE_ (2 << 6)
3210 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3211 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3212 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3214 static void alc_free_kctls(struct hda_codec *codec);
3216 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3217 /* additional beep mixers; the actual parameters are overwritten at build */
3218 static const struct snd_kcontrol_new alc_beep_mixer[] = {
3219 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3220 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3225 static int alc_build_controls(struct hda_codec *codec)
3227 struct alc_spec *spec = codec->spec;
3228 struct snd_kcontrol *kctl = NULL;
3229 const struct snd_kcontrol_new *knew;
3234 for (i = 0; i < spec->num_mixers; i++) {
3235 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3239 if (spec->cap_mixer) {
3240 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3244 if (spec->multiout.dig_out_nid) {
3245 err = snd_hda_create_spdif_out_ctls(codec,
3246 spec->multiout.dig_out_nid,
3247 spec->multiout.dig_out_nid);
3250 if (!spec->no_analog) {
3251 err = snd_hda_create_spdif_share_sw(codec,
3255 spec->multiout.share_spdif = 1;
3258 if (spec->dig_in_nid) {
3259 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3264 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3265 /* create beep controls if needed */
3266 if (spec->beep_amp) {
3267 const struct snd_kcontrol_new *knew;
3268 for (knew = alc_beep_mixer; knew->name; knew++) {
3269 struct snd_kcontrol *kctl;
3270 kctl = snd_ctl_new1(knew, codec);
3273 kctl->private_value = spec->beep_amp;
3274 err = snd_hda_ctl_add(codec, 0, kctl);
3281 /* if we have no master control, let's create it */
3282 if (!spec->no_analog &&
3283 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3284 unsigned int vmaster_tlv[4];
3285 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3286 HDA_OUTPUT, vmaster_tlv);
3287 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3288 vmaster_tlv, alc_slave_vols);
3292 if (!spec->no_analog &&
3293 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3294 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3295 NULL, alc_slave_sws);
3300 /* assign Capture Source enums to NID */
3301 if (spec->capsrc_nids || spec->adc_nids) {
3302 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3304 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3305 for (i = 0; kctl && i < kctl->count; i++) {
3306 const hda_nid_t *nids = spec->capsrc_nids;
3308 nids = spec->adc_nids;
3309 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3314 if (spec->cap_mixer) {
3315 const char *kname = kctl ? kctl->id.name : NULL;
3316 for (knew = spec->cap_mixer; knew->name; knew++) {
3317 if (kname && strcmp(knew->name, kname) == 0)
3319 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3320 for (i = 0; kctl && i < kctl->count; i++) {
3321 err = snd_hda_add_nid(codec, kctl, i,
3329 /* other nid->control mapping */
3330 for (i = 0; i < spec->num_mixers; i++) {
3331 for (knew = spec->mixers[i]; knew->name; knew++) {
3332 if (knew->iface != NID_MAPPING)
3334 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3337 u = knew->subdevice;
3338 for (j = 0; j < 4; j++, u >>= 8) {
3343 case SUBDEV_SPEAKER_:
3344 nid = spec->autocfg.speaker_pins[nid];
3347 nid = spec->autocfg.line_out_pins[nid];
3350 nid = spec->autocfg.hp_pins[nid];
3355 err = snd_hda_add_nid(codec, kctl, 0, nid);
3359 u = knew->private_value;
3360 for (j = 0; j < 4; j++, u >>= 8) {
3364 err = snd_hda_add_nid(codec, kctl, 0, nid);
3371 alc_free_kctls(codec); /* no longer needed */
3378 * initialize the codec volumes, etc
3382 * generic initialization of ADC, input mixers and output mixers
3384 static const struct hda_verb alc880_volume_init_verbs[] = {
3386 * Unmute ADC0-2 and set the default input to mic-in
3388 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3390 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3392 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3395 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3397 * Note: PASD motherboards uses the Line In 2 as the input for front
3400 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3410 * Set up output mixers (0x0c - 0x0f)
3412 /* set vol=0 to output mixers */
3413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3415 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3417 /* set up input amps for analog loopback */
3418 /* Amp Indices: DAC = 0, mixer = 1 */
3419 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3432 * 3-stack pin configuration:
3433 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3435 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3437 * preset connection lists of input pins
3438 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3440 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3441 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3442 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3445 * Set pin mode and muting
3447 /* set front pin widgets 0x14 for output */
3448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3450 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3453 /* Mic2 (as headphone out) for HP output */
3454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3456 /* Line In pin widget for input */
3457 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3459 /* Line2 (as front mic) pin widget for input and vref at 80% */
3460 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3461 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3462 /* CD pin widget for input */
3463 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3469 * 5-stack pin configuration:
3470 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3471 * line-in/side = 0x1a, f-mic = 0x1b
3473 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3475 * preset connection lists of input pins
3476 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3478 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3479 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3482 * Set pin mode and muting
3484 /* set pin widgets 0x14-0x17 for output */
3485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3488 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3489 /* unmute pins for output (no gain on this amp) */
3490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3491 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3495 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3496 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3498 /* Mic2 (as headphone out) for HP output */
3499 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3500 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 /* Line In pin widget for input */
3502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3504 /* Line2 (as front mic) pin widget for input and vref at 80% */
3505 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3506 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3507 /* CD pin widget for input */
3508 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3514 * W810 pin configuration:
3515 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3517 static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3518 /* hphone/speaker input selector: front DAC */
3519 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3524 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3525 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3526 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3528 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3529 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3535 * Z71V pin configuration:
3536 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3538 static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3553 * 6-stack pin configuration:
3554 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3555 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3557 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3558 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3562 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3564 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3566 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3567 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3573 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3574 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3576 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3583 * Uniwill pin configuration:
3584 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3587 static const struct hda_verb alc880_uniwill_init_verbs[] = {
3588 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3591 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3595 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3596 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3600 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3601 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3605 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3606 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3608 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3609 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3610 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3611 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3612 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3613 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3616 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3623 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3625 static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3626 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3628 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3629 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3630 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3632 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3633 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3637 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3638 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3639 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3641 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3643 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3648 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3649 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3654 static const struct hda_verb alc880_beep_init_verbs[] = {
3655 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3659 /* auto-toggle front mic */
3660 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3662 unsigned int present;
3665 present = snd_hda_jack_detect(codec, 0x18);
3666 bits = present ? HDA_AMP_MUTE : 0;
3667 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3670 static void alc880_uniwill_setup(struct hda_codec *codec)
3672 struct alc_spec *spec = codec->spec;
3674 spec->autocfg.hp_pins[0] = 0x14;
3675 spec->autocfg.speaker_pins[0] = 0x15;
3676 spec->autocfg.speaker_pins[0] = 0x16;
3678 spec->automute_mode = ALC_AUTOMUTE_AMP;
3681 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3683 alc_hp_automute(codec);
3684 alc88x_simple_mic_automute(codec);
3687 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3690 /* Looks like the unsol event is incompatible with the standard
3691 * definition. 4bit tag is placed at 28 bit!
3693 switch (res >> 28) {
3694 case ALC880_MIC_EVENT:
3695 alc88x_simple_mic_automute(codec);
3698 alc_sku_unsol_event(codec, res);
3703 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3705 struct alc_spec *spec = codec->spec;
3707 spec->autocfg.hp_pins[0] = 0x14;
3708 spec->autocfg.speaker_pins[0] = 0x15;
3710 spec->automute_mode = ALC_AUTOMUTE_AMP;
3713 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3715 unsigned int present;
3717 present = snd_hda_codec_read(codec, 0x21, 0,
3718 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3719 present &= HDA_AMP_VOLMASK;
3720 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3721 HDA_AMP_VOLMASK, present);
3722 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3723 HDA_AMP_VOLMASK, present);
3726 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3729 /* Looks like the unsol event is incompatible with the standard
3730 * definition. 4bit tag is placed at 28 bit!
3732 if ((res >> 28) == ALC880_DCVOL_EVENT)
3733 alc880_uniwill_p53_dcvol_automute(codec);
3735 alc_sku_unsol_event(codec, res);
3739 * F1734 pin configuration:
3740 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3742 static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3743 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3744 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3745 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3746 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3747 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3749 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3750 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3754 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3755 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3761 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3762 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3764 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3765 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3771 * ASUS pin configuration:
3772 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3774 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3775 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3776 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3777 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3778 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3781 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3784 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3786 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3790 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3791 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3793 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3802 /* Enable GPIO mask and set output */
3803 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3804 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3805 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3807 /* Clevo m520g init */
3808 static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3809 /* headphone output */
3810 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3813 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3818 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3819 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3820 /* Mic1 (rear panel) */
3821 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3823 /* Mic2 (front panel) */
3824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3827 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3828 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3829 /* change to EAPD mode */
3830 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3831 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3836 static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3837 /* change to EAPD mode */
3838 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3839 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3841 /* Headphone output */
3842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3844 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3845 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3847 /* Line In pin widget for input */
3848 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3849 /* CD pin widget for input */
3850 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3851 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3852 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3854 /* change to EAPD mode */
3855 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3856 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3862 * LG m1 express dual
3865 * Rear Line-In/Out (blue): 0x14
3866 * Build-in Mic-In: 0x15
3868 * HP-Out (green): 0x1b
3869 * Mic-In/Out (red): 0x19
3873 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3874 static const hda_nid_t alc880_lg_dac_nids[3] = {
3878 /* seems analog CD is not working */
3879 static const struct hda_input_mux alc880_lg_capture_source = {
3884 { "Internal Mic", 0x6 },
3888 /* 2,4,6 channel modes */
3889 static const struct hda_verb alc880_lg_ch2_init[] = {
3890 /* set line-in and mic-in to input */
3891 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3892 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3896 static const struct hda_verb alc880_lg_ch4_init[] = {
3897 /* set line-in to out and mic-in to input */
3898 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3899 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3903 static const struct hda_verb alc880_lg_ch6_init[] = {
3904 /* set line-in and mic-in to output */
3905 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3906 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3910 static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3911 { 2, alc880_lg_ch2_init },
3912 { 4, alc880_lg_ch4_init },
3913 { 6, alc880_lg_ch6_init },
3916 static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3918 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3919 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3920 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3921 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3922 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3923 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3924 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3927 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3928 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3929 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3930 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3933 .name = "Channel Mode",
3934 .info = alc_ch_mode_info,
3935 .get = alc_ch_mode_get,
3936 .put = alc_ch_mode_put,
3941 static const struct hda_verb alc880_lg_init_verbs[] = {
3942 /* set capture source to mic-in */
3943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3944 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3945 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3946 /* mute all amp mixer inputs */
3947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3950 /* line-in to input */
3951 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3952 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3957 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3958 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3959 /* mic-in to input */
3960 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3961 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3962 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3964 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3965 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3966 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3968 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3972 /* toggle speaker-output according to the hp-jack state */
3973 static void alc880_lg_setup(struct hda_codec *codec)
3975 struct alc_spec *spec = codec->spec;
3977 spec->autocfg.hp_pins[0] = 0x1b;
3978 spec->autocfg.speaker_pins[0] = 0x17;
3980 spec->automute_mode = ALC_AUTOMUTE_AMP;
3989 * Built-in Mic-In: 0x19
3995 static const struct hda_input_mux alc880_lg_lw_capture_source = {
3999 { "Internal Mic", 0x1 },
4004 #define alc880_lg_lw_modes alc880_threestack_modes
4006 static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4009 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4010 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4011 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4012 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4013 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4014 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4015 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4016 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4019 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4020 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4023 .name = "Channel Mode",
4024 .info = alc_ch_mode_info,
4025 .get = alc_ch_mode_get,
4026 .put = alc_ch_mode_put,
4031 static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4032 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4033 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4034 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4036 /* set capture source to mic-in */
4037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4039 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4042 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4043 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4045 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4046 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4047 /* mic-in to input */
4048 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4049 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4051 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4052 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4054 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4058 /* toggle speaker-output according to the hp-jack state */
4059 static void alc880_lg_lw_setup(struct hda_codec *codec)
4061 struct alc_spec *spec = codec->spec;
4063 spec->autocfg.hp_pins[0] = 0x1b;
4064 spec->autocfg.speaker_pins[0] = 0x14;
4066 spec->automute_mode = ALC_AUTOMUTE_AMP;
4069 static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4070 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4071 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4074 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4075 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4079 static const struct hda_input_mux alc880_medion_rim_capture_source = {
4083 { "Internal Mic", 0x1 },
4087 static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4088 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4093 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4096 /* Mic2 (as headphone out) for HP output */
4097 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4099 /* Internal Speaker */
4100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4101 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4103 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4104 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4106 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4110 /* toggle speaker-output according to the hp-jack state */
4111 static void alc880_medion_rim_automute(struct hda_codec *codec)
4113 struct alc_spec *spec = codec->spec;
4114 alc_hp_automute(codec);
4116 if (spec->jack_present)
4117 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4119 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4122 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4125 /* Looks like the unsol event is incompatible with the standard
4126 * definition. 4bit tag is placed at 28 bit!
4128 if ((res >> 28) == ALC880_HP_EVENT)
4129 alc880_medion_rim_automute(codec);
4132 static void alc880_medion_rim_setup(struct hda_codec *codec)
4134 struct alc_spec *spec = codec->spec;
4136 spec->autocfg.hp_pins[0] = 0x14;
4137 spec->autocfg.speaker_pins[0] = 0x1b;
4139 spec->automute_mode = ALC_AUTOMUTE_AMP;
4142 #ifdef CONFIG_SND_HDA_POWER_SAVE
4143 static const struct hda_amp_list alc880_loopbacks[] = {
4144 { 0x0b, HDA_INPUT, 0 },
4145 { 0x0b, HDA_INPUT, 1 },
4146 { 0x0b, HDA_INPUT, 2 },
4147 { 0x0b, HDA_INPUT, 3 },
4148 { 0x0b, HDA_INPUT, 4 },
4152 static const struct hda_amp_list alc880_lg_loopbacks[] = {
4153 { 0x0b, HDA_INPUT, 1 },
4154 { 0x0b, HDA_INPUT, 6 },
4155 { 0x0b, HDA_INPUT, 7 },
4164 static void alc_init_special_input_src(struct hda_codec *codec);
4166 static int alc_init(struct hda_codec *codec)
4168 struct alc_spec *spec = codec->spec;
4172 alc_auto_init_amp(codec, spec->init_amp);
4174 for (i = 0; i < spec->num_init_verbs; i++)
4175 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4176 alc_init_special_input_src(codec);
4178 if (spec->init_hook)
4179 spec->init_hook(codec);
4181 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4183 hda_call_check_power_status(codec, 0x01);
4187 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4189 struct alc_spec *spec = codec->spec;
4191 if (spec->unsol_event)
4192 spec->unsol_event(codec, res);
4195 #ifdef CONFIG_SND_HDA_POWER_SAVE
4196 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4198 struct alc_spec *spec = codec->spec;
4199 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4204 * Analog playback callbacks
4206 static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
4207 struct hda_codec *codec,
4208 struct snd_pcm_substream *substream)
4210 struct alc_spec *spec = codec->spec;
4211 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4215 static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4216 struct hda_codec *codec,
4217 unsigned int stream_tag,
4218 unsigned int format,
4219 struct snd_pcm_substream *substream)
4221 struct alc_spec *spec = codec->spec;
4222 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4223 stream_tag, format, substream);
4226 static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4227 struct hda_codec *codec,
4228 struct snd_pcm_substream *substream)
4230 struct alc_spec *spec = codec->spec;
4231 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4237 static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4238 struct hda_codec *codec,
4239 struct snd_pcm_substream *substream)
4241 struct alc_spec *spec = codec->spec;
4242 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4245 static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4246 struct hda_codec *codec,
4247 unsigned int stream_tag,
4248 unsigned int format,
4249 struct snd_pcm_substream *substream)
4251 struct alc_spec *spec = codec->spec;
4252 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4253 stream_tag, format, substream);
4256 static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4257 struct hda_codec *codec,
4258 struct snd_pcm_substream *substream)
4260 struct alc_spec *spec = codec->spec;
4261 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4264 static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4265 struct hda_codec *codec,
4266 struct snd_pcm_substream *substream)
4268 struct alc_spec *spec = codec->spec;
4269 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4275 static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4276 struct hda_codec *codec,
4277 unsigned int stream_tag,
4278 unsigned int format,
4279 struct snd_pcm_substream *substream)
4281 struct alc_spec *spec = codec->spec;
4283 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4284 stream_tag, 0, format);
4288 static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4289 struct hda_codec *codec,
4290 struct snd_pcm_substream *substream)
4292 struct alc_spec *spec = codec->spec;
4294 snd_hda_codec_cleanup_stream(codec,
4295 spec->adc_nids[substream->number + 1]);
4299 /* analog capture with dynamic dual-adc changes */
4300 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4301 struct hda_codec *codec,
4302 unsigned int stream_tag,
4303 unsigned int format,
4304 struct snd_pcm_substream *substream)
4306 struct alc_spec *spec = codec->spec;
4307 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4308 spec->cur_adc_stream_tag = stream_tag;
4309 spec->cur_adc_format = format;
4310 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4314 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4315 struct hda_codec *codec,
4316 struct snd_pcm_substream *substream)
4318 struct alc_spec *spec = codec->spec;
4319 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4324 static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4328 .nid = 0, /* fill later */
4330 .prepare = dualmic_capture_pcm_prepare,
4331 .cleanup = dualmic_capture_pcm_cleanup
4337 static const struct hda_pcm_stream alc_pcm_analog_playback = {
4341 /* NID is set in alc_build_pcms */
4343 .open = alc_playback_pcm_open,
4344 .prepare = alc_playback_pcm_prepare,
4345 .cleanup = alc_playback_pcm_cleanup
4349 static const struct hda_pcm_stream alc_pcm_analog_capture = {
4353 /* NID is set in alc_build_pcms */
4356 static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
4360 /* NID is set in alc_build_pcms */
4363 static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
4364 .substreams = 2, /* can be overridden */
4367 /* NID is set in alc_build_pcms */
4369 .prepare = alc_alt_capture_pcm_prepare,
4370 .cleanup = alc_alt_capture_pcm_cleanup
4374 static const struct hda_pcm_stream alc_pcm_digital_playback = {
4378 /* NID is set in alc_build_pcms */
4380 .open = alc_dig_playback_pcm_open,
4381 .close = alc_dig_playback_pcm_close,
4382 .prepare = alc_dig_playback_pcm_prepare,
4383 .cleanup = alc_dig_playback_pcm_cleanup
4387 static const struct hda_pcm_stream alc_pcm_digital_capture = {
4391 /* NID is set in alc_build_pcms */
4394 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4395 static const struct hda_pcm_stream alc_pcm_null_stream = {
4401 static int alc_build_pcms(struct hda_codec *codec)
4403 struct alc_spec *spec = codec->spec;
4404 struct hda_pcm *info = spec->pcm_rec;
4405 const struct hda_pcm_stream *p;
4408 codec->num_pcms = 1;
4409 codec->pcm_info = info;
4411 if (spec->no_analog)
4414 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4415 "%s Analog", codec->chip_name);
4416 info->name = spec->stream_name_analog;
4418 if (spec->multiout.dac_nids > 0) {
4419 p = spec->stream_analog_playback;
4421 p = &alc_pcm_analog_playback;
4422 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4423 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4425 if (spec->adc_nids) {
4426 p = spec->stream_analog_capture;
4428 p = &alc_pcm_analog_capture;
4429 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4430 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4433 if (spec->channel_mode) {
4434 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4435 for (i = 0; i < spec->num_channel_mode; i++) {
4436 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4437 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4443 /* SPDIF for stream index #1 */
4444 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4445 snprintf(spec->stream_name_digital,
4446 sizeof(spec->stream_name_digital),
4447 "%s Digital", codec->chip_name);
4448 codec->num_pcms = 2;
4449 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4450 info = spec->pcm_rec + 1;
4451 info->name = spec->stream_name_digital;
4452 if (spec->dig_out_type)
4453 info->pcm_type = spec->dig_out_type;
4455 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4456 if (spec->multiout.dig_out_nid) {
4457 p = spec->stream_digital_playback;
4459 p = &alc_pcm_digital_playback;
4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4461 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4463 if (spec->dig_in_nid) {
4464 p = spec->stream_digital_capture;
4466 p = &alc_pcm_digital_capture;
4467 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4468 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4470 /* FIXME: do we need this for all Realtek codec models? */
4471 codec->spdif_status_reset = 1;
4474 if (spec->no_analog)
4477 /* If the use of more than one ADC is requested for the current
4478 * model, configure a second analog capture-only PCM.
4480 /* Additional Analaog capture for index #2 */
4481 if (spec->alt_dac_nid || spec->num_adc_nids > 1) {
4482 codec->num_pcms = 3;
4483 info = spec->pcm_rec + 2;
4484 info->name = spec->stream_name_analog;
4485 if (spec->alt_dac_nid) {
4486 p = spec->stream_analog_alt_playback;
4488 p = &alc_pcm_analog_alt_playback;
4489 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4490 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4493 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4494 alc_pcm_null_stream;
4495 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4497 if (spec->num_adc_nids > 1) {
4498 p = spec->stream_analog_alt_capture;
4500 p = &alc_pcm_analog_alt_capture;
4501 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4502 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4504 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4505 spec->num_adc_nids - 1;
4507 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4508 alc_pcm_null_stream;
4509 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4516 static inline void alc_shutup(struct hda_codec *codec)
4518 struct alc_spec *spec = codec->spec;
4520 if (spec && spec->shutup)
4521 spec->shutup(codec);
4522 snd_hda_shutup_pins(codec);
4525 static void alc_free_kctls(struct hda_codec *codec)
4527 struct alc_spec *spec = codec->spec;
4529 if (spec->kctls.list) {
4530 struct snd_kcontrol_new *kctl = spec->kctls.list;
4532 for (i = 0; i < spec->kctls.used; i++)
4533 kfree(kctl[i].name);
4535 snd_array_free(&spec->kctls);
4538 static void alc_free(struct hda_codec *codec)
4540 struct alc_spec *spec = codec->spec;
4546 snd_hda_input_jack_free(codec);
4547 alc_free_kctls(codec);
4549 snd_hda_detach_beep_device(codec);
4552 #ifdef CONFIG_SND_HDA_POWER_SAVE
4553 static void alc_power_eapd(struct hda_codec *codec)
4555 alc_auto_setup_eapd(codec, false);
4558 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4560 struct alc_spec *spec = codec->spec;
4562 if (spec && spec->power_hook)
4563 spec->power_hook(codec);
4568 #ifdef SND_HDA_NEEDS_RESUME
4569 static int alc_resume(struct hda_codec *codec)
4571 msleep(150); /* to avoid pop noise */
4572 codec->patch_ops.init(codec);
4573 snd_hda_codec_resume_amp(codec);
4574 snd_hda_codec_resume_cache(codec);
4575 hda_call_check_power_status(codec, 0x01);
4582 static const struct hda_codec_ops alc_patch_ops = {
4583 .build_controls = alc_build_controls,
4584 .build_pcms = alc_build_pcms,
4587 .unsol_event = alc_unsol_event,
4588 #ifdef SND_HDA_NEEDS_RESUME
4589 .resume = alc_resume,
4591 #ifdef CONFIG_SND_HDA_POWER_SAVE
4592 .suspend = alc_suspend,
4593 .check_power_status = alc_check_power_status,
4595 .reboot_notify = alc_shutup,
4598 /* replace the codec chip_name with the given string */
4599 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4601 kfree(codec->chip_name);
4602 codec->chip_name = kstrdup(name, GFP_KERNEL);
4603 if (!codec->chip_name) {
4611 * Test configuration for debugging
4613 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4616 #ifdef CONFIG_SND_DEBUG
4617 static const hda_nid_t alc880_test_dac_nids[4] = {
4618 0x02, 0x03, 0x04, 0x05
4621 static const struct hda_input_mux alc880_test_capture_source = {
4630 { "Surround", 0x6 },
4634 static const struct hda_channel_mode alc880_test_modes[4] = {
4641 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4642 struct snd_ctl_elem_info *uinfo)
4644 static const char * const texts[] = {
4645 "N/A", "Line Out", "HP Out",
4646 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4648 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4650 uinfo->value.enumerated.items = 8;
4651 if (uinfo->value.enumerated.item >= 8)
4652 uinfo->value.enumerated.item = 7;
4653 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4657 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4662 unsigned int pin_ctl, item = 0;
4664 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4665 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4666 if (pin_ctl & AC_PINCTL_OUT_EN) {
4667 if (pin_ctl & AC_PINCTL_HP_EN)
4671 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4672 switch (pin_ctl & AC_PINCTL_VREFEN) {
4673 case AC_PINCTL_VREF_HIZ: item = 3; break;
4674 case AC_PINCTL_VREF_50: item = 4; break;
4675 case AC_PINCTL_VREF_GRD: item = 5; break;
4676 case AC_PINCTL_VREF_80: item = 6; break;
4677 case AC_PINCTL_VREF_100: item = 7; break;
4680 ucontrol->value.enumerated.item[0] = item;
4684 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4685 struct snd_ctl_elem_value *ucontrol)
4687 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4688 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4689 static const unsigned int ctls[] = {
4690 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4691 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4692 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4693 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4694 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4695 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4697 unsigned int old_ctl, new_ctl;
4699 old_ctl = snd_hda_codec_read(codec, nid, 0,
4700 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4701 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4702 if (old_ctl != new_ctl) {
4704 snd_hda_codec_write_cache(codec, nid, 0,
4705 AC_VERB_SET_PIN_WIDGET_CONTROL,
4707 val = ucontrol->value.enumerated.item[0] >= 3 ?
4709 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4716 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4717 struct snd_ctl_elem_info *uinfo)
4719 static const char * const texts[] = {
4720 "Front", "Surround", "CLFE", "Side"
4722 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4724 uinfo->value.enumerated.items = 4;
4725 if (uinfo->value.enumerated.item >= 4)
4726 uinfo->value.enumerated.item = 3;
4727 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4731 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4732 struct snd_ctl_elem_value *ucontrol)
4734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4735 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4738 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4739 ucontrol->value.enumerated.item[0] = sel & 3;
4743 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4744 struct snd_ctl_elem_value *ucontrol)
4746 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4747 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4750 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4751 if (ucontrol->value.enumerated.item[0] != sel) {
4752 sel = ucontrol->value.enumerated.item[0] & 3;
4753 snd_hda_codec_write_cache(codec, nid, 0,
4754 AC_VERB_SET_CONNECT_SEL, sel);
4760 #define PIN_CTL_TEST(xname,nid) { \
4761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4763 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4764 .info = alc_test_pin_ctl_info, \
4765 .get = alc_test_pin_ctl_get, \
4766 .put = alc_test_pin_ctl_put, \
4767 .private_value = nid \
4770 #define PIN_SRC_TEST(xname,nid) { \
4771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4773 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4774 .info = alc_test_pin_src_info, \
4775 .get = alc_test_pin_src_get, \
4776 .put = alc_test_pin_src_put, \
4777 .private_value = nid \
4780 static const struct snd_kcontrol_new alc880_test_mixer[] = {
4781 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4782 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4783 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4784 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4785 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4786 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4787 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4788 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4789 PIN_CTL_TEST("Front Pin Mode", 0x14),
4790 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4791 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4792 PIN_CTL_TEST("Side Pin Mode", 0x17),
4793 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4794 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4795 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4796 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4797 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4798 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4799 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4800 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4801 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4802 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4803 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4804 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4805 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4806 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4807 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4808 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4809 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4810 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4813 .name = "Channel Mode",
4814 .info = alc_ch_mode_info,
4815 .get = alc_ch_mode_get,
4816 .put = alc_ch_mode_put,
4821 static const struct hda_verb alc880_test_init_verbs[] = {
4822 /* Unmute inputs of 0x0c - 0x0f */
4823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4824 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4825 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4826 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4827 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4828 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4829 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4830 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4831 /* Vol output for 0x0c-0x0f */
4832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4833 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4834 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4836 /* Set output pins 0x14-0x17 */
4837 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4838 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4839 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4840 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4841 /* Unmute output pins 0x14-0x17 */
4842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4844 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4845 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4846 /* Set input pins 0x18-0x1c */
4847 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4848 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4849 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4850 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4851 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4852 /* Mute input pins 0x18-0x1b */
4853 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4854 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4856 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4859 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4861 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4862 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4863 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4864 /* Analog input/passthru */
4865 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4866 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4867 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4868 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4869 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4877 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4878 [ALC880_3ST] = "3stack",
4879 [ALC880_TCL_S700] = "tcl",
4880 [ALC880_3ST_DIG] = "3stack-digout",
4881 [ALC880_CLEVO] = "clevo",
4882 [ALC880_5ST] = "5stack",
4883 [ALC880_5ST_DIG] = "5stack-digout",
4884 [ALC880_W810] = "w810",
4885 [ALC880_Z71V] = "z71v",
4886 [ALC880_6ST] = "6stack",
4887 [ALC880_6ST_DIG] = "6stack-digout",
4888 [ALC880_ASUS] = "asus",
4889 [ALC880_ASUS_W1V] = "asus-w1v",
4890 [ALC880_ASUS_DIG] = "asus-dig",
4891 [ALC880_ASUS_DIG2] = "asus-dig2",
4892 [ALC880_UNIWILL_DIG] = "uniwill",
4893 [ALC880_UNIWILL_P53] = "uniwill-p53",
4894 [ALC880_FUJITSU] = "fujitsu",
4895 [ALC880_F1734] = "F1734",
4897 [ALC880_LG_LW] = "lg-lw",
4898 [ALC880_MEDION_RIM] = "medion",
4899 #ifdef CONFIG_SND_DEBUG
4900 [ALC880_TEST] = "test",
4902 [ALC880_AUTO] = "auto",
4905 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4906 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4907 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4908 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4909 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4910 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4911 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4912 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4913 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4914 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4915 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4916 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4917 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4918 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4919 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4920 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4921 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4922 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4923 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4924 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4925 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4926 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4927 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4928 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4929 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4930 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4931 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4932 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4933 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4934 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4935 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4936 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4937 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4938 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4939 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4940 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4941 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4942 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4943 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4944 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4945 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4946 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4947 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4948 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4949 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4950 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4951 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4952 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4953 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4954 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4955 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4956 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4957 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4958 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4959 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4960 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4961 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4962 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4963 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4964 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4965 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4966 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4967 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4968 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4969 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4970 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4971 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4972 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4973 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4975 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4976 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4977 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4982 * ALC880 codec presets
4984 static const struct alc_config_preset alc880_presets[] = {
4986 .mixers = { alc880_three_stack_mixer },
4987 .init_verbs = { alc880_volume_init_verbs,
4988 alc880_pin_3stack_init_verbs },
4989 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4990 .dac_nids = alc880_dac_nids,
4991 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4992 .channel_mode = alc880_threestack_modes,
4994 .input_mux = &alc880_capture_source,
4996 [ALC880_3ST_DIG] = {
4997 .mixers = { alc880_three_stack_mixer },
4998 .init_verbs = { alc880_volume_init_verbs,
4999 alc880_pin_3stack_init_verbs },
5000 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5001 .dac_nids = alc880_dac_nids,
5002 .dig_out_nid = ALC880_DIGOUT_NID,
5003 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5004 .channel_mode = alc880_threestack_modes,
5006 .input_mux = &alc880_capture_source,
5008 [ALC880_TCL_S700] = {
5009 .mixers = { alc880_tcl_s700_mixer },
5010 .init_verbs = { alc880_volume_init_verbs,
5011 alc880_pin_tcl_S700_init_verbs,
5012 alc880_gpio2_init_verbs },
5013 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5014 .dac_nids = alc880_dac_nids,
5015 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5016 .num_adc_nids = 1, /* single ADC */
5018 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5019 .channel_mode = alc880_2_jack_modes,
5020 .input_mux = &alc880_capture_source,
5023 .mixers = { alc880_three_stack_mixer,
5024 alc880_five_stack_mixer},
5025 .init_verbs = { alc880_volume_init_verbs,
5026 alc880_pin_5stack_init_verbs },
5027 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5028 .dac_nids = alc880_dac_nids,
5029 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5030 .channel_mode = alc880_fivestack_modes,
5031 .input_mux = &alc880_capture_source,
5033 [ALC880_5ST_DIG] = {
5034 .mixers = { alc880_three_stack_mixer,
5035 alc880_five_stack_mixer },
5036 .init_verbs = { alc880_volume_init_verbs,
5037 alc880_pin_5stack_init_verbs },
5038 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5039 .dac_nids = alc880_dac_nids,
5040 .dig_out_nid = ALC880_DIGOUT_NID,
5041 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5042 .channel_mode = alc880_fivestack_modes,
5043 .input_mux = &alc880_capture_source,
5046 .mixers = { alc880_six_stack_mixer },
5047 .init_verbs = { alc880_volume_init_verbs,
5048 alc880_pin_6stack_init_verbs },
5049 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5050 .dac_nids = alc880_6st_dac_nids,
5051 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5052 .channel_mode = alc880_sixstack_modes,
5053 .input_mux = &alc880_6stack_capture_source,
5055 [ALC880_6ST_DIG] = {
5056 .mixers = { alc880_six_stack_mixer },
5057 .init_verbs = { alc880_volume_init_verbs,
5058 alc880_pin_6stack_init_verbs },
5059 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5060 .dac_nids = alc880_6st_dac_nids,
5061 .dig_out_nid = ALC880_DIGOUT_NID,
5062 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5063 .channel_mode = alc880_sixstack_modes,
5064 .input_mux = &alc880_6stack_capture_source,
5067 .mixers = { alc880_w810_base_mixer },
5068 .init_verbs = { alc880_volume_init_verbs,
5069 alc880_pin_w810_init_verbs,
5070 alc880_gpio2_init_verbs },
5071 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5072 .dac_nids = alc880_w810_dac_nids,
5073 .dig_out_nid = ALC880_DIGOUT_NID,
5074 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5075 .channel_mode = alc880_w810_modes,
5076 .input_mux = &alc880_capture_source,
5079 .mixers = { alc880_z71v_mixer },
5080 .init_verbs = { alc880_volume_init_verbs,
5081 alc880_pin_z71v_init_verbs },
5082 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5083 .dac_nids = alc880_z71v_dac_nids,
5084 .dig_out_nid = ALC880_DIGOUT_NID,
5086 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5087 .channel_mode = alc880_2_jack_modes,
5088 .input_mux = &alc880_capture_source,
5091 .mixers = { alc880_f1734_mixer },
5092 .init_verbs = { alc880_volume_init_verbs,
5093 alc880_pin_f1734_init_verbs },
5094 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5095 .dac_nids = alc880_f1734_dac_nids,
5097 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5098 .channel_mode = alc880_2_jack_modes,
5099 .input_mux = &alc880_f1734_capture_source,
5100 .unsol_event = alc880_uniwill_p53_unsol_event,
5101 .setup = alc880_uniwill_p53_setup,
5102 .init_hook = alc_hp_automute,
5105 .mixers = { alc880_asus_mixer },
5106 .init_verbs = { alc880_volume_init_verbs,
5107 alc880_pin_asus_init_verbs,
5108 alc880_gpio1_init_verbs },
5109 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5110 .dac_nids = alc880_asus_dac_nids,
5111 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5112 .channel_mode = alc880_asus_modes,
5114 .input_mux = &alc880_capture_source,
5116 [ALC880_ASUS_DIG] = {
5117 .mixers = { alc880_asus_mixer },
5118 .init_verbs = { alc880_volume_init_verbs,
5119 alc880_pin_asus_init_verbs,
5120 alc880_gpio1_init_verbs },
5121 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5122 .dac_nids = alc880_asus_dac_nids,
5123 .dig_out_nid = ALC880_DIGOUT_NID,
5124 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5125 .channel_mode = alc880_asus_modes,
5127 .input_mux = &alc880_capture_source,
5129 [ALC880_ASUS_DIG2] = {
5130 .mixers = { alc880_asus_mixer },
5131 .init_verbs = { alc880_volume_init_verbs,
5132 alc880_pin_asus_init_verbs,
5133 alc880_gpio2_init_verbs }, /* use GPIO2 */
5134 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5135 .dac_nids = alc880_asus_dac_nids,
5136 .dig_out_nid = ALC880_DIGOUT_NID,
5137 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5138 .channel_mode = alc880_asus_modes,
5140 .input_mux = &alc880_capture_source,
5142 [ALC880_ASUS_W1V] = {
5143 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5144 .init_verbs = { alc880_volume_init_verbs,
5145 alc880_pin_asus_init_verbs,
5146 alc880_gpio1_init_verbs },
5147 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5148 .dac_nids = alc880_asus_dac_nids,
5149 .dig_out_nid = ALC880_DIGOUT_NID,
5150 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5151 .channel_mode = alc880_asus_modes,
5153 .input_mux = &alc880_capture_source,
5155 [ALC880_UNIWILL_DIG] = {
5156 .mixers = { alc880_asus_mixer },
5157 .init_verbs = { alc880_volume_init_verbs,
5158 alc880_pin_asus_init_verbs },
5159 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5160 .dac_nids = alc880_asus_dac_nids,
5161 .dig_out_nid = ALC880_DIGOUT_NID,
5162 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5163 .channel_mode = alc880_asus_modes,
5165 .input_mux = &alc880_capture_source,
5167 [ALC880_UNIWILL] = {
5168 .mixers = { alc880_uniwill_mixer },
5169 .init_verbs = { alc880_volume_init_verbs,
5170 alc880_uniwill_init_verbs },
5171 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5172 .dac_nids = alc880_asus_dac_nids,
5173 .dig_out_nid = ALC880_DIGOUT_NID,
5174 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5175 .channel_mode = alc880_threestack_modes,
5177 .input_mux = &alc880_capture_source,
5178 .unsol_event = alc880_uniwill_unsol_event,
5179 .setup = alc880_uniwill_setup,
5180 .init_hook = alc880_uniwill_init_hook,
5182 [ALC880_UNIWILL_P53] = {
5183 .mixers = { alc880_uniwill_p53_mixer },
5184 .init_verbs = { alc880_volume_init_verbs,
5185 alc880_uniwill_p53_init_verbs },
5186 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5187 .dac_nids = alc880_asus_dac_nids,
5188 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5189 .channel_mode = alc880_threestack_modes,
5190 .input_mux = &alc880_capture_source,
5191 .unsol_event = alc880_uniwill_p53_unsol_event,
5192 .setup = alc880_uniwill_p53_setup,
5193 .init_hook = alc_hp_automute,
5195 [ALC880_FUJITSU] = {
5196 .mixers = { alc880_fujitsu_mixer },
5197 .init_verbs = { alc880_volume_init_verbs,
5198 alc880_uniwill_p53_init_verbs,
5199 alc880_beep_init_verbs },
5200 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5201 .dac_nids = alc880_dac_nids,
5202 .dig_out_nid = ALC880_DIGOUT_NID,
5203 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5204 .channel_mode = alc880_2_jack_modes,
5205 .input_mux = &alc880_capture_source,
5206 .unsol_event = alc880_uniwill_p53_unsol_event,
5207 .setup = alc880_uniwill_p53_setup,
5208 .init_hook = alc_hp_automute,
5211 .mixers = { alc880_three_stack_mixer },
5212 .init_verbs = { alc880_volume_init_verbs,
5213 alc880_pin_clevo_init_verbs },
5214 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5215 .dac_nids = alc880_dac_nids,
5217 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5218 .channel_mode = alc880_threestack_modes,
5220 .input_mux = &alc880_capture_source,
5223 .mixers = { alc880_lg_mixer },
5224 .init_verbs = { alc880_volume_init_verbs,
5225 alc880_lg_init_verbs },
5226 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5227 .dac_nids = alc880_lg_dac_nids,
5228 .dig_out_nid = ALC880_DIGOUT_NID,
5229 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5230 .channel_mode = alc880_lg_ch_modes,
5232 .input_mux = &alc880_lg_capture_source,
5233 .unsol_event = alc_sku_unsol_event,
5234 .setup = alc880_lg_setup,
5235 .init_hook = alc_hp_automute,
5236 #ifdef CONFIG_SND_HDA_POWER_SAVE
5237 .loopbacks = alc880_lg_loopbacks,
5241 .mixers = { alc880_lg_lw_mixer },
5242 .init_verbs = { alc880_volume_init_verbs,
5243 alc880_lg_lw_init_verbs },
5244 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5245 .dac_nids = alc880_dac_nids,
5246 .dig_out_nid = ALC880_DIGOUT_NID,
5247 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5248 .channel_mode = alc880_lg_lw_modes,
5249 .input_mux = &alc880_lg_lw_capture_source,
5250 .unsol_event = alc_sku_unsol_event,
5251 .setup = alc880_lg_lw_setup,
5252 .init_hook = alc_hp_automute,
5254 [ALC880_MEDION_RIM] = {
5255 .mixers = { alc880_medion_rim_mixer },
5256 .init_verbs = { alc880_volume_init_verbs,
5257 alc880_medion_rim_init_verbs,
5258 alc_gpio2_init_verbs },
5259 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5260 .dac_nids = alc880_dac_nids,
5261 .dig_out_nid = ALC880_DIGOUT_NID,
5262 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5263 .channel_mode = alc880_2_jack_modes,
5264 .input_mux = &alc880_medion_rim_capture_source,
5265 .unsol_event = alc880_medion_rim_unsol_event,
5266 .setup = alc880_medion_rim_setup,
5267 .init_hook = alc880_medion_rim_automute,
5269 #ifdef CONFIG_SND_DEBUG
5271 .mixers = { alc880_test_mixer },
5272 .init_verbs = { alc880_test_init_verbs },
5273 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5274 .dac_nids = alc880_test_dac_nids,
5275 .dig_out_nid = ALC880_DIGOUT_NID,
5276 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5277 .channel_mode = alc880_test_modes,
5278 .input_mux = &alc880_test_capture_source,
5284 * Automatic parse of I/O pins from the BIOS configuration
5289 ALC_CTL_WIDGET_MUTE,
5292 static const struct snd_kcontrol_new alc880_control_templates[] = {
5293 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5294 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5295 HDA_BIND_MUTE(NULL, 0, 0, 0),
5298 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5300 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5301 return snd_array_new(&spec->kctls);
5304 /* add dynamic controls */
5305 static int add_control(struct alc_spec *spec, int type, const char *name,
5306 int cidx, unsigned long val)
5308 struct snd_kcontrol_new *knew;
5310 knew = alc_kcontrol_new(spec);
5313 *knew = alc880_control_templates[type];
5314 knew->name = kstrdup(name, GFP_KERNEL);
5318 if (get_amp_nid_(val))
5319 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5320 knew->private_value = val;
5324 static int add_control_with_pfx(struct alc_spec *spec, int type,
5325 const char *pfx, const char *dir,
5326 const char *sfx, int cidx, unsigned long val)
5329 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5330 return add_control(spec, type, name, cidx, val);
5333 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5334 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5335 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5336 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5337 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5338 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5339 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5340 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5342 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5343 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5344 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5345 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5346 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5347 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5348 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5349 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5350 #define ALC880_PIN_CD_NID 0x1c
5352 static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5353 bool can_be_master, int *index)
5355 struct auto_pin_cfg *cfg = &spec->autocfg;
5356 static const char * const chname[4] = {
5357 "Front", "Surround", NULL /*CLFE*/, "Side"
5361 if (cfg->line_outs == 1 && !spec->multi_ios &&
5362 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5365 switch (cfg->line_out_type) {
5366 case AUTO_PIN_SPEAKER_OUT:
5367 if (cfg->line_outs == 1)
5370 case AUTO_PIN_HP_OUT:
5371 /* for multi-io case, only the primary out */
5372 if (ch && spec->multi_ios)
5377 if (cfg->line_outs == 1 && !spec->multi_ios)
5384 /* create input playback/capture controls for the given pin */
5385 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5386 const char *ctlname, int ctlidx,
5387 int idx, hda_nid_t mix_nid)
5391 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5392 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5395 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5396 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5402 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5404 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5405 return (pincap & AC_PINCAP_IN) != 0;
5408 static int alc_auto_fill_adc_caps(struct hda_codec *codec)
5410 struct alc_spec *spec = codec->spec;
5412 hda_nid_t *adc_nids = spec->private_adc_nids;
5413 hda_nid_t *cap_nids = spec->private_capsrc_nids;
5414 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
5415 bool indep_capsrc = false;
5418 nid = codec->start_nid;
5419 for (i = 0; i < codec->num_nodes; i++, nid++) {
5421 const hda_nid_t *list;
5422 unsigned int caps = get_wcaps(codec, nid);
5423 int type = get_wcaps_type(caps);
5425 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
5427 adc_nids[nums] = nid;
5428 cap_nids[nums] = nid;
5432 type = get_wcaps_type(get_wcaps(codec, src));
5433 if (type == AC_WID_PIN)
5435 if (type == AC_WID_AUD_SEL) {
5436 cap_nids[nums] = src;
5437 indep_capsrc = true;
5440 n = snd_hda_get_conn_list(codec, src, &list);
5442 cap_nids[nums] = src;
5443 indep_capsrc = true;
5449 if (++nums >= max_nums)
5452 spec->adc_nids = spec->private_adc_nids;
5454 spec->capsrc_nids = spec->private_capsrc_nids;
5455 spec->num_adc_nids = nums;
5459 /* create playback/capture controls for input pins */
5460 static int alc_auto_create_input_ctls(struct hda_codec *codec)
5462 struct alc_spec *spec = codec->spec;
5463 const struct auto_pin_cfg *cfg = &spec->autocfg;
5464 hda_nid_t mixer = spec->mixer_nid;
5465 struct hda_input_mux *imux = &spec->private_imux[0];
5467 int i, c, err, idx, type_idx = 0;
5468 const char *prev_label = NULL;
5470 num_adcs = alc_auto_fill_adc_caps(codec);
5474 for (i = 0; i < cfg->num_inputs; i++) {
5478 pin = cfg->inputs[i].pin;
5479 if (!alc_is_input_pin(codec, pin))
5482 label = hda_get_autocfg_input_label(codec, cfg, i);
5483 if (prev_label && !strcmp(label, prev_label))
5490 idx = get_connection_index(codec, mixer, pin);
5492 err = new_analog_input(spec, pin,
5500 for (c = 0; c < num_adcs; c++) {
5501 hda_nid_t cap = spec->capsrc_nids ?
5502 spec->capsrc_nids[c] : spec->adc_nids[c];
5503 idx = get_connection_index(codec, cap, pin);
5505 snd_hda_add_imux_item(imux, label, idx, NULL);
5513 static int alc_auto_fill_dac_nids(struct hda_codec *codec);
5514 static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
5515 const struct auto_pin_cfg *cfg);
5516 static int alc_auto_create_hp_out(struct hda_codec *codec);
5517 static int alc_auto_create_speaker_out(struct hda_codec *codec);
5518 static void alc_auto_init_multi_out(struct hda_codec *codec);
5519 static void alc_auto_init_extra_out(struct hda_codec *codec);
5521 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5522 unsigned int pin_type)
5524 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5527 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5531 static int get_pin_type(int line_out_type)
5533 if (line_out_type == AUTO_PIN_HP_OUT)
5539 static void alc_auto_init_analog_input(struct hda_codec *codec)
5541 struct alc_spec *spec = codec->spec;
5542 struct auto_pin_cfg *cfg = &spec->autocfg;
5545 for (i = 0; i < cfg->num_inputs; i++) {
5546 hda_nid_t nid = cfg->inputs[i].pin;
5547 if (alc_is_input_pin(codec, nid)) {
5548 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5549 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
5550 snd_hda_codec_write(codec, nid, 0,
5551 AC_VERB_SET_AMP_GAIN_MUTE,
5556 /* mute all loopback inputs */
5557 if (spec->mixer_nid) {
5558 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5559 for (i = 0; i < nums; i++)
5560 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5561 AC_VERB_SET_AMP_GAIN_MUTE,
5566 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5567 int (*fill_dac)(struct hda_codec *));
5568 static void alc_remove_invalid_adc_nids(struct hda_codec *codec);
5569 static void alc_auto_init_input_src(struct hda_codec *codec);
5571 /* parse the BIOS configuration and set up the alc_spec */
5572 /* return 1 if successful, 0 if the proper config is not found,
5573 * or a negative error code
5575 static int alc880_parse_auto_config(struct hda_codec *codec)
5577 struct alc_spec *spec = codec->spec;
5579 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5581 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5585 if (!spec->autocfg.line_outs)
5586 return 0; /* can't find valid BIOS pin config */
5588 err = alc_auto_fill_dac_nids(codec);
5591 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
5594 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
5597 err = alc_auto_create_hp_out(codec);
5600 err = alc_auto_create_speaker_out(codec);
5603 err = alc_auto_create_input_ctls(codec);
5607 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5609 alc_auto_parse_digital(codec);
5611 if (spec->kctls.list)
5612 add_mixer(spec, spec->kctls.list);
5614 spec->num_mux_defs = 1;
5615 spec->input_mux = &spec->private_imux[0];
5617 if (!spec->dual_adc_switch)
5618 alc_remove_invalid_adc_nids(codec);
5620 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5625 /* additional initialization for auto-configuration model */
5626 static void alc880_auto_init(struct hda_codec *codec)
5628 struct alc_spec *spec = codec->spec;
5629 alc_auto_init_multi_out(codec);
5630 alc_auto_init_extra_out(codec);
5631 alc_auto_init_analog_input(codec);
5632 alc_auto_init_input_src(codec);
5633 alc_auto_init_digital(codec);
5634 if (spec->unsol_event)
5635 alc_inithook(codec);
5638 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5639 * one of two digital mic pins, e.g. on ALC272
5641 static void fixup_automic_adc(struct hda_codec *codec)
5643 struct alc_spec *spec = codec->spec;
5646 for (i = 0; i < spec->num_adc_nids; i++) {
5647 hda_nid_t cap = spec->capsrc_nids ?
5648 spec->capsrc_nids[i] : spec->adc_nids[i];
5651 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5654 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5657 spec->int_mic.mux_idx = iidx;
5658 spec->ext_mic.mux_idx = eidx;
5659 if (spec->capsrc_nids)
5660 spec->capsrc_nids += i;
5661 spec->adc_nids += i;
5662 spec->num_adc_nids = 1;
5663 /* optional dock-mic */
5664 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5666 spec->dock_mic.pin = 0;
5668 spec->dock_mic.mux_idx = eidx;
5671 snd_printd(KERN_INFO "hda_codec: %s: "
5672 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5673 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5674 spec->auto_mic = 0; /* disable auto-mic to be sure */
5677 /* select or unmute the given capsrc route */
5678 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5681 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5682 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5685 snd_hda_codec_write_cache(codec, cap, 0,
5686 AC_VERB_SET_CONNECT_SEL, idx);
5690 /* set the default connection to that pin */
5691 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5693 struct alc_spec *spec = codec->spec;
5698 for (i = 0; i < spec->num_adc_nids; i++) {
5699 hda_nid_t cap = spec->capsrc_nids ?
5700 spec->capsrc_nids[i] : spec->adc_nids[i];
5703 idx = get_connection_index(codec, cap, pin);
5706 select_or_unmute_capsrc(codec, cap, idx);
5707 return i; /* return the found index */
5709 return -1; /* not found */
5712 /* choose the ADC/MUX containing the input pin and initialize the setup */
5713 static void fixup_single_adc(struct hda_codec *codec)
5715 struct alc_spec *spec = codec->spec;
5716 struct auto_pin_cfg *cfg = &spec->autocfg;
5719 /* search for the input pin; there must be only one */
5720 if (cfg->num_inputs != 1)
5722 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5724 /* use only this ADC */
5725 if (spec->capsrc_nids)
5726 spec->capsrc_nids += i;
5727 spec->adc_nids += i;
5728 spec->num_adc_nids = 1;
5729 spec->single_input_src = 1;
5733 /* initialize dual adcs */
5734 static void fixup_dual_adc_switch(struct hda_codec *codec)
5736 struct alc_spec *spec = codec->spec;
5737 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5738 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5739 init_capsrc_for_pin(codec, spec->int_mic.pin);
5742 /* initialize some special cases for input sources */
5743 static void alc_init_special_input_src(struct hda_codec *codec)
5745 struct alc_spec *spec = codec->spec;
5746 if (spec->dual_adc_switch)
5747 fixup_dual_adc_switch(codec);
5748 else if (spec->single_input_src)
5749 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5752 static void set_capture_mixer(struct hda_codec *codec)
5754 struct alc_spec *spec = codec->spec;
5755 static const struct snd_kcontrol_new *caps[2][3] = {
5756 { alc_capture_mixer_nosrc1,
5757 alc_capture_mixer_nosrc2,
5758 alc_capture_mixer_nosrc3 },
5759 { alc_capture_mixer1,
5761 alc_capture_mixer3 },
5764 /* check whether either of ADC or MUX has a volume control */
5765 if (!(query_amp_caps(codec, spec->adc_nids[0], HDA_INPUT) &
5766 AC_AMPCAP_NUM_STEPS)) {
5767 if (!spec->capsrc_nids)
5768 return; /* no volume */
5769 if (!(query_amp_caps(codec, spec->capsrc_nids[0], HDA_OUTPUT) &
5770 AC_AMPCAP_NUM_STEPS))
5771 return; /* no volume in capsrc, too */
5772 spec->vol_in_capsrc = 1;
5775 if (spec->num_adc_nids > 0) {
5778 if (spec->dual_adc_switch)
5780 else if (spec->auto_mic)
5781 fixup_automic_adc(codec);
5782 else if (spec->input_mux) {
5783 if (spec->input_mux->num_items > 1)
5785 else if (spec->input_mux->num_items == 1)
5786 fixup_single_adc(codec);
5789 if (spec->num_adc_nids > 3)
5790 spec->num_adc_nids = 3;
5791 else if (!spec->num_adc_nids)
5793 num_adcs = spec->num_adc_nids;
5795 spec->cap_mixer = caps[mux][num_adcs - 1];
5799 /* filter out invalid adc_nids (and capsrc_nids) that don't give all
5802 static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5804 struct alc_spec *spec = codec->spec;
5805 struct auto_pin_cfg *cfg = &spec->autocfg;
5806 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5807 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5811 for (n = 0; n < spec->num_adc_nids; n++) {
5812 hda_nid_t cap = spec->private_capsrc_nids[n];
5813 for (i = 0; i < cfg->num_inputs; i++) {
5814 hda_nid_t pin = cfg->inputs[i].pin;
5815 if (get_connection_index(codec, cap, pin) < 0)
5818 if (i >= cfg->num_inputs) {
5819 adc_nids[nums] = spec->private_adc_nids[n];
5820 capsrc_nids[nums++] = cap;
5824 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5825 " using fallback 0x%x\n",
5826 codec->chip_name, spec->private_adc_nids[0]);
5827 spec->num_adc_nids = 1;
5828 } else if (nums != spec->num_adc_nids) {
5829 memcpy(spec->private_adc_nids, adc_nids,
5830 nums * sizeof(hda_nid_t));
5831 memcpy(spec->private_capsrc_nids, capsrc_nids,
5832 nums * sizeof(hda_nid_t));
5833 spec->num_adc_nids = nums;
5837 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5838 #define set_beep_amp(spec, nid, idx, dir) \
5839 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5841 static const struct snd_pci_quirk beep_white_list[] = {
5842 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5843 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5844 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5845 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5846 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5850 static inline int has_cdefine_beep(struct hda_codec *codec)
5852 struct alc_spec *spec = codec->spec;
5853 const struct snd_pci_quirk *q;
5854 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5857 return spec->cdefine.enable_pcbeep;
5860 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5861 #define has_cdefine_beep(codec) 0
5865 * OK, here we have finally the patch for ALC880
5868 static int patch_alc880(struct hda_codec *codec)
5870 struct alc_spec *spec;
5874 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5880 spec->mixer_nid = 0x0b;
5882 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5885 if (board_config < 0) {
5886 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5888 board_config = ALC880_AUTO;
5891 if (board_config == ALC880_AUTO) {
5892 /* automatic parse from the BIOS config */
5893 err = alc880_parse_auto_config(codec);
5899 "hda_codec: Cannot set up configuration "
5900 "from BIOS. Using 3-stack mode...\n");
5901 board_config = ALC880_3ST;
5905 err = snd_hda_attach_beep_device(codec, 0x1);
5911 if (board_config != ALC880_AUTO)
5912 setup_preset(codec, &alc880_presets[board_config]);
5914 if (!spec->adc_nids && spec->input_mux) {
5915 alc_auto_fill_adc_caps(codec);
5916 alc_remove_invalid_adc_nids(codec);
5918 set_capture_mixer(codec);
5919 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5921 spec->vmaster_nid = 0x0c;
5923 codec->patch_ops = alc_patch_ops;
5924 if (board_config == ALC880_AUTO)
5925 spec->init_hook = alc880_auto_init;
5926 #ifdef CONFIG_SND_HDA_POWER_SAVE
5927 if (!spec->loopback.amplist)
5928 spec->loopback.amplist = alc880_loopbacks;
5939 static const hda_nid_t alc260_dac_nids[1] = {
5944 static const hda_nid_t alc260_adc_nids[1] = {
5949 static const hda_nid_t alc260_adc_nids_alt[1] = {
5954 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5955 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5957 static const hda_nid_t alc260_dual_adc_nids[2] = {
5962 #define ALC260_DIGOUT_NID 0x03
5963 #define ALC260_DIGIN_NID 0x06
5965 static const struct hda_input_mux alc260_capture_source = {
5969 { "Front Mic", 0x1 },
5975 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5976 * headphone jack and the internal CD lines since these are the only pins at
5977 * which audio can appear. For flexibility, also allow the option of
5978 * recording the mixer output on the second ADC (ADC0 doesn't have a
5979 * connection to the mixer output).
5981 static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5985 { "Mic/Line", 0x0 },
5987 { "Headphone", 0x2 },
5993 { "Mic/Line", 0x0 },
5995 { "Headphone", 0x2 },
6002 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6003 * the Fujitsu S702x, but jacks are marked differently.
6005 static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6012 { "Headphone", 0x5 },
6021 { "Headphone", 0x6 },
6027 /* Maxdata Favorit 100XS */
6028 static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6032 { "Line/Mic", 0x0 },
6039 { "Line/Mic", 0x0 },
6047 * This is just place-holder, so there's something for alc_build_pcms to look
6048 * at when it calculates the maximum number of channels. ALC260 has no mixer
6049 * element which allows changing the channel mode, so the verb list is
6052 static const struct hda_channel_mode alc260_modes[1] = {
6057 /* Mixer combinations
6059 * basic: base_output + input + pc_beep + capture
6060 * HP: base_output + input + capture_alt
6061 * HP_3013: hp_3013 + input + capture
6062 * fujitsu: fujitsu + capture
6063 * acer: acer + capture
6066 static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6067 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6068 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6069 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6070 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6071 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6072 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6076 static const struct snd_kcontrol_new alc260_input_mixer[] = {
6077 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6078 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6079 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6080 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6082 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6083 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6084 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6088 /* update HP, line and mono out pins according to the master switch */
6089 static void alc260_hp_master_update(struct hda_codec *codec)
6091 update_speakers(codec);
6094 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6095 struct snd_ctl_elem_value *ucontrol)
6097 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6098 struct alc_spec *spec = codec->spec;
6099 *ucontrol->value.integer.value = !spec->master_mute;
6103 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6104 struct snd_ctl_elem_value *ucontrol)
6106 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6107 struct alc_spec *spec = codec->spec;
6108 int val = !*ucontrol->value.integer.value;
6110 if (val == spec->master_mute)
6112 spec->master_mute = val;
6113 alc260_hp_master_update(codec);
6117 static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6120 .name = "Master Playback Switch",
6121 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6122 .info = snd_ctl_boolean_mono_info,
6123 .get = alc260_hp_master_sw_get,
6124 .put = alc260_hp_master_sw_put,
6126 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6127 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6128 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6129 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6130 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6132 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6136 static const struct hda_verb alc260_hp_unsol_verbs[] = {
6137 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6141 static void alc260_hp_setup(struct hda_codec *codec)
6143 struct alc_spec *spec = codec->spec;
6145 spec->autocfg.hp_pins[0] = 0x0f;
6146 spec->autocfg.speaker_pins[0] = 0x10;
6147 spec->autocfg.speaker_pins[1] = 0x11;
6149 spec->automute_mode = ALC_AUTOMUTE_PIN;
6152 static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6155 .name = "Master Playback Switch",
6156 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6157 .info = snd_ctl_boolean_mono_info,
6158 .get = alc260_hp_master_sw_get,
6159 .put = alc260_hp_master_sw_put,
6161 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6162 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6163 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6164 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6167 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6168 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6172 static void alc260_hp_3013_setup(struct hda_codec *codec)
6174 struct alc_spec *spec = codec->spec;
6176 spec->autocfg.hp_pins[0] = 0x15;
6177 spec->autocfg.speaker_pins[0] = 0x10;
6178 spec->autocfg.speaker_pins[1] = 0x11;
6180 spec->automute_mode = ALC_AUTOMUTE_PIN;
6183 static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6184 .ops = &snd_hda_bind_vol,
6186 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6187 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6188 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6193 static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6194 .ops = &snd_hda_bind_sw,
6196 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6197 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6202 static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6203 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6204 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6205 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6210 static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6211 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6215 static void alc260_hp_3012_setup(struct hda_codec *codec)
6217 struct alc_spec *spec = codec->spec;
6219 spec->autocfg.hp_pins[0] = 0x10;
6220 spec->autocfg.speaker_pins[0] = 0x0f;
6221 spec->autocfg.speaker_pins[1] = 0x11;
6222 spec->autocfg.speaker_pins[2] = 0x15;
6224 spec->automute_mode = ALC_AUTOMUTE_PIN;
6227 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6228 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6230 static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6231 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6232 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6233 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6234 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6235 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6236 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6237 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6238 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6240 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6244 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6245 * versions of the ALC260 don't act on requests to enable mic bias from NID
6246 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6247 * datasheet doesn't mention this restriction. At this stage it's not clear
6248 * whether this behaviour is intentional or is a hardware bug in chip
6249 * revisions available in early 2006. Therefore for now allow the
6250 * "Headphone Jack Mode" control to span all choices, but if it turns out
6251 * that the lack of mic bias for this NID is intentional we could change the
6252 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6254 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6255 * don't appear to make the mic bias available from the "line" jack, even
6256 * though the NID used for this jack (0x14) can supply it. The theory is
6257 * that perhaps Acer have included blocking capacitors between the ALC260
6258 * and the output jack. If this turns out to be the case for all such
6259 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6260 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6262 * The C20x Tablet series have a mono internal speaker which is controlled
6263 * via the chip's Mono sum widget and pin complex, so include the necessary
6264 * controls for such models. On models without a "mono speaker" the control
6265 * won't do anything.
6267 static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6268 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6269 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6270 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6271 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6273 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6275 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6276 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6278 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6279 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6280 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6281 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6282 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6286 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6288 static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6289 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6290 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6291 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6292 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6293 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6294 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6298 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6299 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6301 static const struct snd_kcontrol_new alc260_will_mixer[] = {
6302 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6303 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6305 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6306 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6307 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6308 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6309 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6310 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6311 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6315 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6316 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6318 static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6319 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6320 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6322 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6323 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6324 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6325 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6326 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6327 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6328 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6333 * initialization verbs
6335 static const struct hda_verb alc260_init_verbs[] = {
6336 /* Line In pin widget for input */
6337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6338 /* CD pin widget for input */
6339 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6340 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6341 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6342 /* Mic2 (front panel) pin widget for input and vref at 80% */
6343 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6344 /* LINE-2 is used for line-out in rear */
6345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6346 /* select line-out */
6347 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6349 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6351 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6353 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6354 /* mute capture amp left and right */
6355 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6356 /* set connection select to line in (default select for this ADC) */
6357 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6358 /* mute capture amp left and right */
6359 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6360 /* set connection select to line in (default select for this ADC) */
6361 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6362 /* set vol=0 Line-Out mixer amp left and right */
6363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6364 /* unmute pin widget amp left and right (no gain on this amp) */
6365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6366 /* set vol=0 HP mixer amp left and right */
6367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6368 /* unmute pin widget amp left and right (no gain on this amp) */
6369 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6370 /* set vol=0 Mono mixer amp left and right */
6371 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6372 /* unmute pin widget amp left and right (no gain on this amp) */
6373 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6374 /* unmute LINE-2 out pin */
6375 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6376 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6379 /* mute analog inputs */
6380 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6381 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6383 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6385 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6386 /* mute Front out path */
6387 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6388 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6389 /* mute Headphone out path */
6390 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6392 /* mute Mono out path */
6393 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6394 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6398 #if 0 /* should be identical with alc260_init_verbs? */
6399 static const struct hda_verb alc260_hp_init_verbs[] = {
6400 /* Headphone and output */
6401 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6403 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6404 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6405 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6406 /* Mic2 (front panel) pin widget for input and vref at 80% */
6407 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6408 /* Line In pin widget for input */
6409 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6410 /* Line-2 pin widget for output */
6411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6412 /* CD pin widget for input */
6413 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6414 /* unmute amp left and right */
6415 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6416 /* set connection select to line in (default select for this ADC) */
6417 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6418 /* unmute Line-Out mixer amp left and right (volume = 0) */
6419 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6420 /* mute pin widget amp left and right (no gain on this amp) */
6421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6422 /* unmute HP mixer amp left and right (volume = 0) */
6423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6424 /* mute pin widget amp left and right (no gain on this amp) */
6425 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6426 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6429 /* mute analog inputs */
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6434 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6435 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6436 /* Unmute Front out path */
6437 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6438 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6439 /* Unmute Headphone out path */
6440 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6442 /* Unmute Mono out path */
6443 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6444 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6449 static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6450 /* Line out and output */
6451 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6453 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6454 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6455 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6456 /* Mic2 (front panel) pin widget for input and vref at 80% */
6457 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6458 /* Line In pin widget for input */
6459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6460 /* Headphone pin widget for output */
6461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6462 /* CD pin widget for input */
6463 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6464 /* unmute amp left and right */
6465 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6466 /* set connection select to line in (default select for this ADC) */
6467 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6468 /* unmute Line-Out mixer amp left and right (volume = 0) */
6469 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6470 /* mute pin widget amp left and right (no gain on this amp) */
6471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6472 /* unmute HP mixer amp left and right (volume = 0) */
6473 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6474 /* mute pin widget amp left and right (no gain on this amp) */
6475 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6476 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6479 /* mute analog inputs */
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6485 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6486 /* Unmute Front out path */
6487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6488 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6489 /* Unmute Headphone out path */
6490 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6491 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6492 /* Unmute Mono out path */
6493 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6494 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6498 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6499 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6500 * audio = 0x16, internal speaker = 0x10.
6502 static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6503 /* Disable all GPIOs */
6504 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6505 /* Internal speaker is connected to headphone pin */
6506 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6507 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6509 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6510 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6511 /* Ensure all other unused pins are disabled and muted. */
6512 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6513 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6514 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6515 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6516 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6517 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6521 /* Disable digital (SPDIF) pins */
6522 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6523 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6525 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6526 * when acting as an output.
6528 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6530 /* Start with output sum widgets muted and their output gains at min */
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6532 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6534 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6537 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6538 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6541 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6542 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6543 /* Unmute Line1 pin widget output buffer since it starts as an output.
6544 * If the pin mode is changed by the user the pin mode control will
6545 * take care of enabling the pin's input/output buffers as needed.
6546 * Therefore there's no need to enable the input buffer at this
6549 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6550 /* Unmute input buffer of pin widget used for Line-in (no equiv
6553 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6555 /* Mute capture amp left and right */
6556 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6557 /* Set ADC connection select to match default mixer setting - line
6560 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6562 /* Do the same for the second ADC: mute capture input amp and
6563 * set ADC connection to line in (on mic1 pin)
6565 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6566 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6568 /* Mute all inputs to mixer widget (even unconnected ones) */
6569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6581 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6582 * similar laptops (adapted from Fujitsu init verbs).
6584 static const struct hda_verb alc260_acer_init_verbs[] = {
6585 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6586 * the headphone jack. Turn this on and rely on the standard mute
6587 * methods whenever the user wants to turn these outputs off.
6589 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6590 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6591 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6592 /* Internal speaker/Headphone jack is connected to Line-out pin */
6593 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6594 /* Internal microphone/Mic jack is connected to Mic1 pin */
6595 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6596 /* Line In jack is connected to Line1 pin */
6597 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6598 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6599 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6600 /* Ensure all other unused pins are disabled and muted. */
6601 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6602 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6603 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6604 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6606 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6607 /* Disable digital (SPDIF) pins */
6608 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6609 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6611 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6612 * bus when acting as outputs.
6614 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6615 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6617 /* Start with output sum widgets muted and their output gains at min */
6618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6620 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6623 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6624 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6625 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6626 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6628 /* Unmute Line-out pin widget amp left and right
6629 * (no equiv mixer ctrl)
6631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6632 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6633 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6634 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6635 * inputs. If the pin mode is changed by the user the pin mode control
6636 * will take care of enabling the pin's input/output buffers as needed.
6637 * Therefore there's no need to enable the input buffer at this
6640 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6643 /* Mute capture amp left and right */
6644 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6645 /* Set ADC connection select to match default mixer setting - mic
6648 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6650 /* Do similar with the second ADC: mute capture input amp and
6651 * set ADC connection to mic to match ALSA's default state.
6653 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6656 /* Mute all inputs to mixer widget (even unconnected ones) */
6657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6662 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6663 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6664 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6669 /* Initialisation sequence for Maxdata Favorit 100XS
6670 * (adapted from Acer init verbs).
6672 static const struct hda_verb alc260_favorit100_init_verbs[] = {
6673 /* GPIO 0 enables the output jack.
6674 * Turn this on and rely on the standard mute
6675 * methods whenever the user wants to turn these outputs off.
6677 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6678 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6679 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6680 /* Line/Mic input jack is connected to Mic1 pin */
6681 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6682 /* Ensure all other unused pins are disabled and muted. */
6683 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6685 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6686 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6687 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6688 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6693 /* Disable digital (SPDIF) pins */
6694 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6695 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6697 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6698 * bus when acting as outputs.
6700 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6701 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6703 /* Start with output sum widgets muted and their output gains at min */
6704 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6705 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6706 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6708 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6709 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6710 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6711 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6712 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6714 /* Unmute Line-out pin widget amp left and right
6715 * (no equiv mixer ctrl)
6717 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6718 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6719 * inputs. If the pin mode is changed by the user the pin mode control
6720 * will take care of enabling the pin's input/output buffers as needed.
6721 * Therefore there's no need to enable the input buffer at this
6724 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6726 /* Mute capture amp left and right */
6727 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6728 /* Set ADC connection select to match default mixer setting - mic
6731 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6733 /* Do similar with the second ADC: mute capture input amp and
6734 * set ADC connection to mic to match ALSA's default state.
6736 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6739 /* Mute all inputs to mixer widget (even unconnected ones) */
6740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6752 static const struct hda_verb alc260_will_verbs[] = {
6753 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6754 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6755 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6756 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6757 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6758 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6762 static const struct hda_verb alc260_replacer_672v_verbs[] = {
6763 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6764 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6765 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6767 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6768 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6769 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6771 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6775 /* toggle speaker-output according to the hp-jack state */
6776 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6778 unsigned int present;
6780 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6781 present = snd_hda_jack_detect(codec, 0x0f);
6783 snd_hda_codec_write_cache(codec, 0x01, 0,
6784 AC_VERB_SET_GPIO_DATA, 1);
6785 snd_hda_codec_write_cache(codec, 0x0f, 0,
6786 AC_VERB_SET_PIN_WIDGET_CONTROL,
6789 snd_hda_codec_write_cache(codec, 0x01, 0,
6790 AC_VERB_SET_GPIO_DATA, 0);
6791 snd_hda_codec_write_cache(codec, 0x0f, 0,
6792 AC_VERB_SET_PIN_WIDGET_CONTROL,
6797 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6800 if ((res >> 26) == ALC880_HP_EVENT)
6801 alc260_replacer_672v_automute(codec);
6804 static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6805 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6807 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6808 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6809 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6811 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6812 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6813 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6814 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6818 /* Test configuration for debugging, modelled after the ALC880 test
6821 #ifdef CONFIG_SND_DEBUG
6822 static const hda_nid_t alc260_test_dac_nids[1] = {
6825 static const hda_nid_t alc260_test_adc_nids[2] = {
6828 /* For testing the ALC260, each input MUX needs its own definition since
6829 * the signal assignments are different. This assumes that the first ADC
6832 static const struct hda_input_mux alc260_test_capture_sources[2] = {
6836 { "MIC1 pin", 0x0 },
6837 { "MIC2 pin", 0x1 },
6838 { "LINE1 pin", 0x2 },
6839 { "LINE2 pin", 0x3 },
6841 { "LINE-OUT pin", 0x5 },
6842 { "HP-OUT pin", 0x6 },
6848 { "MIC1 pin", 0x0 },
6849 { "MIC2 pin", 0x1 },
6850 { "LINE1 pin", 0x2 },
6851 { "LINE2 pin", 0x3 },
6854 { "LINE-OUT pin", 0x6 },
6855 { "HP-OUT pin", 0x7 },
6859 static const struct snd_kcontrol_new alc260_test_mixer[] = {
6860 /* Output driver widgets */
6861 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6862 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6863 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6864 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6865 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6866 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6868 /* Modes for retasking pin widgets
6869 * Note: the ALC260 doesn't seem to act on requests to enable mic
6870 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6871 * mention this restriction. At this stage it's not clear whether
6872 * this behaviour is intentional or is a hardware bug in chip
6873 * revisions available at least up until early 2006. Therefore for
6874 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6875 * choices, but if it turns out that the lack of mic bias for these
6876 * NIDs is intentional we could change their modes from
6877 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6879 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6880 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6881 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6882 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6883 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6884 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6886 /* Loopback mixer controls */
6887 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6888 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6889 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6890 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6891 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6892 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6893 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6894 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6895 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6896 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6897 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6898 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6899 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6900 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6902 /* Controls for GPIO pins, assuming they are configured as outputs */
6903 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6904 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6905 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6906 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6908 /* Switches to allow the digital IO pins to be enabled. The datasheet
6909 * is ambigious as to which NID is which; testing on laptops which
6910 * make this output available should provide clarification.
6912 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6913 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6915 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6916 * this output to turn on an external amplifier.
6918 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6919 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6923 static const struct hda_verb alc260_test_init_verbs[] = {
6924 /* Enable all GPIOs as outputs with an initial value of 0 */
6925 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6926 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6927 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6929 /* Enable retasking pins as output, initially without power amp */
6930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6931 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6933 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6934 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6935 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6937 /* Disable digital (SPDIF) pins initially, but users can enable
6938 * them via a mixer switch. In the case of SPDIF-out, this initverb
6939 * payload also sets the generation to 0, output to be in "consumer"
6940 * PCM format, copyright asserted, no pre-emphasis and no validity
6943 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6944 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6946 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6947 * OUT1 sum bus when acting as an output.
6949 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6950 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6951 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6952 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6954 /* Start with output sum widgets muted and their output gains at min */
6955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6956 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6957 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6960 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6961 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6962 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6963 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6965 /* Unmute retasking pin widget output buffers since the default
6966 * state appears to be output. As the pin mode is changed by the
6967 * user the pin mode control will take care of enabling the pin's
6968 * input/output buffers as needed.
6970 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6971 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6972 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6973 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6974 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6975 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6976 /* Also unmute the mono-out pin widget */
6977 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6979 /* Mute capture amp left and right */
6980 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6981 /* Set ADC connection select to match default mixer setting (mic1
6984 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6986 /* Do the same for the second ADC: mute capture input amp and
6987 * set ADC connection to mic1 pin
6989 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6990 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6992 /* Mute all inputs to mixer widget (even unconnected ones) */
6993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7007 * for BIOS auto-configuration
7010 /* convert from pin to volume-mixer widget */
7011 static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7013 if (nid >= 0x0f && nid <= 0x11)
7015 else if (nid >= 0x12 && nid <= 0x15)
7021 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7022 const char *pfx, int *vol_bits)
7025 unsigned long vol_val, sw_val;
7028 nid_vol = alc260_pin_to_vol_mix(nid);
7035 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7036 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
7038 if (!(*vol_bits & (1 << nid_vol))) {
7039 /* first control for the volume widget */
7040 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7043 *vol_bits |= (1 << nid_vol);
7045 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7051 /* add playback controls from the parsed DAC table */
7052 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7053 const struct auto_pin_cfg *cfg)
7059 spec->multiout.num_dacs = 1;
7060 spec->multiout.dac_nids = spec->private_dac_nids;
7061 spec->private_dac_nids[0] = 0x02;
7063 nid = cfg->line_out_pins[0];
7067 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
7068 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7073 nid = cfg->speaker_pins[0];
7075 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7080 nid = cfg->hp_pins[0];
7082 err = alc260_add_playback_controls(spec, nid, "Headphone",
7090 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7091 hda_nid_t nid, int pin_type,
7096 alc_set_pin_output(codec, nid, pin_type);
7097 /* need the manual connection? */
7099 int idx = nid - 0x12;
7100 snd_hda_codec_write(codec, idx + 0x0b, 0,
7101 AC_VERB_SET_CONNECT_SEL, sel_idx);
7104 mix = alc260_pin_to_vol_mix(nid);
7107 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7109 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7111 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7115 static void alc260_auto_init_multi_out(struct hda_codec *codec)
7117 struct alc_spec *spec = codec->spec;
7120 nid = spec->autocfg.line_out_pins[0];
7122 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7123 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7126 nid = spec->autocfg.speaker_pins[0];
7128 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7130 nid = spec->autocfg.hp_pins[0];
7132 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7135 static int alc260_parse_auto_config(struct hda_codec *codec)
7137 struct alc_spec *spec = codec->spec;
7139 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7141 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7145 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7148 if (!spec->kctls.list)
7149 return 0; /* can't find valid BIOS pin config */
7150 err = alc_auto_create_input_ctls(codec);
7154 spec->multiout.max_channels = 2;
7156 if (spec->autocfg.dig_outs)
7157 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7158 if (spec->kctls.list)
7159 add_mixer(spec, spec->kctls.list);
7161 spec->num_mux_defs = 1;
7162 spec->input_mux = &spec->private_imux[0];
7164 if (!spec->dual_adc_switch)
7165 alc_remove_invalid_adc_nids(codec);
7167 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7172 /* additional initialization for auto-configuration model */
7173 static void alc260_auto_init(struct hda_codec *codec)
7175 struct alc_spec *spec = codec->spec;
7176 alc260_auto_init_multi_out(codec);
7177 alc_auto_init_analog_input(codec);
7178 alc_auto_init_input_src(codec);
7179 alc_auto_init_digital(codec);
7180 if (spec->unsol_event)
7181 alc_inithook(codec);
7184 #ifdef CONFIG_SND_HDA_POWER_SAVE
7185 static const struct hda_amp_list alc260_loopbacks[] = {
7186 { 0x07, HDA_INPUT, 0 },
7187 { 0x07, HDA_INPUT, 1 },
7188 { 0x07, HDA_INPUT, 2 },
7189 { 0x07, HDA_INPUT, 3 },
7190 { 0x07, HDA_INPUT, 4 },
7202 static const struct alc_fixup alc260_fixups[] = {
7203 [PINFIX_HP_DC5750] = {
7204 .type = ALC_FIXUP_PINS,
7205 .v.pins = (const struct alc_pincfg[]) {
7206 { 0x11, 0x90130110 }, /* speaker */
7212 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7213 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7218 * ALC260 configurations
7220 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7221 [ALC260_BASIC] = "basic",
7223 [ALC260_HP_3013] = "hp-3013",
7224 [ALC260_HP_DC7600] = "hp-dc7600",
7225 [ALC260_FUJITSU_S702X] = "fujitsu",
7226 [ALC260_ACER] = "acer",
7227 [ALC260_WILL] = "will",
7228 [ALC260_REPLACER_672V] = "replacer",
7229 [ALC260_FAVORIT100] = "favorit100",
7230 #ifdef CONFIG_SND_DEBUG
7231 [ALC260_TEST] = "test",
7233 [ALC260_AUTO] = "auto",
7236 static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7237 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7238 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7239 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7240 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7241 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7242 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7243 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7244 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7245 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7246 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7247 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7248 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7249 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7250 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7251 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7252 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7253 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7254 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7255 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7256 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7260 static const struct alc_config_preset alc260_presets[] = {
7262 .mixers = { alc260_base_output_mixer,
7263 alc260_input_mixer },
7264 .init_verbs = { alc260_init_verbs },
7265 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7266 .dac_nids = alc260_dac_nids,
7267 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7268 .adc_nids = alc260_dual_adc_nids,
7269 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7270 .channel_mode = alc260_modes,
7271 .input_mux = &alc260_capture_source,
7274 .mixers = { alc260_hp_output_mixer,
7275 alc260_input_mixer },
7276 .init_verbs = { alc260_init_verbs,
7277 alc260_hp_unsol_verbs },
7278 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7279 .dac_nids = alc260_dac_nids,
7280 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7281 .adc_nids = alc260_adc_nids_alt,
7282 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7283 .channel_mode = alc260_modes,
7284 .input_mux = &alc260_capture_source,
7285 .unsol_event = alc_sku_unsol_event,
7286 .setup = alc260_hp_setup,
7287 .init_hook = alc_inithook,
7289 [ALC260_HP_DC7600] = {
7290 .mixers = { alc260_hp_dc7600_mixer,
7291 alc260_input_mixer },
7292 .init_verbs = { alc260_init_verbs,
7293 alc260_hp_dc7600_verbs },
7294 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7295 .dac_nids = alc260_dac_nids,
7296 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7297 .adc_nids = alc260_adc_nids_alt,
7298 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7299 .channel_mode = alc260_modes,
7300 .input_mux = &alc260_capture_source,
7301 .unsol_event = alc_sku_unsol_event,
7302 .setup = alc260_hp_3012_setup,
7303 .init_hook = alc_inithook,
7305 [ALC260_HP_3013] = {
7306 .mixers = { alc260_hp_3013_mixer,
7307 alc260_input_mixer },
7308 .init_verbs = { alc260_hp_3013_init_verbs,
7309 alc260_hp_3013_unsol_verbs },
7310 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7311 .dac_nids = alc260_dac_nids,
7312 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7313 .adc_nids = alc260_adc_nids_alt,
7314 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7315 .channel_mode = alc260_modes,
7316 .input_mux = &alc260_capture_source,
7317 .unsol_event = alc_sku_unsol_event,
7318 .setup = alc260_hp_3013_setup,
7319 .init_hook = alc_inithook,
7321 [ALC260_FUJITSU_S702X] = {
7322 .mixers = { alc260_fujitsu_mixer },
7323 .init_verbs = { alc260_fujitsu_init_verbs },
7324 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7325 .dac_nids = alc260_dac_nids,
7326 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7327 .adc_nids = alc260_dual_adc_nids,
7328 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7329 .channel_mode = alc260_modes,
7330 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7331 .input_mux = alc260_fujitsu_capture_sources,
7334 .mixers = { alc260_acer_mixer },
7335 .init_verbs = { alc260_acer_init_verbs },
7336 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7337 .dac_nids = alc260_dac_nids,
7338 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7339 .adc_nids = alc260_dual_adc_nids,
7340 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7341 .channel_mode = alc260_modes,
7342 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7343 .input_mux = alc260_acer_capture_sources,
7345 [ALC260_FAVORIT100] = {
7346 .mixers = { alc260_favorit100_mixer },
7347 .init_verbs = { alc260_favorit100_init_verbs },
7348 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7349 .dac_nids = alc260_dac_nids,
7350 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7351 .adc_nids = alc260_dual_adc_nids,
7352 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7353 .channel_mode = alc260_modes,
7354 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7355 .input_mux = alc260_favorit100_capture_sources,
7358 .mixers = { alc260_will_mixer },
7359 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7360 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7361 .dac_nids = alc260_dac_nids,
7362 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7363 .adc_nids = alc260_adc_nids,
7364 .dig_out_nid = ALC260_DIGOUT_NID,
7365 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7366 .channel_mode = alc260_modes,
7367 .input_mux = &alc260_capture_source,
7369 [ALC260_REPLACER_672V] = {
7370 .mixers = { alc260_replacer_672v_mixer },
7371 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7372 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7373 .dac_nids = alc260_dac_nids,
7374 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7375 .adc_nids = alc260_adc_nids,
7376 .dig_out_nid = ALC260_DIGOUT_NID,
7377 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7378 .channel_mode = alc260_modes,
7379 .input_mux = &alc260_capture_source,
7380 .unsol_event = alc260_replacer_672v_unsol_event,
7381 .init_hook = alc260_replacer_672v_automute,
7383 #ifdef CONFIG_SND_DEBUG
7385 .mixers = { alc260_test_mixer },
7386 .init_verbs = { alc260_test_init_verbs },
7387 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7388 .dac_nids = alc260_test_dac_nids,
7389 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7390 .adc_nids = alc260_test_adc_nids,
7391 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7392 .channel_mode = alc260_modes,
7393 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7394 .input_mux = alc260_test_capture_sources,
7399 static int patch_alc260(struct hda_codec *codec)
7401 struct alc_spec *spec;
7402 int err, board_config;
7404 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7410 spec->mixer_nid = 0x07;
7412 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7415 if (board_config < 0) {
7416 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7418 board_config = ALC260_AUTO;
7421 if (board_config == ALC260_AUTO) {
7422 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7423 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7426 if (board_config == ALC260_AUTO) {
7427 /* automatic parse from the BIOS config */
7428 err = alc260_parse_auto_config(codec);
7434 "hda_codec: Cannot set up configuration "
7435 "from BIOS. Using base mode...\n");
7436 board_config = ALC260_BASIC;
7440 err = snd_hda_attach_beep_device(codec, 0x1);
7446 if (board_config != ALC260_AUTO)
7447 setup_preset(codec, &alc260_presets[board_config]);
7449 if (!spec->adc_nids && spec->input_mux) {
7450 alc_auto_fill_adc_caps(codec);
7451 alc_remove_invalid_adc_nids(codec);
7453 set_capture_mixer(codec);
7454 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7456 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7458 spec->vmaster_nid = 0x08;
7460 codec->patch_ops = alc_patch_ops;
7461 if (board_config == ALC260_AUTO)
7462 spec->init_hook = alc260_auto_init;
7463 spec->shutup = alc_eapd_shutup;
7464 #ifdef CONFIG_SND_HDA_POWER_SAVE
7465 if (!spec->loopback.amplist)
7466 spec->loopback.amplist = alc260_loopbacks;
7474 * ALC882/883/885/888/889 support
7476 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7477 * configuration. Each pin widget can choose any input DACs and a mixer.
7478 * Each ADC is connected from a mixer of all inputs. This makes possible
7479 * 6-channel independent captures.
7481 * In addition, an independent DAC for the multi-playback (not used in this
7484 #define ALC882_DIGOUT_NID 0x06
7485 #define ALC882_DIGIN_NID 0x0a
7486 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7487 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7488 #define ALC1200_DIGOUT_NID 0x10
7491 static const struct hda_channel_mode alc882_ch_modes[1] = {
7496 static const hda_nid_t alc882_dac_nids[4] = {
7497 /* front, rear, clfe, rear_surr */
7498 0x02, 0x03, 0x04, 0x05
7500 #define alc883_dac_nids alc882_dac_nids
7503 #define alc882_adc_nids alc880_adc_nids
7504 #define alc882_adc_nids_alt alc880_adc_nids_alt
7505 #define alc883_adc_nids alc882_adc_nids_alt
7506 static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7507 static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7508 #define alc889_adc_nids alc880_adc_nids
7510 static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7511 static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7512 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7513 static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7514 #define alc889_capsrc_nids alc882_capsrc_nids
7517 /* FIXME: should be a matrix-type input source selection */
7519 static const struct hda_input_mux alc882_capture_source = {
7523 { "Front Mic", 0x1 },
7529 #define alc883_capture_source alc882_capture_source
7531 static const struct hda_input_mux alc889_capture_source = {
7534 { "Front Mic", 0x0 },
7540 static const struct hda_input_mux mb5_capture_source = {
7549 static const struct hda_input_mux macmini3_capture_source = {
7557 static const struct hda_input_mux alc883_3stack_6ch_intel = {
7561 { "Front Mic", 0x0 },
7567 static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7575 static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7579 { "Internal Mic", 0x1 },
7585 static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7589 { "Internal Mic", 0x1 },
7593 static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7597 { "Front Mic", 0x1 },
7602 static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7610 static const struct hda_input_mux alc889A_mb31_capture_source = {
7614 /* Front Mic (0x01) unused */
7616 /* Line 2 (0x03) unused */
7617 /* CD (0x04) unused? */
7621 static const struct hda_input_mux alc889A_imac91_capture_source = {
7625 { "Line", 0x2 }, /* Not sure! */
7632 static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7639 static const struct hda_verb alc882_3ST_ch2_init[] = {
7640 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7641 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7642 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7643 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7650 static const struct hda_verb alc882_3ST_ch4_init[] = {
7651 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7652 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7653 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7654 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7655 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7662 static const struct hda_verb alc882_3ST_ch6_init[] = {
7663 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7664 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7665 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7666 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7667 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7668 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7672 static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7673 { 2, alc882_3ST_ch2_init },
7674 { 4, alc882_3ST_ch4_init },
7675 { 6, alc882_3ST_ch6_init },
7678 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7683 static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7684 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7695 static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7696 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7697 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7698 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7699 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7700 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7701 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7708 static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7709 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7710 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7711 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7712 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7713 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7714 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7715 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7719 static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7720 { 2, alc883_3ST_ch2_clevo_init },
7721 { 4, alc883_3ST_ch4_clevo_init },
7722 { 6, alc883_3ST_ch6_clevo_init },
7729 static const struct hda_verb alc882_sixstack_ch6_init[] = {
7730 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7731 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7732 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7733 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7740 static const struct hda_verb alc882_sixstack_ch8_init[] = {
7741 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7743 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7748 static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7749 { 6, alc882_sixstack_ch6_init },
7750 { 8, alc882_sixstack_ch8_init },
7754 /* Macbook Air 2,1 */
7756 static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7761 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7767 static const struct hda_verb alc885_mbp_ch2_init[] = {
7768 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7769 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7770 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7777 static const struct hda_verb alc885_mbp_ch4_init[] = {
7778 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7780 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7781 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7782 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7786 static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7787 { 2, alc885_mbp_ch2_init },
7788 { 4, alc885_mbp_ch4_init },
7793 * Speakers/Woofer/HP = Front
7796 static const struct hda_verb alc885_mb5_ch2_init[] = {
7797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7804 * Speakers/HP = Front
7808 static const struct hda_verb alc885_mb5_ch6_init[] = {
7809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7815 static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7816 { 2, alc885_mb5_ch2_init },
7817 { 6, alc885_mb5_ch6_init },
7820 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7825 static const struct hda_verb alc883_4ST_ch2_init[] = {
7826 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7827 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7828 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7829 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7830 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7831 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7838 static const struct hda_verb alc883_4ST_ch4_init[] = {
7839 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7840 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7841 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7842 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7843 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7844 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7845 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7852 static const struct hda_verb alc883_4ST_ch6_init[] = {
7853 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7854 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7855 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7856 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7857 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7860 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7867 static const struct hda_verb alc883_4ST_ch8_init[] = {
7868 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7869 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7870 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7871 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7873 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7874 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7875 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7876 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7880 static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7881 { 2, alc883_4ST_ch2_init },
7882 { 4, alc883_4ST_ch4_init },
7883 { 6, alc883_4ST_ch6_init },
7884 { 8, alc883_4ST_ch8_init },
7891 static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
7892 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7893 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7894 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7895 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7902 static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
7903 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7904 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7905 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7907 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7914 static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
7915 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7916 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7917 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7918 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7919 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7920 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7924 static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7925 { 2, alc883_3ST_ch2_intel_init },
7926 { 4, alc883_3ST_ch4_intel_init },
7927 { 6, alc883_3ST_ch6_intel_init },
7933 static const struct hda_verb alc889_ch2_intel_init[] = {
7934 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7935 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7936 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7937 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7938 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7939 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7946 static const struct hda_verb alc889_ch6_intel_init[] = {
7947 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7948 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7949 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7950 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7951 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7952 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7959 static const struct hda_verb alc889_ch8_intel_init[] = {
7960 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7961 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7962 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7963 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7964 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7966 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7970 static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7971 { 2, alc889_ch2_intel_init },
7972 { 6, alc889_ch6_intel_init },
7973 { 8, alc889_ch8_intel_init },
7979 static const struct hda_verb alc883_sixstack_ch6_init[] = {
7980 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7981 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7982 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7983 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7990 static const struct hda_verb alc883_sixstack_ch8_init[] = {
7991 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7992 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7993 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7994 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7998 static const struct hda_channel_mode alc883_sixstack_modes[2] = {
7999 { 6, alc883_sixstack_ch6_init },
8000 { 8, alc883_sixstack_ch8_init },
8004 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8005 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8007 static const struct snd_kcontrol_new alc882_base_mixer[] = {
8008 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8009 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8011 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8012 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8013 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8014 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8015 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8016 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8017 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8018 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8019 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8020 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8021 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8022 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8027 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8028 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8032 /* Macbook Air 2,1 same control for HP and internal Speaker */
8034 static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8035 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8036 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8041 static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8042 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8043 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8044 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8045 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8046 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8047 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8048 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8050 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8051 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8056 static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8058 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8059 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8060 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8061 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8062 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8063 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8064 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8066 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8068 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8070 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8074 static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8075 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8076 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8077 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8078 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8079 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8080 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8082 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8083 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8084 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8085 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8089 static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8091 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8096 static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8098 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8109 static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8111 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8112 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8113 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8114 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8115 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8116 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8119 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8120 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8121 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8122 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8126 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8127 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8129 static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8130 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8131 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8132 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8133 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8134 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8135 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8138 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8139 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8140 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8141 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8146 static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8147 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8148 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8150 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8151 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8152 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8153 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8155 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8160 static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8162 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8163 .name = "Channel Mode",
8164 .info = alc_ch_mode_info,
8165 .get = alc_ch_mode_get,
8166 .put = alc_ch_mode_put,
8171 static const struct hda_verb alc882_base_init_verbs[] = {
8172 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8182 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8183 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8185 /* Front Pin: output 0 (0x0c) */
8186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8187 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8188 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8189 /* Rear Pin: output 1 (0x0d) */
8190 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8192 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8193 /* CLFE Pin: output 2 (0x0e) */
8194 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8196 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8197 /* Side Pin: output 3 (0x0f) */
8198 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8199 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8200 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8201 /* Mic (rear) pin: input vref at 80% */
8202 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8203 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8204 /* Front Mic pin: input vref at 80% */
8205 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8206 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8207 /* Line In pin: input */
8208 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8209 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8210 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8211 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8212 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8213 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8214 /* CD pin widget for input */
8215 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8217 /* FIXME: use matrix-type input source selection */
8218 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8223 /* ADC2: mute amp left and right */
8224 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8225 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8226 /* ADC3: mute amp left and right */
8227 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8228 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8233 static const struct hda_verb alc882_adc1_init_verbs[] = {
8234 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8235 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8236 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8237 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8239 /* ADC1: mute amp left and right */
8240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8241 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8245 static const struct hda_verb alc882_eapd_verbs[] = {
8246 /* change to EAPD mode */
8247 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8248 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8252 static const struct hda_verb alc889_eapd_verbs[] = {
8253 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8254 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8258 static const struct hda_verb alc_hp15_unsol_verbs[] = {
8259 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8264 static const struct hda_verb alc885_init_verbs[] = {
8265 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8267 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8269 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8270 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8272 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8273 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8275 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8276 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8278 /* Front HP Pin: output 0 (0x0c) */
8279 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8281 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8282 /* Front Pin: output 0 (0x0c) */
8283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8284 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8285 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8286 /* Rear Pin: output 1 (0x0d) */
8287 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8289 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8290 /* CLFE Pin: output 2 (0x0e) */
8291 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8292 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8293 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8294 /* Side Pin: output 3 (0x0f) */
8295 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8296 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8297 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8298 /* Mic (rear) pin: input vref at 80% */
8299 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8300 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8301 /* Front Mic pin: input vref at 80% */
8302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8303 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8304 /* Line In pin: input */
8305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8308 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8310 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8315 /* ADC2: mute amp left and right */
8316 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8317 /* ADC3: mute amp left and right */
8318 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 static const struct hda_verb alc885_init_input_verbs[] = {
8324 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8331 /* Unmute Selector 24h and set the default input to front mic */
8332 static const struct hda_verb alc889_init_input_verbs[] = {
8333 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8334 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8339 #define alc883_init_verbs alc882_base_init_verbs
8342 static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8343 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8346 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8347 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8348 /* FIXME: this looks suspicious...
8349 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8355 static const struct hda_verb alc882_macpro_init_verbs[] = {
8356 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8360 /* Front Pin: output 0 (0x0c) */
8361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8363 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8364 /* Front Mic pin: input vref at 80% */
8365 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8366 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8367 /* Speaker: output */
8368 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8369 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8370 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8371 /* Headphone output (output 0 - 0x0c) */
8372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8374 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8376 /* FIXME: use matrix-type input source selection */
8377 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8378 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8380 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8381 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8382 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8385 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8390 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8391 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8393 /* ADC1: mute amp left and right */
8394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8395 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8396 /* ADC2: mute amp left and right */
8397 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8398 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8399 /* ADC3: mute amp left and right */
8400 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8401 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8407 static const struct hda_verb alc885_mb5_init_verbs[] = {
8409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8411 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8417 /* Surround mixer */
8418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8422 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8427 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8429 /* Front Pin (0x0c) */
8430 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8432 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8433 /* LFE Pin (0x0e) */
8434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8435 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8436 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8441 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8442 /* Front Mic pin: input vref at 80% */
8443 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8456 static const struct hda_verb alc885_macmini3_init_verbs[] = {
8458 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8459 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8460 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8461 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8466 /* Surround mixer */
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8468 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8469 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8471 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8472 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8475 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8476 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8477 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8478 /* Front Pin (0x0c) */
8479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8482 /* LFE Pin (0x0e) */
8483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8485 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8489 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8490 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8497 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8498 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8503 static const struct hda_verb alc885_mba21_init_verbs[] = {
8504 /*Internal and HP Speaker Mixer*/
8505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8507 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8508 /*Internal Speaker Pin (0x0c)*/
8509 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8510 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8511 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8512 /* HP Pin: output 0 (0x0e) */
8513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8516 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8517 /* Line in (is hp when jack connected)*/
8518 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8519 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8525 /* Macbook Pro rev3 */
8526 static const struct hda_verb alc885_mbp3_init_verbs[] = {
8527 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8539 /* Front Pin: output 0 (0x0c) */
8540 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8541 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8542 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8543 /* HP Pin: output 0 (0x0e) */
8544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8546 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8547 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8548 /* Mic (rear) pin: input vref at 80% */
8549 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8550 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8551 /* Front Mic pin: input vref at 80% */
8552 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8553 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8554 /* Line In pin: use output 1 when in LineOut mode */
8555 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8556 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8557 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8559 /* FIXME: use matrix-type input source selection */
8560 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8561 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8562 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8563 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8564 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8568 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8569 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8570 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8574 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8576 /* ADC1: mute amp left and right */
8577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8578 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8579 /* ADC2: mute amp left and right */
8580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8581 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8582 /* ADC3: mute amp left and right */
8583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8584 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8590 static const struct hda_verb alc885_imac91_init_verbs[] = {
8591 /* Internal Speaker Pin (0x0c) */
8592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8594 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8595 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8596 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8597 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8601 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8602 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8605 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8606 /* Front Mic pin: input vref at 80% */
8607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8608 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8611 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8613 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8617 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8618 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8619 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8621 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8622 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8623 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8624 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8627 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8632 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8633 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8634 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8635 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8637 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8638 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8639 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8640 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8644 /* iMac 24 mixer. */
8645 static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8646 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8647 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8651 /* iMac 24 init verbs. */
8652 static const struct hda_verb alc885_imac24_init_verbs[] = {
8653 /* Internal speakers: output 0 (0x0c) */
8654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8657 /* Internal speakers: output 0 (0x0c) */
8658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8660 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8661 /* Headphone: output 0 (0x0c) */
8662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8664 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8666 /* Front Mic: input vref at 80% */
8667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8672 /* Toggle speaker-output according to the hp-jack state */
8673 static void alc885_imac24_setup(struct hda_codec *codec)
8675 struct alc_spec *spec = codec->spec;
8677 spec->autocfg.hp_pins[0] = 0x14;
8678 spec->autocfg.speaker_pins[0] = 0x18;
8679 spec->autocfg.speaker_pins[1] = 0x1a;
8681 spec->automute_mode = ALC_AUTOMUTE_AMP;
8684 #define alc885_mb5_setup alc885_imac24_setup
8685 #define alc885_macmini3_setup alc885_imac24_setup
8687 /* Macbook Air 2,1 */
8688 static void alc885_mba21_setup(struct hda_codec *codec)
8690 struct alc_spec *spec = codec->spec;
8692 spec->autocfg.hp_pins[0] = 0x14;
8693 spec->autocfg.speaker_pins[0] = 0x18;
8695 spec->automute_mode = ALC_AUTOMUTE_AMP;
8700 static void alc885_mbp3_setup(struct hda_codec *codec)
8702 struct alc_spec *spec = codec->spec;
8704 spec->autocfg.hp_pins[0] = 0x15;
8705 spec->autocfg.speaker_pins[0] = 0x14;
8707 spec->automute_mode = ALC_AUTOMUTE_AMP;
8710 static void alc885_imac91_setup(struct hda_codec *codec)
8712 struct alc_spec *spec = codec->spec;
8714 spec->autocfg.hp_pins[0] = 0x14;
8715 spec->autocfg.speaker_pins[0] = 0x18;
8716 spec->autocfg.speaker_pins[1] = 0x1a;
8718 spec->automute_mode = ALC_AUTOMUTE_AMP;
8721 static const struct hda_verb alc882_targa_verbs[] = {
8722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8728 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8729 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8730 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8732 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8736 /* toggle speaker-output according to the hp-jack state */
8737 static void alc882_targa_automute(struct hda_codec *codec)
8739 struct alc_spec *spec = codec->spec;
8740 alc_hp_automute(codec);
8741 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8742 spec->jack_present ? 1 : 3);
8745 static void alc882_targa_setup(struct hda_codec *codec)
8747 struct alc_spec *spec = codec->spec;
8749 spec->autocfg.hp_pins[0] = 0x14;
8750 spec->autocfg.speaker_pins[0] = 0x1b;
8752 spec->automute_mode = ALC_AUTOMUTE_AMP;
8755 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8757 if ((res >> 26) == ALC880_HP_EVENT)
8758 alc882_targa_automute(codec);
8761 static const struct hda_verb alc882_asus_a7j_verbs[] = {
8762 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8766 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8769 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8770 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8771 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8773 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8779 static const struct hda_verb alc882_asus_a7m_verbs[] = {
8780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8783 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8785 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8787 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8788 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8789 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8792 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8793 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8797 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8799 unsigned int gpiostate, gpiomask, gpiodir;
8801 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8802 AC_VERB_GET_GPIO_DATA, 0);
8805 gpiostate |= (1 << pin);
8807 gpiostate &= ~(1 << pin);
8809 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8810 AC_VERB_GET_GPIO_MASK, 0);
8811 gpiomask |= (1 << pin);
8813 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8814 AC_VERB_GET_GPIO_DIRECTION, 0);
8815 gpiodir |= (1 << pin);
8818 snd_hda_codec_write(codec, codec->afg, 0,
8819 AC_VERB_SET_GPIO_MASK, gpiomask);
8820 snd_hda_codec_write(codec, codec->afg, 0,
8821 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8825 snd_hda_codec_write(codec, codec->afg, 0,
8826 AC_VERB_SET_GPIO_DATA, gpiostate);
8829 /* set up GPIO at initialization */
8830 static void alc885_macpro_init_hook(struct hda_codec *codec)
8832 alc882_gpio_mute(codec, 0, 0);
8833 alc882_gpio_mute(codec, 1, 0);
8836 /* set up GPIO and update auto-muting at initialization */
8837 static void alc885_imac24_init_hook(struct hda_codec *codec)
8839 alc885_macpro_init_hook(codec);
8840 alc_hp_automute(codec);
8843 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8844 static const struct hda_verb alc889A_mb31_ch2_init[] = {
8845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8846 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8847 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8848 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8852 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8853 static const struct hda_verb alc889A_mb31_ch4_init[] = {
8854 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8855 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8856 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8857 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8861 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8862 static const struct hda_verb alc889A_mb31_ch5_init[] = {
8863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8870 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8871 static const struct hda_verb alc889A_mb31_ch6_init[] = {
8872 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8873 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8874 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8875 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8879 static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8880 { 2, alc889A_mb31_ch2_init },
8881 { 4, alc889A_mb31_ch4_init },
8882 { 5, alc889A_mb31_ch5_init },
8883 { 6, alc889A_mb31_ch6_init },
8886 static const struct hda_verb alc883_medion_eapd_verbs[] = {
8887 /* eanable EAPD on medion laptop */
8888 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8889 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8893 #define alc883_base_mixer alc882_base_mixer
8895 static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
8896 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8897 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8898 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8899 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8900 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8901 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8902 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8906 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8907 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8908 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8912 static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8913 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8914 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8915 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8916 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8918 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8919 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8920 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8922 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8926 static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8927 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8928 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8930 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8935 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8936 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8940 static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8941 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8957 static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8958 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8959 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8960 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8961 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8962 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8963 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8964 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8965 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8975 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8980 static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8981 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8983 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8984 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8985 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8987 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8988 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8989 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9004 static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9006 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9007 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9008 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9009 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9011 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9012 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9013 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9014 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9015 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9022 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9023 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9024 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9028 static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9029 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9030 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9032 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9033 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9034 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9035 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9036 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9038 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9039 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9041 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9043 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9045 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9046 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9047 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9051 static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9055 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9056 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9057 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9058 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9059 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9060 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9061 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9064 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9065 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9066 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9067 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9072 static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9074 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9075 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9076 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9077 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9078 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9081 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9082 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9083 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9084 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9088 static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9089 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9090 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9091 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9092 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9093 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9097 static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9101 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9102 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9109 static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9110 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9111 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9112 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9113 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9114 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9117 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9118 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9122 static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9123 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9124 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9125 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9126 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9127 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9128 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9132 static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9133 /* Unmute front mixer */
9134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9137 /* Set speaker pin to front mixer */
9138 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9140 /* Init headphone pin */
9141 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9142 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9143 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9144 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9149 /* toggle speaker-output according to the hp-jack state */
9150 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9152 struct alc_spec *spec = codec->spec;
9154 spec->autocfg.hp_pins[0] = 0x1a;
9155 spec->autocfg.speaker_pins[0] = 0x15;
9157 spec->automute_mode = ALC_AUTOMUTE_AMP;
9160 static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9161 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9162 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9164 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9165 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9172 static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9173 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9174 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9175 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9176 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9177 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9178 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9180 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9185 static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9186 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9187 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9188 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9189 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9190 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9191 0x0d, 1, 0x0, HDA_OUTPUT),
9192 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9193 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9194 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9195 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9196 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9199 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9200 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9201 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9202 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9205 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9206 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9210 static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9212 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9213 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9214 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9215 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9216 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9218 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9219 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9220 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9221 /* Output switches */
9222 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9223 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9224 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9226 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9227 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9229 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9236 static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9237 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9238 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9241 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9246 static const struct hda_bind_ctls alc883_bind_cap_vol = {
9247 .ops = &snd_hda_bind_vol,
9249 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9250 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9255 static const struct hda_bind_ctls alc883_bind_cap_switch = {
9256 .ops = &snd_hda_bind_sw,
9258 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9259 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9264 static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9265 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9266 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9267 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9268 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9269 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9270 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9276 static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9277 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9278 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9281 /* .name = "Capture Source", */
9282 .name = "Input Source",
9284 .info = alc_mux_enum_info,
9285 .get = alc_mux_enum_get,
9286 .put = alc_mux_enum_put,
9291 static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9294 .name = "Channel Mode",
9295 .info = alc_ch_mode_info,
9296 .get = alc_ch_mode_get,
9297 .put = alc_ch_mode_put,
9302 /* toggle speaker-output according to the hp-jack state */
9303 static void alc883_mitac_setup(struct hda_codec *codec)
9305 struct alc_spec *spec = codec->spec;
9307 spec->autocfg.hp_pins[0] = 0x15;
9308 spec->autocfg.speaker_pins[0] = 0x14;
9309 spec->autocfg.speaker_pins[1] = 0x17;
9311 spec->automute_mode = ALC_AUTOMUTE_AMP;
9314 static const struct hda_verb alc883_mitac_verbs[] = {
9316 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9319 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9320 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9322 /* enable unsolicited event */
9323 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9324 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9329 static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9334 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9336 /* enable unsolicited event */
9338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9339 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9345 static const struct hda_verb alc883_clevo_m720_verbs[] = {
9347 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9350 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9353 /* enable unsolicited event */
9354 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9355 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9360 static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9362 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9368 /* enable unsolicited event */
9369 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9374 static const struct hda_verb alc883_targa_verbs[] = {
9375 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9378 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9379 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9381 /* Connect Line-Out side jack (SPDIF) to Side */
9382 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9383 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9384 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9385 /* Connect Mic jack to CLFE */
9386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9388 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9389 /* Connect Line-in jack to Surround */
9390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9391 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9392 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9393 /* Connect HP out jack to Front */
9394 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9395 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9396 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9398 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9403 static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9404 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9405 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9406 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9410 static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9411 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9412 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9413 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9414 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9418 static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9419 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9421 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9423 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9427 static const struct hda_verb alc883_haier_w66_verbs[] = {
9428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9433 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9434 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9435 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9436 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9440 static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9441 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9442 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9443 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9445 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9447 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9448 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9452 static const struct hda_verb alc888_6st_dell_verbs[] = {
9453 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9457 static const struct hda_verb alc883_vaiott_verbs[] = {
9459 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9462 /* enable unsolicited event */
9463 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9468 static void alc888_3st_hp_setup(struct hda_codec *codec)
9470 struct alc_spec *spec = codec->spec;
9472 spec->autocfg.hp_pins[0] = 0x1b;
9473 spec->autocfg.speaker_pins[0] = 0x14;
9474 spec->autocfg.speaker_pins[1] = 0x16;
9475 spec->autocfg.speaker_pins[2] = 0x18;
9477 spec->automute_mode = ALC_AUTOMUTE_AMP;
9480 static const struct hda_verb alc888_3st_hp_verbs[] = {
9481 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9482 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9483 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9484 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9491 static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9492 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9493 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9494 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9495 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9502 static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9503 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9504 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9505 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9506 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9507 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9514 static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9515 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9516 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9517 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9518 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9519 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9520 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9524 static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9525 { 2, alc888_3st_hp_2ch_init },
9526 { 4, alc888_3st_hp_4ch_init },
9527 { 6, alc888_3st_hp_6ch_init },
9530 static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9532 struct alc_spec *spec = codec->spec;
9534 spec->autocfg.hp_pins[0] = 0x1b;
9535 spec->autocfg.line_out_pins[0] = 0x14;
9536 spec->autocfg.speaker_pins[0] = 0x15;
9538 spec->automute_mode = ALC_AUTOMUTE_AMP;
9541 /* toggle speaker-output according to the hp-jack state */
9542 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9544 struct alc_spec *spec = codec->spec;
9546 spec->autocfg.hp_pins[0] = 0x14;
9547 spec->autocfg.speaker_pins[0] = 0x15;
9549 spec->automute_mode = ALC_AUTOMUTE_AMP;
9552 /* toggle speaker-output according to the hp-jack state */
9553 #define alc883_targa_init_hook alc882_targa_init_hook
9554 #define alc883_targa_unsol_event alc882_targa_unsol_event
9556 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9558 struct alc_spec *spec = codec->spec;
9560 spec->autocfg.hp_pins[0] = 0x15;
9561 spec->autocfg.speaker_pins[0] = 0x14;
9563 spec->automute_mode = ALC_AUTOMUTE_AMP;
9566 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9568 alc_hp_automute(codec);
9569 alc88x_simple_mic_automute(codec);
9572 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9575 switch (res >> 26) {
9576 case ALC880_MIC_EVENT:
9577 alc88x_simple_mic_automute(codec);
9580 alc_sku_unsol_event(codec, res);
9585 /* toggle speaker-output according to the hp-jack state */
9586 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9588 struct alc_spec *spec = codec->spec;
9590 spec->autocfg.hp_pins[0] = 0x14;
9591 spec->autocfg.speaker_pins[0] = 0x15;
9593 spec->automute_mode = ALC_AUTOMUTE_AMP;
9596 static void alc883_haier_w66_setup(struct hda_codec *codec)
9598 struct alc_spec *spec = codec->spec;
9600 spec->autocfg.hp_pins[0] = 0x1b;
9601 spec->autocfg.speaker_pins[0] = 0x14;
9603 spec->automute_mode = ALC_AUTOMUTE_AMP;
9606 static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9608 struct alc_spec *spec = codec->spec;
9610 spec->autocfg.hp_pins[0] = 0x1b;
9611 spec->autocfg.line_out_pins[0] = 0x14;
9612 spec->autocfg.speaker_pins[0] = 0x15;
9614 spec->detect_line = 1;
9615 spec->automute_lines = 1;
9616 spec->automute_mode = ALC_AUTOMUTE_AMP;
9619 /* toggle speaker-output according to the hp-jack state */
9620 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9622 struct alc_spec *spec = codec->spec;
9624 spec->autocfg.hp_pins[0] = 0x14;
9625 spec->autocfg.speaker_pins[0] = 0x15;
9626 spec->autocfg.speaker_pins[1] = 0x16;
9628 spec->automute_mode = ALC_AUTOMUTE_AMP;
9631 static const struct hda_verb alc883_acer_eapd_verbs[] = {
9632 /* HP Pin: output 0 (0x0c) */
9633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9636 /* Front Pin: output 0 (0x0c) */
9637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9638 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9639 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9640 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9641 /* eanable EAPD on medion laptop */
9642 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9643 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9644 /* enable unsolicited event */
9645 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9649 static void alc888_6st_dell_setup(struct hda_codec *codec)
9651 struct alc_spec *spec = codec->spec;
9653 spec->autocfg.hp_pins[0] = 0x1b;
9654 spec->autocfg.speaker_pins[0] = 0x14;
9655 spec->autocfg.speaker_pins[1] = 0x15;
9656 spec->autocfg.speaker_pins[2] = 0x16;
9657 spec->autocfg.speaker_pins[3] = 0x17;
9659 spec->automute_mode = ALC_AUTOMUTE_AMP;
9662 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9664 struct alc_spec *spec = codec->spec;
9666 spec->autocfg.hp_pins[0] = 0x1b;
9667 spec->autocfg.speaker_pins[0] = 0x14;
9668 spec->autocfg.speaker_pins[1] = 0x15;
9669 spec->autocfg.speaker_pins[2] = 0x16;
9670 spec->autocfg.speaker_pins[3] = 0x17;
9671 spec->autocfg.speaker_pins[4] = 0x1a;
9673 spec->automute_mode = ALC_AUTOMUTE_AMP;
9676 static void alc883_vaiott_setup(struct hda_codec *codec)
9678 struct alc_spec *spec = codec->spec;
9680 spec->autocfg.hp_pins[0] = 0x15;
9681 spec->autocfg.speaker_pins[0] = 0x14;
9682 spec->autocfg.speaker_pins[1] = 0x17;
9684 spec->automute_mode = ALC_AUTOMUTE_AMP;
9687 static const struct hda_verb alc888_asus_m90v_verbs[] = {
9688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9689 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9690 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9691 /* enable unsolicited event */
9692 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9693 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9697 static void alc883_mode2_setup(struct hda_codec *codec)
9699 struct alc_spec *spec = codec->spec;
9701 spec->autocfg.hp_pins[0] = 0x1b;
9702 spec->autocfg.speaker_pins[0] = 0x14;
9703 spec->autocfg.speaker_pins[1] = 0x15;
9704 spec->autocfg.speaker_pins[2] = 0x16;
9705 spec->ext_mic.pin = 0x18;
9706 spec->int_mic.pin = 0x19;
9707 spec->ext_mic.mux_idx = 0;
9708 spec->int_mic.mux_idx = 1;
9711 spec->automute_mode = ALC_AUTOMUTE_AMP;
9714 static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9716 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9718 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9720 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9721 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9722 /* enable unsolicited event */
9723 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9727 static void alc883_eee1601_inithook(struct hda_codec *codec)
9729 struct alc_spec *spec = codec->spec;
9731 spec->autocfg.hp_pins[0] = 0x14;
9732 spec->autocfg.speaker_pins[0] = 0x1b;
9733 alc_hp_automute(codec);
9736 static const struct hda_verb alc889A_mb31_verbs[] = {
9737 /* Init rear pin (used as headphone output) */
9738 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9739 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9740 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9741 /* Init line pin (used as output in 4ch and 6ch mode) */
9742 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9743 /* Init line 2 pin (used as headphone out by default) */
9744 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9745 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9749 /* Mute speakers according to the headphone jack state */
9750 static void alc889A_mb31_automute(struct hda_codec *codec)
9752 unsigned int present;
9754 /* Mute only in 2ch or 4ch mode */
9755 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9757 present = snd_hda_jack_detect(codec, 0x15);
9758 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9759 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9760 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9761 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9765 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9767 if ((res >> 26) == ALC880_HP_EVENT)
9768 alc889A_mb31_automute(codec);
9772 #ifdef CONFIG_SND_HDA_POWER_SAVE
9773 #define alc882_loopbacks alc880_loopbacks
9776 static const hda_nid_t alc883_slave_dig_outs[] = {
9777 ALC1200_DIGOUT_NID, 0,
9780 static const hda_nid_t alc1200_slave_dig_outs[] = {
9781 ALC883_DIGOUT_NID, 0,
9785 * configuration and preset
9787 static const char * const alc882_models[ALC882_MODEL_LAST] = {
9788 [ALC882_3ST_DIG] = "3stack-dig",
9789 [ALC882_6ST_DIG] = "6stack-dig",
9790 [ALC882_ARIMA] = "arima",
9791 [ALC882_W2JC] = "w2jc",
9792 [ALC882_TARGA] = "targa",
9793 [ALC882_ASUS_A7J] = "asus-a7j",
9794 [ALC882_ASUS_A7M] = "asus-a7m",
9795 [ALC885_MACPRO] = "macpro",
9796 [ALC885_MB5] = "mb5",
9797 [ALC885_MACMINI3] = "macmini3",
9798 [ALC885_MBA21] = "mba21",
9799 [ALC885_MBP3] = "mbp3",
9800 [ALC885_IMAC24] = "imac24",
9801 [ALC885_IMAC91] = "imac91",
9802 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9803 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9804 [ALC883_3ST_6ch] = "3stack-6ch",
9805 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9806 [ALC883_TARGA_DIG] = "targa-dig",
9807 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9808 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9809 [ALC883_ACER] = "acer",
9810 [ALC883_ACER_ASPIRE] = "acer-aspire",
9811 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9812 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9813 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9814 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9815 [ALC883_MEDION] = "medion",
9816 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9817 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9818 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9819 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9820 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9821 [ALC888_LENOVO_SKY] = "lenovo-sky",
9822 [ALC883_HAIER_W66] = "haier-w66",
9823 [ALC888_3ST_HP] = "3stack-hp",
9824 [ALC888_6ST_DELL] = "6stack-dell",
9825 [ALC883_MITAC] = "mitac",
9826 [ALC883_CLEVO_M540R] = "clevo-m540r",
9827 [ALC883_CLEVO_M720] = "clevo-m720",
9828 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9829 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9830 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9831 [ALC889A_INTEL] = "intel-alc889a",
9832 [ALC889_INTEL] = "intel-x58",
9833 [ALC1200_ASUS_P5Q] = "asus-p5q",
9834 [ALC889A_MB31] = "mb31",
9835 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9836 [ALC882_AUTO] = "auto",
9839 static const struct snd_pci_quirk alc882_cfg_tbl[] = {
9840 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9842 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9843 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9844 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9845 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9846 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9847 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9848 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9849 ALC888_ACER_ASPIRE_4930G),
9850 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9851 ALC888_ACER_ASPIRE_4930G),
9852 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9853 ALC888_ACER_ASPIRE_8930G),
9854 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9855 ALC888_ACER_ASPIRE_8930G),
9856 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9857 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9858 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9859 ALC888_ACER_ASPIRE_6530G),
9860 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9861 ALC888_ACER_ASPIRE_6530G),
9862 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9863 ALC888_ACER_ASPIRE_7730G),
9864 /* default Acer -- disabled as it causes more problems.
9865 * model=auto should work fine now
9867 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9869 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9871 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
9872 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9873 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9874 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9875 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9876 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9878 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9879 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9880 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9881 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9882 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9883 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9884 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9885 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9886 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9887 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9888 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9890 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9891 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9892 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9893 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9894 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9895 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9896 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9897 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9898 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9900 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9901 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9902 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9903 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9904 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9905 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9906 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9907 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9908 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9909 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9910 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9911 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9912 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9913 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9914 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9915 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9916 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9917 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9918 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9919 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9920 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9921 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9922 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9923 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9924 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9925 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9926 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9927 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9928 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9929 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9930 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9932 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9933 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9934 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9935 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9936 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9937 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9938 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9939 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9940 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9941 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9942 ALC883_FUJITSU_PI2515),
9943 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9944 ALC888_FUJITSU_XA3530),
9945 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9946 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9947 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9948 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9949 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9950 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9951 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9952 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9954 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9955 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9956 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9957 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9958 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9959 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9960 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9965 /* codec SSID table for Intel Mac */
9966 static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9967 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9968 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9969 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9970 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9971 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9972 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9973 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9974 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9975 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9976 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9977 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9978 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9979 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9980 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9981 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9982 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9983 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9984 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9985 * so apparently no perfect solution yet
9987 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9988 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9989 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9993 static const struct alc_config_preset alc882_presets[] = {
9994 [ALC882_3ST_DIG] = {
9995 .mixers = { alc882_base_mixer },
9996 .init_verbs = { alc882_base_init_verbs,
9997 alc882_adc1_init_verbs },
9998 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9999 .dac_nids = alc882_dac_nids,
10000 .dig_out_nid = ALC882_DIGOUT_NID,
10001 .dig_in_nid = ALC882_DIGIN_NID,
10002 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10003 .channel_mode = alc882_ch_modes,
10005 .input_mux = &alc882_capture_source,
10007 [ALC882_6ST_DIG] = {
10008 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10009 .init_verbs = { alc882_base_init_verbs,
10010 alc882_adc1_init_verbs },
10011 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10012 .dac_nids = alc882_dac_nids,
10013 .dig_out_nid = ALC882_DIGOUT_NID,
10014 .dig_in_nid = ALC882_DIGIN_NID,
10015 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10016 .channel_mode = alc882_sixstack_modes,
10017 .input_mux = &alc882_capture_source,
10020 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10021 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10022 alc882_eapd_verbs },
10023 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10024 .dac_nids = alc882_dac_nids,
10025 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10026 .channel_mode = alc882_sixstack_modes,
10027 .input_mux = &alc882_capture_source,
10030 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10031 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10032 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10033 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10034 .dac_nids = alc882_dac_nids,
10035 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10036 .channel_mode = alc880_threestack_modes,
10038 .input_mux = &alc882_capture_source,
10039 .dig_out_nid = ALC882_DIGOUT_NID,
10042 .mixers = { alc885_mba21_mixer },
10043 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10045 .dac_nids = alc882_dac_nids,
10046 .channel_mode = alc885_mba21_ch_modes,
10047 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10048 .input_mux = &alc882_capture_source,
10049 .unsol_event = alc_sku_unsol_event,
10050 .setup = alc885_mba21_setup,
10051 .init_hook = alc_hp_automute,
10054 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10055 .init_verbs = { alc885_mbp3_init_verbs,
10056 alc880_gpio1_init_verbs },
10058 .dac_nids = alc882_dac_nids,
10060 .channel_mode = alc885_mbp_4ch_modes,
10061 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10062 .input_mux = &alc882_capture_source,
10063 .dig_out_nid = ALC882_DIGOUT_NID,
10064 .dig_in_nid = ALC882_DIGIN_NID,
10065 .unsol_event = alc_sku_unsol_event,
10066 .setup = alc885_mbp3_setup,
10067 .init_hook = alc_hp_automute,
10070 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10071 .init_verbs = { alc885_mb5_init_verbs,
10072 alc880_gpio1_init_verbs },
10073 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10074 .dac_nids = alc882_dac_nids,
10075 .channel_mode = alc885_mb5_6ch_modes,
10076 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10077 .input_mux = &mb5_capture_source,
10078 .dig_out_nid = ALC882_DIGOUT_NID,
10079 .dig_in_nid = ALC882_DIGIN_NID,
10080 .unsol_event = alc_sku_unsol_event,
10081 .setup = alc885_mb5_setup,
10082 .init_hook = alc_hp_automute,
10084 [ALC885_MACMINI3] = {
10085 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10086 .init_verbs = { alc885_macmini3_init_verbs,
10087 alc880_gpio1_init_verbs },
10088 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10089 .dac_nids = alc882_dac_nids,
10090 .channel_mode = alc885_macmini3_6ch_modes,
10091 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10092 .input_mux = &macmini3_capture_source,
10093 .dig_out_nid = ALC882_DIGOUT_NID,
10094 .dig_in_nid = ALC882_DIGIN_NID,
10095 .unsol_event = alc_sku_unsol_event,
10096 .setup = alc885_macmini3_setup,
10097 .init_hook = alc_hp_automute,
10099 [ALC885_MACPRO] = {
10100 .mixers = { alc882_macpro_mixer },
10101 .init_verbs = { alc882_macpro_init_verbs },
10102 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10103 .dac_nids = alc882_dac_nids,
10104 .dig_out_nid = ALC882_DIGOUT_NID,
10105 .dig_in_nid = ALC882_DIGIN_NID,
10106 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10107 .channel_mode = alc882_ch_modes,
10108 .input_mux = &alc882_capture_source,
10109 .init_hook = alc885_macpro_init_hook,
10111 [ALC885_IMAC24] = {
10112 .mixers = { alc885_imac24_mixer },
10113 .init_verbs = { alc885_imac24_init_verbs },
10114 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10115 .dac_nids = alc882_dac_nids,
10116 .dig_out_nid = ALC882_DIGOUT_NID,
10117 .dig_in_nid = ALC882_DIGIN_NID,
10118 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10119 .channel_mode = alc882_ch_modes,
10120 .input_mux = &alc882_capture_source,
10121 .unsol_event = alc_sku_unsol_event,
10122 .setup = alc885_imac24_setup,
10123 .init_hook = alc885_imac24_init_hook,
10125 [ALC885_IMAC91] = {
10126 .mixers = {alc885_imac91_mixer},
10127 .init_verbs = { alc885_imac91_init_verbs,
10128 alc880_gpio1_init_verbs },
10129 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10130 .dac_nids = alc882_dac_nids,
10131 .channel_mode = alc885_mba21_ch_modes,
10132 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10133 .input_mux = &alc889A_imac91_capture_source,
10134 .dig_out_nid = ALC882_DIGOUT_NID,
10135 .dig_in_nid = ALC882_DIGIN_NID,
10136 .unsol_event = alc_sku_unsol_event,
10137 .setup = alc885_imac91_setup,
10138 .init_hook = alc_hp_automute,
10141 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10142 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10143 alc880_gpio3_init_verbs, alc882_targa_verbs},
10144 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10145 .dac_nids = alc882_dac_nids,
10146 .dig_out_nid = ALC882_DIGOUT_NID,
10147 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10148 .adc_nids = alc882_adc_nids,
10149 .capsrc_nids = alc882_capsrc_nids,
10150 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10151 .channel_mode = alc882_3ST_6ch_modes,
10153 .input_mux = &alc882_capture_source,
10154 .unsol_event = alc_sku_unsol_event,
10155 .setup = alc882_targa_setup,
10156 .init_hook = alc882_targa_automute,
10158 [ALC882_ASUS_A7J] = {
10159 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10160 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10161 alc882_asus_a7j_verbs},
10162 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10163 .dac_nids = alc882_dac_nids,
10164 .dig_out_nid = ALC882_DIGOUT_NID,
10165 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10166 .adc_nids = alc882_adc_nids,
10167 .capsrc_nids = alc882_capsrc_nids,
10168 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10169 .channel_mode = alc882_3ST_6ch_modes,
10171 .input_mux = &alc882_capture_source,
10173 [ALC882_ASUS_A7M] = {
10174 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10175 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10176 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10177 alc882_asus_a7m_verbs },
10178 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10179 .dac_nids = alc882_dac_nids,
10180 .dig_out_nid = ALC882_DIGOUT_NID,
10181 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10182 .channel_mode = alc880_threestack_modes,
10184 .input_mux = &alc882_capture_source,
10186 [ALC883_3ST_2ch_DIG] = {
10187 .mixers = { alc883_3ST_2ch_mixer },
10188 .init_verbs = { alc883_init_verbs },
10189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10190 .dac_nids = alc883_dac_nids,
10191 .dig_out_nid = ALC883_DIGOUT_NID,
10192 .dig_in_nid = ALC883_DIGIN_NID,
10193 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10194 .channel_mode = alc883_3ST_2ch_modes,
10195 .input_mux = &alc883_capture_source,
10197 [ALC883_3ST_6ch_DIG] = {
10198 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10199 .init_verbs = { alc883_init_verbs },
10200 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10201 .dac_nids = alc883_dac_nids,
10202 .dig_out_nid = ALC883_DIGOUT_NID,
10203 .dig_in_nid = ALC883_DIGIN_NID,
10204 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10205 .channel_mode = alc883_3ST_6ch_modes,
10207 .input_mux = &alc883_capture_source,
10209 [ALC883_3ST_6ch] = {
10210 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10211 .init_verbs = { alc883_init_verbs },
10212 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10213 .dac_nids = alc883_dac_nids,
10214 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10215 .channel_mode = alc883_3ST_6ch_modes,
10217 .input_mux = &alc883_capture_source,
10219 [ALC883_3ST_6ch_INTEL] = {
10220 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10221 .init_verbs = { alc883_init_verbs },
10222 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10223 .dac_nids = alc883_dac_nids,
10224 .dig_out_nid = ALC883_DIGOUT_NID,
10225 .dig_in_nid = ALC883_DIGIN_NID,
10226 .slave_dig_outs = alc883_slave_dig_outs,
10227 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10228 .channel_mode = alc883_3ST_6ch_intel_modes,
10230 .input_mux = &alc883_3stack_6ch_intel,
10232 [ALC889A_INTEL] = {
10233 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10234 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10235 alc_hp15_unsol_verbs },
10236 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10237 .dac_nids = alc883_dac_nids,
10238 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10239 .adc_nids = alc889_adc_nids,
10240 .dig_out_nid = ALC883_DIGOUT_NID,
10241 .dig_in_nid = ALC883_DIGIN_NID,
10242 .slave_dig_outs = alc883_slave_dig_outs,
10243 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10244 .channel_mode = alc889_8ch_intel_modes,
10245 .capsrc_nids = alc889_capsrc_nids,
10246 .input_mux = &alc889_capture_source,
10247 .setup = alc889_automute_setup,
10248 .init_hook = alc_hp_automute,
10249 .unsol_event = alc_sku_unsol_event,
10253 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10254 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10255 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10256 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10257 .dac_nids = alc883_dac_nids,
10258 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10259 .adc_nids = alc889_adc_nids,
10260 .dig_out_nid = ALC883_DIGOUT_NID,
10261 .dig_in_nid = ALC883_DIGIN_NID,
10262 .slave_dig_outs = alc883_slave_dig_outs,
10263 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10264 .channel_mode = alc889_8ch_intel_modes,
10265 .capsrc_nids = alc889_capsrc_nids,
10266 .input_mux = &alc889_capture_source,
10267 .setup = alc889_automute_setup,
10268 .init_hook = alc889_intel_init_hook,
10269 .unsol_event = alc_sku_unsol_event,
10272 [ALC883_6ST_DIG] = {
10273 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10274 .init_verbs = { alc883_init_verbs },
10275 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10276 .dac_nids = alc883_dac_nids,
10277 .dig_out_nid = ALC883_DIGOUT_NID,
10278 .dig_in_nid = ALC883_DIGIN_NID,
10279 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10280 .channel_mode = alc883_sixstack_modes,
10281 .input_mux = &alc883_capture_source,
10283 [ALC883_TARGA_DIG] = {
10284 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10285 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10286 alc883_targa_verbs},
10287 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10288 .dac_nids = alc883_dac_nids,
10289 .dig_out_nid = ALC883_DIGOUT_NID,
10290 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10291 .channel_mode = alc883_3ST_6ch_modes,
10293 .input_mux = &alc883_capture_source,
10294 .unsol_event = alc883_targa_unsol_event,
10295 .setup = alc882_targa_setup,
10296 .init_hook = alc882_targa_automute,
10298 [ALC883_TARGA_2ch_DIG] = {
10299 .mixers = { alc883_targa_2ch_mixer},
10300 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10301 alc883_targa_verbs},
10302 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10303 .dac_nids = alc883_dac_nids,
10304 .adc_nids = alc883_adc_nids_alt,
10305 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10306 .capsrc_nids = alc883_capsrc_nids,
10307 .dig_out_nid = ALC883_DIGOUT_NID,
10308 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10309 .channel_mode = alc883_3ST_2ch_modes,
10310 .input_mux = &alc883_capture_source,
10311 .unsol_event = alc883_targa_unsol_event,
10312 .setup = alc882_targa_setup,
10313 .init_hook = alc882_targa_automute,
10315 [ALC883_TARGA_8ch_DIG] = {
10316 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10317 alc883_chmode_mixer },
10318 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10319 alc883_targa_verbs },
10320 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10321 .dac_nids = alc883_dac_nids,
10322 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10323 .adc_nids = alc883_adc_nids_rev,
10324 .capsrc_nids = alc883_capsrc_nids_rev,
10325 .dig_out_nid = ALC883_DIGOUT_NID,
10326 .dig_in_nid = ALC883_DIGIN_NID,
10327 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10328 .channel_mode = alc883_4ST_8ch_modes,
10330 .input_mux = &alc883_capture_source,
10331 .unsol_event = alc883_targa_unsol_event,
10332 .setup = alc882_targa_setup,
10333 .init_hook = alc882_targa_automute,
10336 .mixers = { alc883_base_mixer },
10337 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10338 * and the headphone jack. Turn this on and rely on the
10339 * standard mute methods whenever the user wants to turn
10340 * these outputs off.
10342 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10343 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10344 .dac_nids = alc883_dac_nids,
10345 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10346 .channel_mode = alc883_3ST_2ch_modes,
10347 .input_mux = &alc883_capture_source,
10349 [ALC883_ACER_ASPIRE] = {
10350 .mixers = { alc883_acer_aspire_mixer },
10351 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10352 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10353 .dac_nids = alc883_dac_nids,
10354 .dig_out_nid = ALC883_DIGOUT_NID,
10355 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10356 .channel_mode = alc883_3ST_2ch_modes,
10357 .input_mux = &alc883_capture_source,
10358 .unsol_event = alc_sku_unsol_event,
10359 .setup = alc883_acer_aspire_setup,
10360 .init_hook = alc_hp_automute,
10362 [ALC888_ACER_ASPIRE_4930G] = {
10363 .mixers = { alc888_acer_aspire_4930g_mixer,
10364 alc883_chmode_mixer },
10365 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10366 alc888_acer_aspire_4930g_verbs },
10367 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10368 .dac_nids = alc883_dac_nids,
10369 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10370 .adc_nids = alc883_adc_nids_rev,
10371 .capsrc_nids = alc883_capsrc_nids_rev,
10372 .dig_out_nid = ALC883_DIGOUT_NID,
10373 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10374 .channel_mode = alc883_3ST_6ch_modes,
10376 .const_channel_count = 6,
10378 ARRAY_SIZE(alc888_2_capture_sources),
10379 .input_mux = alc888_2_capture_sources,
10380 .unsol_event = alc_sku_unsol_event,
10381 .setup = alc888_acer_aspire_4930g_setup,
10382 .init_hook = alc_hp_automute,
10384 [ALC888_ACER_ASPIRE_6530G] = {
10385 .mixers = { alc888_acer_aspire_6530_mixer },
10386 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10387 alc888_acer_aspire_6530g_verbs },
10388 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10389 .dac_nids = alc883_dac_nids,
10390 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10391 .adc_nids = alc883_adc_nids_rev,
10392 .capsrc_nids = alc883_capsrc_nids_rev,
10393 .dig_out_nid = ALC883_DIGOUT_NID,
10394 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10395 .channel_mode = alc883_3ST_2ch_modes,
10397 ARRAY_SIZE(alc888_2_capture_sources),
10398 .input_mux = alc888_acer_aspire_6530_sources,
10399 .unsol_event = alc_sku_unsol_event,
10400 .setup = alc888_acer_aspire_6530g_setup,
10401 .init_hook = alc_hp_automute,
10403 [ALC888_ACER_ASPIRE_8930G] = {
10404 .mixers = { alc889_acer_aspire_8930g_mixer,
10405 alc883_chmode_mixer },
10406 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10407 alc889_acer_aspire_8930g_verbs,
10408 alc889_eapd_verbs},
10409 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10410 .dac_nids = alc883_dac_nids,
10411 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10412 .adc_nids = alc889_adc_nids,
10413 .capsrc_nids = alc889_capsrc_nids,
10414 .dig_out_nid = ALC883_DIGOUT_NID,
10415 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10416 .channel_mode = alc883_3ST_6ch_modes,
10418 .const_channel_count = 6,
10420 ARRAY_SIZE(alc889_capture_sources),
10421 .input_mux = alc889_capture_sources,
10422 .unsol_event = alc_sku_unsol_event,
10423 .setup = alc889_acer_aspire_8930g_setup,
10424 .init_hook = alc_hp_automute,
10425 #ifdef CONFIG_SND_HDA_POWER_SAVE
10426 .power_hook = alc_power_eapd,
10429 [ALC888_ACER_ASPIRE_7730G] = {
10430 .mixers = { alc883_3ST_6ch_mixer,
10431 alc883_chmode_mixer },
10432 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10433 alc888_acer_aspire_7730G_verbs },
10434 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10435 .dac_nids = alc883_dac_nids,
10436 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10437 .adc_nids = alc883_adc_nids_rev,
10438 .capsrc_nids = alc883_capsrc_nids_rev,
10439 .dig_out_nid = ALC883_DIGOUT_NID,
10440 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10441 .channel_mode = alc883_3ST_6ch_modes,
10443 .const_channel_count = 6,
10444 .input_mux = &alc883_capture_source,
10445 .unsol_event = alc_sku_unsol_event,
10446 .setup = alc888_acer_aspire_7730g_setup,
10447 .init_hook = alc_hp_automute,
10449 [ALC883_MEDION] = {
10450 .mixers = { alc883_fivestack_mixer,
10451 alc883_chmode_mixer },
10452 .init_verbs = { alc883_init_verbs,
10453 alc883_medion_eapd_verbs },
10454 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10455 .dac_nids = alc883_dac_nids,
10456 .adc_nids = alc883_adc_nids_alt,
10457 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10458 .capsrc_nids = alc883_capsrc_nids,
10459 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10460 .channel_mode = alc883_sixstack_modes,
10461 .input_mux = &alc883_capture_source,
10463 [ALC883_MEDION_WIM2160] = {
10464 .mixers = { alc883_medion_wim2160_mixer },
10465 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10466 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10467 .dac_nids = alc883_dac_nids,
10468 .dig_out_nid = ALC883_DIGOUT_NID,
10469 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10470 .adc_nids = alc883_adc_nids,
10471 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10472 .channel_mode = alc883_3ST_2ch_modes,
10473 .input_mux = &alc883_capture_source,
10474 .unsol_event = alc_sku_unsol_event,
10475 .setup = alc883_medion_wim2160_setup,
10476 .init_hook = alc_hp_automute,
10478 [ALC883_LAPTOP_EAPD] = {
10479 .mixers = { alc883_base_mixer },
10480 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10482 .dac_nids = alc883_dac_nids,
10483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10484 .channel_mode = alc883_3ST_2ch_modes,
10485 .input_mux = &alc883_capture_source,
10487 [ALC883_CLEVO_M540R] = {
10488 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10489 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10491 .dac_nids = alc883_dac_nids,
10492 .dig_out_nid = ALC883_DIGOUT_NID,
10493 .dig_in_nid = ALC883_DIGIN_NID,
10494 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10495 .channel_mode = alc883_3ST_6ch_clevo_modes,
10497 .input_mux = &alc883_capture_source,
10498 /* This machine has the hardware HP auto-muting, thus
10499 * we need no software mute via unsol event
10502 [ALC883_CLEVO_M720] = {
10503 .mixers = { alc883_clevo_m720_mixer },
10504 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10505 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10506 .dac_nids = alc883_dac_nids,
10507 .dig_out_nid = ALC883_DIGOUT_NID,
10508 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10509 .channel_mode = alc883_3ST_2ch_modes,
10510 .input_mux = &alc883_capture_source,
10511 .unsol_event = alc883_clevo_m720_unsol_event,
10512 .setup = alc883_clevo_m720_setup,
10513 .init_hook = alc883_clevo_m720_init_hook,
10515 [ALC883_LENOVO_101E_2ch] = {
10516 .mixers = { alc883_lenovo_101e_2ch_mixer},
10517 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10518 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10519 .dac_nids = alc883_dac_nids,
10520 .adc_nids = alc883_adc_nids_alt,
10521 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10522 .capsrc_nids = alc883_capsrc_nids,
10523 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10524 .channel_mode = alc883_3ST_2ch_modes,
10525 .input_mux = &alc883_lenovo_101e_capture_source,
10526 .setup = alc883_lenovo_101e_setup,
10527 .unsol_event = alc_sku_unsol_event,
10528 .init_hook = alc_inithook,
10530 [ALC883_LENOVO_NB0763] = {
10531 .mixers = { alc883_lenovo_nb0763_mixer },
10532 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10533 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10534 .dac_nids = alc883_dac_nids,
10535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10536 .channel_mode = alc883_3ST_2ch_modes,
10538 .input_mux = &alc883_lenovo_nb0763_capture_source,
10539 .unsol_event = alc_sku_unsol_event,
10540 .setup = alc883_lenovo_nb0763_setup,
10541 .init_hook = alc_hp_automute,
10543 [ALC888_LENOVO_MS7195_DIG] = {
10544 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10545 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
10548 .dig_out_nid = ALC883_DIGOUT_NID,
10549 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10550 .channel_mode = alc883_3ST_6ch_modes,
10552 .input_mux = &alc883_capture_source,
10553 .unsol_event = alc_sku_unsol_event,
10554 .setup = alc888_lenovo_ms7195_setup,
10555 .init_hook = alc_inithook,
10557 [ALC883_HAIER_W66] = {
10558 .mixers = { alc883_targa_2ch_mixer},
10559 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10561 .dac_nids = alc883_dac_nids,
10562 .dig_out_nid = ALC883_DIGOUT_NID,
10563 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10564 .channel_mode = alc883_3ST_2ch_modes,
10565 .input_mux = &alc883_capture_source,
10566 .unsol_event = alc_sku_unsol_event,
10567 .setup = alc883_haier_w66_setup,
10568 .init_hook = alc_hp_automute,
10570 [ALC888_3ST_HP] = {
10571 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10572 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10573 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10574 .dac_nids = alc883_dac_nids,
10575 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10576 .channel_mode = alc888_3st_hp_modes,
10578 .input_mux = &alc883_capture_source,
10579 .unsol_event = alc_sku_unsol_event,
10580 .setup = alc888_3st_hp_setup,
10581 .init_hook = alc_hp_automute,
10583 [ALC888_6ST_DELL] = {
10584 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10585 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10586 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10587 .dac_nids = alc883_dac_nids,
10588 .dig_out_nid = ALC883_DIGOUT_NID,
10589 .dig_in_nid = ALC883_DIGIN_NID,
10590 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10591 .channel_mode = alc883_sixstack_modes,
10592 .input_mux = &alc883_capture_source,
10593 .unsol_event = alc_sku_unsol_event,
10594 .setup = alc888_6st_dell_setup,
10595 .init_hook = alc_hp_automute,
10598 .mixers = { alc883_mitac_mixer },
10599 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10601 .dac_nids = alc883_dac_nids,
10602 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10603 .channel_mode = alc883_3ST_2ch_modes,
10604 .input_mux = &alc883_capture_source,
10605 .unsol_event = alc_sku_unsol_event,
10606 .setup = alc883_mitac_setup,
10607 .init_hook = alc_hp_automute,
10609 [ALC883_FUJITSU_PI2515] = {
10610 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10611 .init_verbs = { alc883_init_verbs,
10612 alc883_2ch_fujitsu_pi2515_verbs},
10613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10614 .dac_nids = alc883_dac_nids,
10615 .dig_out_nid = ALC883_DIGOUT_NID,
10616 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10617 .channel_mode = alc883_3ST_2ch_modes,
10618 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10619 .unsol_event = alc_sku_unsol_event,
10620 .setup = alc883_2ch_fujitsu_pi2515_setup,
10621 .init_hook = alc_hp_automute,
10623 [ALC888_FUJITSU_XA3530] = {
10624 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10625 .init_verbs = { alc883_init_verbs,
10626 alc888_fujitsu_xa3530_verbs },
10627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10628 .dac_nids = alc883_dac_nids,
10629 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10630 .adc_nids = alc883_adc_nids_rev,
10631 .capsrc_nids = alc883_capsrc_nids_rev,
10632 .dig_out_nid = ALC883_DIGOUT_NID,
10633 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10634 .channel_mode = alc888_4ST_8ch_intel_modes,
10636 ARRAY_SIZE(alc888_2_capture_sources),
10637 .input_mux = alc888_2_capture_sources,
10638 .unsol_event = alc_sku_unsol_event,
10639 .setup = alc888_fujitsu_xa3530_setup,
10640 .init_hook = alc_hp_automute,
10642 [ALC888_LENOVO_SKY] = {
10643 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10644 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10645 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10646 .dac_nids = alc883_dac_nids,
10647 .dig_out_nid = ALC883_DIGOUT_NID,
10648 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10649 .channel_mode = alc883_sixstack_modes,
10651 .input_mux = &alc883_lenovo_sky_capture_source,
10652 .unsol_event = alc_sku_unsol_event,
10653 .setup = alc888_lenovo_sky_setup,
10654 .init_hook = alc_hp_automute,
10656 [ALC888_ASUS_M90V] = {
10657 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10658 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10659 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10660 .dac_nids = alc883_dac_nids,
10661 .dig_out_nid = ALC883_DIGOUT_NID,
10662 .dig_in_nid = ALC883_DIGIN_NID,
10663 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10664 .channel_mode = alc883_3ST_6ch_modes,
10666 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10667 .unsol_event = alc_sku_unsol_event,
10668 .setup = alc883_mode2_setup,
10669 .init_hook = alc_inithook,
10671 [ALC888_ASUS_EEE1601] = {
10672 .mixers = { alc883_asus_eee1601_mixer },
10673 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10674 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10675 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10676 .dac_nids = alc883_dac_nids,
10677 .dig_out_nid = ALC883_DIGOUT_NID,
10678 .dig_in_nid = ALC883_DIGIN_NID,
10679 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10680 .channel_mode = alc883_3ST_2ch_modes,
10682 .input_mux = &alc883_asus_eee1601_capture_source,
10683 .unsol_event = alc_sku_unsol_event,
10684 .init_hook = alc883_eee1601_inithook,
10686 [ALC1200_ASUS_P5Q] = {
10687 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10688 .init_verbs = { alc883_init_verbs },
10689 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10690 .dac_nids = alc883_dac_nids,
10691 .dig_out_nid = ALC1200_DIGOUT_NID,
10692 .dig_in_nid = ALC883_DIGIN_NID,
10693 .slave_dig_outs = alc1200_slave_dig_outs,
10694 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10695 .channel_mode = alc883_sixstack_modes,
10696 .input_mux = &alc883_capture_source,
10699 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10700 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10701 alc880_gpio1_init_verbs },
10702 .adc_nids = alc883_adc_nids,
10703 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10704 .capsrc_nids = alc883_capsrc_nids,
10705 .dac_nids = alc883_dac_nids,
10706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10707 .channel_mode = alc889A_mb31_6ch_modes,
10708 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10709 .input_mux = &alc889A_mb31_capture_source,
10710 .dig_out_nid = ALC883_DIGOUT_NID,
10711 .unsol_event = alc889A_mb31_unsol_event,
10712 .init_hook = alc889A_mb31_automute,
10714 [ALC883_SONY_VAIO_TT] = {
10715 .mixers = { alc883_vaiott_mixer },
10716 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10717 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10718 .dac_nids = alc883_dac_nids,
10719 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10720 .channel_mode = alc883_3ST_2ch_modes,
10721 .input_mux = &alc883_capture_source,
10722 .unsol_event = alc_sku_unsol_event,
10723 .setup = alc883_vaiott_setup,
10724 .init_hook = alc_hp_automute,
10733 PINFIX_ABIT_AW9D_MAX,
10734 PINFIX_LENOVO_Y530,
10736 PINFIX_ACER_ASPIRE_7736,
10739 static const struct alc_fixup alc882_fixups[] = {
10740 [PINFIX_ABIT_AW9D_MAX] = {
10741 .type = ALC_FIXUP_PINS,
10742 .v.pins = (const struct alc_pincfg[]) {
10743 { 0x15, 0x01080104 }, /* side */
10744 { 0x16, 0x01011012 }, /* rear */
10745 { 0x17, 0x01016011 }, /* clfe */
10749 [PINFIX_LENOVO_Y530] = {
10750 .type = ALC_FIXUP_PINS,
10751 .v.pins = (const struct alc_pincfg[]) {
10752 { 0x15, 0x99130112 }, /* rear int speakers */
10753 { 0x16, 0x99130111 }, /* subwoofer */
10757 [PINFIX_PB_M5210] = {
10758 .type = ALC_FIXUP_VERBS,
10759 .v.verbs = (const struct hda_verb[]) {
10760 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10764 [PINFIX_ACER_ASPIRE_7736] = {
10765 .type = ALC_FIXUP_SKU,
10766 .v.sku = ALC_FIXUP_SKU_IGNORE,
10770 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10771 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10772 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10773 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10774 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10779 * BIOS auto configuration
10781 static void alc_auto_init_input_src(struct hda_codec *codec)
10783 struct alc_spec *spec = codec->spec;
10786 if (spec->dual_adc_switch)
10789 for (c = 0; c < spec->num_adc_nids; c++) {
10791 unsigned int mux_idx;
10792 const struct hda_input_mux *imux;
10793 int conns, mute, idx, item;
10794 unsigned int wid_type;
10796 nid = spec->capsrc_nids ?
10797 spec->capsrc_nids[c] : spec->adc_nids[c];
10799 if (query_amp_caps(codec, spec->adc_nids[c], HDA_INPUT) &
10801 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
10802 AC_VERB_SET_AMP_GAIN_MUTE,
10804 else if (query_amp_caps(codec, nid, HDA_OUTPUT) &
10806 snd_hda_codec_write(codec, nid, 0,
10807 AC_VERB_SET_AMP_GAIN_MUTE,
10810 conns = snd_hda_get_conn_list(codec, nid, NULL);
10813 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10814 imux = &spec->input_mux[mux_idx];
10815 if (!imux->num_items && mux_idx > 0)
10816 imux = &spec->input_mux[0];
10817 wid_type = get_wcaps_type(get_wcaps(codec, nid));
10818 for (idx = 0; idx < conns; idx++) {
10819 /* if the current connection is the selected one,
10820 * unmute it as default - otherwise mute it
10822 mute = AMP_IN_MUTE(idx);
10823 for (item = 0; item < imux->num_items; item++) {
10824 if (imux->items[item].index == idx) {
10825 if (spec->cur_mux[c] == item)
10826 mute = AMP_IN_UNMUTE(idx);
10830 /* initialize the mute status if mute-amp is present */
10831 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
10832 snd_hda_codec_write(codec, nid, 0,
10833 AC_VERB_SET_AMP_GAIN_MUTE,
10835 if (wid_type == AC_WID_AUD_SEL &&
10836 mute != AMP_IN_MUTE(idx))
10837 snd_hda_codec_write(codec, nid, 0,
10838 AC_VERB_SET_CONNECT_SEL,
10844 /* add mic boosts if needed */
10845 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10847 struct alc_spec *spec = codec->spec;
10848 struct auto_pin_cfg *cfg = &spec->autocfg;
10852 const char *prev_label = NULL;
10854 for (i = 0; i < cfg->num_inputs; i++) {
10855 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10857 nid = cfg->inputs[i].pin;
10858 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10860 char boost_label[32];
10862 label = hda_get_autocfg_input_label(codec, cfg, i);
10863 if (prev_label && !strcmp(label, prev_label))
10867 prev_label = label;
10869 snprintf(boost_label, sizeof(boost_label),
10870 "%s Boost Volume", label);
10871 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10872 boost_label, type_idx,
10873 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10881 /* almost identical with ALC880 parser... */
10882 static int alc882_parse_auto_config(struct hda_codec *codec)
10884 struct alc_spec *spec = codec->spec;
10885 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10888 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10892 if (!spec->autocfg.line_outs)
10893 return 0; /* can't find valid BIOS pin config */
10895 err = alc_auto_fill_dac_nids(codec);
10898 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
10901 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
10904 err = alc_auto_create_hp_out(codec);
10907 err = alc_auto_create_speaker_out(codec);
10910 err = alc_auto_create_input_ctls(codec);
10914 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10916 alc_auto_parse_digital(codec);
10918 if (spec->kctls.list)
10919 add_mixer(spec, spec->kctls.list);
10921 spec->num_mux_defs = 1;
10922 spec->input_mux = &spec->private_imux[0];
10924 if (!spec->dual_adc_switch)
10925 alc_remove_invalid_adc_nids(codec);
10927 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10929 err = alc_auto_add_mic_boost(codec);
10933 return 1; /* config found */
10936 /* additional initialization for auto-configuration model */
10937 static void alc882_auto_init(struct hda_codec *codec)
10939 struct alc_spec *spec = codec->spec;
10940 alc_auto_init_multi_out(codec);
10941 alc_auto_init_extra_out(codec);
10942 alc_auto_init_analog_input(codec);
10943 alc_auto_init_input_src(codec);
10944 alc_auto_init_digital(codec);
10945 if (spec->unsol_event)
10946 alc_inithook(codec);
10949 static int patch_alc882(struct hda_codec *codec)
10951 struct alc_spec *spec;
10952 int err, board_config;
10954 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10958 codec->spec = spec;
10960 spec->mixer_nid = 0x0b;
10962 switch (codec->vendor_id) {
10967 /* ALC883 and variants */
10968 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10972 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10976 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10977 board_config = snd_hda_check_board_codec_sid_config(codec,
10978 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10980 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10981 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10983 board_config = ALC882_AUTO;
10986 if (board_config == ALC882_AUTO) {
10987 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
10988 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
10991 alc_auto_parse_customize_define(codec);
10993 if (board_config == ALC882_AUTO) {
10994 /* automatic parse from the BIOS config */
10995 err = alc882_parse_auto_config(codec);
11001 "hda_codec: Cannot set up configuration "
11002 "from BIOS. Using base mode...\n");
11003 board_config = ALC882_3ST_DIG;
11007 if (has_cdefine_beep(codec)) {
11008 err = snd_hda_attach_beep_device(codec, 0x1);
11015 if (board_config != ALC882_AUTO)
11016 setup_preset(codec, &alc882_presets[board_config]);
11018 if (!spec->adc_nids && spec->input_mux) {
11019 alc_auto_fill_adc_caps(codec);
11020 alc_remove_invalid_adc_nids(codec);
11023 set_capture_mixer(codec);
11025 if (has_cdefine_beep(codec))
11026 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11028 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11030 spec->vmaster_nid = 0x0c;
11032 codec->patch_ops = alc_patch_ops;
11033 if (board_config == ALC882_AUTO)
11034 spec->init_hook = alc882_auto_init;
11036 alc_init_jacks(codec);
11037 #ifdef CONFIG_SND_HDA_POWER_SAVE
11038 if (!spec->loopback.amplist)
11039 spec->loopback.amplist = alc882_loopbacks;
11050 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11051 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11053 #define alc262_dac_nids alc260_dac_nids
11054 #define alc262_adc_nids alc882_adc_nids
11055 #define alc262_adc_nids_alt alc882_adc_nids_alt
11056 #define alc262_capsrc_nids alc882_capsrc_nids
11057 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11059 #define alc262_modes alc260_modes
11060 #define alc262_capture_source alc882_capture_source
11062 static const hda_nid_t alc262_dmic_adc_nids[1] = {
11067 static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11069 static const struct snd_kcontrol_new alc262_base_mixer[] = {
11070 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11071 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11078 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11080 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11081 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11082 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11084 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11085 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11089 /* update HP, line and mono-out pins according to the master switch */
11090 #define alc262_hp_master_update alc260_hp_master_update
11092 static void alc262_hp_bpc_setup(struct hda_codec *codec)
11094 struct alc_spec *spec = codec->spec;
11096 spec->autocfg.hp_pins[0] = 0x1b;
11097 spec->autocfg.speaker_pins[0] = 0x16;
11098 spec->automute = 1;
11099 spec->automute_mode = ALC_AUTOMUTE_PIN;
11102 static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11104 struct alc_spec *spec = codec->spec;
11106 spec->autocfg.hp_pins[0] = 0x15;
11107 spec->autocfg.speaker_pins[0] = 0x16;
11108 spec->automute = 1;
11109 spec->automute_mode = ALC_AUTOMUTE_PIN;
11112 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11113 #define alc262_hp_master_sw_put alc260_hp_master_sw_put
11115 #define ALC262_HP_MASTER_SWITCH \
11117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11118 .name = "Master Playback Switch", \
11119 .info = snd_ctl_boolean_mono_info, \
11120 .get = alc262_hp_master_sw_get, \
11121 .put = alc262_hp_master_sw_put, \
11124 .iface = NID_MAPPING, \
11125 .name = "Master Playback Switch", \
11126 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11130 static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11131 ALC262_HP_MASTER_SWITCH,
11132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11133 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11135 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11137 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11141 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11142 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11144 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11145 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11146 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11149 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11150 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11154 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11155 ALC262_HP_MASTER_SWITCH,
11156 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11157 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11158 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11160 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11162 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11164 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11165 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11166 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11167 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11168 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11169 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11170 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11174 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11175 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11176 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11177 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11181 /* mute/unmute internal speaker according to the hp jack and mute state */
11182 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11184 struct alc_spec *spec = codec->spec;
11186 spec->autocfg.hp_pins[0] = 0x15;
11187 spec->autocfg.speaker_pins[0] = 0x14;
11188 spec->automute = 1;
11189 spec->automute_mode = ALC_AUTOMUTE_PIN;
11192 static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11193 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11194 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11195 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11196 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11198 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11199 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11203 static const struct hda_verb alc262_hp_t5735_verbs[] = {
11204 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11205 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11207 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11211 static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11215 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11217 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11221 static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11223 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11224 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11225 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11226 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11227 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11230 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11235 static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11242 /* bind hp and internal speaker mute (with plug check) as master switch */
11243 #define alc262_hippo_master_update alc262_hp_master_update
11244 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11245 #define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11247 #define ALC262_HIPPO_MASTER_SWITCH \
11249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11250 .name = "Master Playback Switch", \
11251 .info = snd_ctl_boolean_mono_info, \
11252 .get = alc262_hippo_master_sw_get, \
11253 .put = alc262_hippo_master_sw_put, \
11256 .iface = NID_MAPPING, \
11257 .name = "Master Playback Switch", \
11258 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11259 (SUBDEV_SPEAKER(0) << 16), \
11262 static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11263 ALC262_HIPPO_MASTER_SWITCH,
11264 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11265 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11266 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11267 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11268 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11269 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11270 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11272 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11273 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11274 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11275 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11279 static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11280 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11281 ALC262_HIPPO_MASTER_SWITCH,
11282 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11283 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11284 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11285 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11286 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11289 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11290 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11291 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11295 /* mute/unmute internal speaker according to the hp jack and mute state */
11296 static void alc262_hippo_setup(struct hda_codec *codec)
11298 struct alc_spec *spec = codec->spec;
11300 spec->autocfg.hp_pins[0] = 0x15;
11301 spec->autocfg.speaker_pins[0] = 0x14;
11302 spec->automute = 1;
11303 spec->automute_mode = ALC_AUTOMUTE_AMP;
11306 static void alc262_hippo1_setup(struct hda_codec *codec)
11308 struct alc_spec *spec = codec->spec;
11310 spec->autocfg.hp_pins[0] = 0x1b;
11311 spec->autocfg.speaker_pins[0] = 0x14;
11312 spec->automute = 1;
11313 spec->automute_mode = ALC_AUTOMUTE_AMP;
11317 static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11318 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11319 ALC262_HIPPO_MASTER_SWITCH,
11320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11322 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11323 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11327 static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11328 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11329 ALC262_HIPPO_MASTER_SWITCH,
11330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11331 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11332 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11333 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11334 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11338 static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11339 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11340 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11341 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11342 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11343 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11344 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11350 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11354 static const struct hda_verb alc262_tyan_verbs[] = {
11355 /* Headphone automute */
11356 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11357 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11358 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11360 /* P11 AUX_IN, white 4-pin connector */
11361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11362 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11363 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11364 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11369 /* unsolicited event for HP jack sensing */
11370 static void alc262_tyan_setup(struct hda_codec *codec)
11372 struct alc_spec *spec = codec->spec;
11374 spec->autocfg.hp_pins[0] = 0x1b;
11375 spec->autocfg.speaker_pins[0] = 0x15;
11376 spec->automute = 1;
11377 spec->automute_mode = ALC_AUTOMUTE_AMP;
11381 #define alc262_capture_mixer alc882_capture_mixer
11382 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11385 * generic initialization of ADC, input mixers and output mixers
11387 static const struct hda_verb alc262_init_verbs[] = {
11389 * Unmute ADC0-2 and set the default input to mic-in
11391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11395 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11398 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11400 * Note: PASD motherboards uses the Line In 2 as the input for
11401 * front panel mic (mic 2)
11403 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11411 * Set up output mixers (0x0c - 0x0e)
11413 /* set vol=0 to output mixers */
11414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11416 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11417 /* set up input amps for analog loopback */
11418 /* Amp Indices: DAC = 0, mixer = 1 */
11419 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11427 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11428 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11431 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11433 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11435 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11436 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11439 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11442 /* FIXME: use matrix-type input source selection */
11443 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11444 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11463 static const struct hda_verb alc262_eapd_verbs[] = {
11464 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11465 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11469 static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11471 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11472 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11475 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11479 static const struct hda_verb alc262_sony_unsol_verbs[] = {
11480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11481 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11484 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11489 static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11490 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11491 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11492 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11498 static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11499 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11502 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11503 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11504 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11505 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11506 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11510 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11512 struct alc_spec *spec = codec->spec;
11514 spec->autocfg.hp_pins[0] = 0x15;
11515 spec->autocfg.speaker_pins[0] = 0x14;
11516 spec->ext_mic.pin = 0x18;
11517 spec->ext_mic.mux_idx = 0;
11518 spec->int_mic.pin = 0x12;
11519 spec->int_mic.mux_idx = 9;
11520 spec->auto_mic = 1;
11521 spec->automute = 1;
11522 spec->automute_mode = ALC_AUTOMUTE_PIN;
11528 * 0x16 = internal speaker
11529 * 0x18 = external mic
11532 static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11533 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11534 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11536 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11538 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11540 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11545 static const struct hda_verb alc262_nec_verbs[] = {
11546 /* Unmute Speaker */
11547 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11550 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11553 /* External mic to headphone */
11554 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11555 /* External mic to speaker */
11556 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11562 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11563 * 0x1b = port replicator headphone out
11566 #define ALC_HP_EVENT ALC880_HP_EVENT
11568 static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11569 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11571 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11576 static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11577 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11578 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11582 static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11583 /* Front Mic pin: input vref at 50% */
11584 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11585 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11589 static const struct hda_input_mux alc262_fujitsu_capture_source = {
11593 { "Internal Mic", 0x1 },
11598 static const struct hda_input_mux alc262_HP_capture_source = {
11602 { "Front Mic", 0x1 },
11609 static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11613 { "Front Mic", 0x2 },
11619 static void alc262_fujitsu_setup(struct hda_codec *codec)
11621 struct alc_spec *spec = codec->spec;
11623 spec->autocfg.hp_pins[0] = 0x14;
11624 spec->autocfg.hp_pins[1] = 0x1b;
11625 spec->autocfg.speaker_pins[0] = 0x15;
11626 spec->automute = 1;
11627 spec->automute_mode = ALC_AUTOMUTE_AMP;
11630 /* bind volumes of both NID 0x0c and 0x0d */
11631 static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11632 .ops = &snd_hda_bind_vol,
11634 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11635 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11640 static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11641 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11643 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11644 .name = "Master Playback Switch",
11645 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11646 .info = snd_ctl_boolean_mono_info,
11647 .get = alc262_hp_master_sw_get,
11648 .put = alc262_hp_master_sw_put,
11651 .iface = NID_MAPPING,
11652 .name = "Master Playback Switch",
11653 .private_value = 0x1b,
11655 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11656 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11657 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11658 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11660 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11661 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11662 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11666 static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11668 struct alc_spec *spec = codec->spec;
11670 spec->autocfg.hp_pins[0] = 0x1b;
11671 spec->autocfg.speaker_pins[0] = 0x14;
11672 spec->autocfg.speaker_pins[1] = 0x16;
11673 spec->automute = 1;
11674 spec->automute_mode = ALC_AUTOMUTE_AMP;
11677 static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11678 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11681 .name = "Master Playback Switch",
11682 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11683 .info = snd_ctl_boolean_mono_info,
11684 .get = alc262_hp_master_sw_get,
11685 .put = alc262_hp_master_sw_put,
11687 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11688 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11689 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11692 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11693 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11694 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11698 static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11699 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11700 ALC262_HIPPO_MASTER_SWITCH,
11701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11703 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11704 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11705 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11710 /* additional init verbs for Benq laptops */
11711 static const struct hda_verb alc262_EAPD_verbs[] = {
11712 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11713 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11717 static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11718 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11721 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11722 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11726 /* Samsung Q1 Ultra Vista model setup */
11727 static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
11728 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11729 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11732 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11733 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11737 static const struct hda_verb alc262_ultra_verbs[] = {
11739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11744 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11746 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11752 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11754 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11755 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11756 /* ADC, choose mic */
11757 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11770 /* mute/unmute internal speaker according to the hp jack and mute state */
11771 static void alc262_ultra_automute(struct hda_codec *codec)
11773 struct alc_spec *spec = codec->spec;
11777 /* auto-mute only when HP is used as HP */
11778 if (!spec->cur_mux[0]) {
11779 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11780 if (spec->jack_present)
11781 mute = HDA_AMP_MUTE;
11783 /* mute/unmute internal speaker */
11784 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11785 HDA_AMP_MUTE, mute);
11786 /* mute/unmute HP */
11787 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11788 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11791 /* unsolicited event for HP jack sensing */
11792 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11795 if ((res >> 26) != ALC880_HP_EVENT)
11797 alc262_ultra_automute(codec);
11800 static const struct hda_input_mux alc262_ultra_capture_source = {
11804 { "Headphone", 0x7 },
11808 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11809 struct snd_ctl_elem_value *ucontrol)
11811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11812 struct alc_spec *spec = codec->spec;
11815 ret = alc_mux_enum_put(kcontrol, ucontrol);
11818 /* reprogram the HP pin as mic or HP according to the input source */
11819 snd_hda_codec_write_cache(codec, 0x15, 0,
11820 AC_VERB_SET_PIN_WIDGET_CONTROL,
11821 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11822 alc262_ultra_automute(codec); /* mute/unmute HP */
11826 static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11827 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11828 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11830 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11831 .name = "Capture Source",
11832 .info = alc_mux_enum_info,
11833 .get = alc_mux_enum_get,
11834 .put = alc262_ultra_mux_enum_put,
11837 .iface = NID_MAPPING,
11838 .name = "Capture Source",
11839 .private_value = 0x15,
11844 /* We use two mixers depending on the output pin; 0x16 is a mono output
11845 * and thus it's bound with a different mixer.
11846 * This function returns which mixer amp should be used.
11848 static int alc262_check_volbit(hda_nid_t nid)
11852 else if (nid == 0x16)
11858 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11859 const char *pfx, int *vbits, int idx)
11864 vbit = alc262_check_volbit(nid);
11867 if (*vbits & vbit) /* a volume control for this mixer already there */
11871 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11873 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11874 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
11877 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11878 const char *pfx, int idx)
11885 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11887 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11888 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
11891 /* add playback controls from the parsed DAC table */
11892 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11893 const struct auto_pin_cfg *cfg)
11899 spec->multiout.num_dacs = 1; /* only use one dac */
11900 spec->multiout.dac_nids = spec->private_dac_nids;
11901 spec->private_dac_nids[0] = 2;
11903 for (i = 0; i < 2; i++) {
11904 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11907 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
11911 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11912 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
11917 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11918 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
11925 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11926 alc262_check_volbit(cfg->speaker_pins[0]) |
11927 alc262_check_volbit(cfg->hp_pins[0]);
11929 for (i = 0; i < 2; i++) {
11930 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11933 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
11937 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11938 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
11939 "Speaker", &vbits, i);
11943 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11944 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
11945 "Headphone", &vbits, i);
11953 static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
11955 * Unmute ADC0-2 and set the default input to mic-in
11957 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11959 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11961 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11962 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11964 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11966 * Note: PASD motherboards uses the Line In 2 as the input for
11967 * front panel mic (mic 2)
11969 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11970 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11971 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11972 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11979 * Set up output mixers (0x0c - 0x0e)
11981 /* set vol=0 to output mixers */
11982 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11983 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11984 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11986 /* set up input amps for analog loopback */
11987 /* Amp Indices: DAC = 0, mixer = 1 */
11988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11989 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11992 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11995 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11997 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11999 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12002 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12005 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12007 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12008 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12009 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12012 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12015 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12016 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12019 /* FIXME: use matrix-type input source selection */
12020 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12021 /* Input mixer1: only unmute Mic */
12022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12032 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12033 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12034 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12035 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12036 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12037 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12038 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12039 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12049 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12052 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12057 static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12059 * Unmute ADC0-2 and set the default input to mic-in
12061 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12063 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12064 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12065 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12066 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12068 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12070 * Note: PASD motherboards uses the Line In 2 as the input for front
12071 * panel mic (mic 2)
12073 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12074 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12075 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12076 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12077 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12078 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12083 * Set up output mixers (0x0c - 0x0e)
12085 /* set vol=0 to output mixers */
12086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12087 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12090 /* set up input amps for analog loopback */
12091 /* Amp Indices: DAC = 0, mixer = 1 */
12092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12094 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12095 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12096 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12102 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12103 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12105 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12106 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12108 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12111 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12114 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12115 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12116 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12117 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12118 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12119 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12121 /* FIXME: use matrix-type input source selection */
12122 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12123 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12125 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12128 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12129 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12130 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12132 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12133 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12134 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12135 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12137 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12145 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12148 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12153 static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12155 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12156 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12157 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12159 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12160 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12162 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12165 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12166 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12178 static const struct alc_fixup alc262_fixups[] = {
12179 [PINFIX_FSC_H270] = {
12180 .type = ALC_FIXUP_PINS,
12181 .v.pins = (const struct alc_pincfg[]) {
12182 { 0x14, 0x99130110 }, /* speaker */
12183 { 0x15, 0x0221142f }, /* front HP */
12184 { 0x1b, 0x0121141f }, /* rear HP */
12188 [PINFIX_HP_Z200] = {
12189 .type = ALC_FIXUP_PINS,
12190 .v.pins = (const struct alc_pincfg[]) {
12191 { 0x16, 0x99130120 }, /* internal speaker */
12197 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12198 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12199 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12204 #ifdef CONFIG_SND_HDA_POWER_SAVE
12205 #define alc262_loopbacks alc880_loopbacks
12209 * BIOS auto configuration
12211 static int alc262_parse_auto_config(struct hda_codec *codec)
12213 struct alc_spec *spec = codec->spec;
12215 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12217 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12221 if (!spec->autocfg.line_outs) {
12222 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12223 spec->multiout.max_channels = 2;
12224 spec->no_analog = 1;
12227 return 0; /* can't find valid BIOS pin config */
12229 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12232 err = alc_auto_create_input_ctls(codec);
12236 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12239 alc_auto_parse_digital(codec);
12241 if (spec->kctls.list)
12242 add_mixer(spec, spec->kctls.list);
12244 spec->num_mux_defs = 1;
12245 spec->input_mux = &spec->private_imux[0];
12247 if (!spec->dual_adc_switch)
12248 alc_remove_invalid_adc_nids(codec);
12250 err = alc_auto_add_mic_boost(codec);
12254 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12260 /* init callback for auto-configuration model -- overriding the default init */
12261 static void alc262_auto_init(struct hda_codec *codec)
12263 struct alc_spec *spec = codec->spec;
12264 alc_auto_init_multi_out(codec);
12265 alc_auto_init_extra_out(codec);
12266 alc_auto_init_analog_input(codec);
12267 alc_auto_init_input_src(codec);
12268 alc_auto_init_digital(codec);
12269 if (spec->unsol_event)
12270 alc_inithook(codec);
12274 * configuration and preset
12276 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12277 [ALC262_BASIC] = "basic",
12278 [ALC262_HIPPO] = "hippo",
12279 [ALC262_HIPPO_1] = "hippo_1",
12280 [ALC262_FUJITSU] = "fujitsu",
12281 [ALC262_HP_BPC] = "hp-bpc",
12282 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12283 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12284 [ALC262_HP_RP5700] = "hp-rp5700",
12285 [ALC262_BENQ_ED8] = "benq",
12286 [ALC262_BENQ_T31] = "benq-t31",
12287 [ALC262_SONY_ASSAMD] = "sony-assamd",
12288 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12289 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12290 [ALC262_ULTRA] = "ultra",
12291 [ALC262_LENOVO_3000] = "lenovo-3000",
12292 [ALC262_NEC] = "nec",
12293 [ALC262_TYAN] = "tyan",
12294 [ALC262_AUTO] = "auto",
12297 static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12298 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12299 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12300 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12302 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12304 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12306 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12308 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12310 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12311 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12312 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12313 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12314 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12315 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12316 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12317 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12318 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12319 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12320 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12321 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12322 ALC262_HP_TC_T5735),
12323 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12324 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12325 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12326 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12327 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12328 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12329 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12330 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12331 #if 0 /* disable the quirk since model=auto works better in recent versions */
12332 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12333 ALC262_SONY_ASSAMD),
12335 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12336 ALC262_TOSHIBA_RX1),
12337 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12338 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12339 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12340 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12341 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12343 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12344 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12345 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12346 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12347 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12351 static const struct alc_config_preset alc262_presets[] = {
12353 .mixers = { alc262_base_mixer },
12354 .init_verbs = { alc262_init_verbs },
12355 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12356 .dac_nids = alc262_dac_nids,
12358 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12359 .channel_mode = alc262_modes,
12360 .input_mux = &alc262_capture_source,
12363 .mixers = { alc262_hippo_mixer },
12364 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12365 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12366 .dac_nids = alc262_dac_nids,
12368 .dig_out_nid = ALC262_DIGOUT_NID,
12369 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12370 .channel_mode = alc262_modes,
12371 .input_mux = &alc262_capture_source,
12372 .unsol_event = alc_sku_unsol_event,
12373 .setup = alc262_hippo_setup,
12374 .init_hook = alc_inithook,
12376 [ALC262_HIPPO_1] = {
12377 .mixers = { alc262_hippo1_mixer },
12378 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12379 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12380 .dac_nids = alc262_dac_nids,
12382 .dig_out_nid = ALC262_DIGOUT_NID,
12383 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12384 .channel_mode = alc262_modes,
12385 .input_mux = &alc262_capture_source,
12386 .unsol_event = alc_sku_unsol_event,
12387 .setup = alc262_hippo1_setup,
12388 .init_hook = alc_inithook,
12390 [ALC262_FUJITSU] = {
12391 .mixers = { alc262_fujitsu_mixer },
12392 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12393 alc262_fujitsu_unsol_verbs },
12394 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12395 .dac_nids = alc262_dac_nids,
12397 .dig_out_nid = ALC262_DIGOUT_NID,
12398 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12399 .channel_mode = alc262_modes,
12400 .input_mux = &alc262_fujitsu_capture_source,
12401 .unsol_event = alc_sku_unsol_event,
12402 .setup = alc262_fujitsu_setup,
12403 .init_hook = alc_inithook,
12405 [ALC262_HP_BPC] = {
12406 .mixers = { alc262_HP_BPC_mixer },
12407 .init_verbs = { alc262_HP_BPC_init_verbs },
12408 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12409 .dac_nids = alc262_dac_nids,
12411 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12412 .channel_mode = alc262_modes,
12413 .input_mux = &alc262_HP_capture_source,
12414 .unsol_event = alc_sku_unsol_event,
12415 .setup = alc262_hp_bpc_setup,
12416 .init_hook = alc_inithook,
12418 [ALC262_HP_BPC_D7000_WF] = {
12419 .mixers = { alc262_HP_BPC_WildWest_mixer },
12420 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12421 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12422 .dac_nids = alc262_dac_nids,
12424 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12425 .channel_mode = alc262_modes,
12426 .input_mux = &alc262_HP_D7000_capture_source,
12427 .unsol_event = alc_sku_unsol_event,
12428 .setup = alc262_hp_wildwest_setup,
12429 .init_hook = alc_inithook,
12431 [ALC262_HP_BPC_D7000_WL] = {
12432 .mixers = { alc262_HP_BPC_WildWest_mixer,
12433 alc262_HP_BPC_WildWest_option_mixer },
12434 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12435 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12436 .dac_nids = alc262_dac_nids,
12438 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12439 .channel_mode = alc262_modes,
12440 .input_mux = &alc262_HP_D7000_capture_source,
12441 .unsol_event = alc_sku_unsol_event,
12442 .setup = alc262_hp_wildwest_setup,
12443 .init_hook = alc_inithook,
12445 [ALC262_HP_TC_T5735] = {
12446 .mixers = { alc262_hp_t5735_mixer },
12447 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12448 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12449 .dac_nids = alc262_dac_nids,
12451 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12452 .channel_mode = alc262_modes,
12453 .input_mux = &alc262_capture_source,
12454 .unsol_event = alc_sku_unsol_event,
12455 .setup = alc262_hp_t5735_setup,
12456 .init_hook = alc_inithook,
12458 [ALC262_HP_RP5700] = {
12459 .mixers = { alc262_hp_rp5700_mixer },
12460 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12461 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12462 .dac_nids = alc262_dac_nids,
12463 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12464 .channel_mode = alc262_modes,
12465 .input_mux = &alc262_hp_rp5700_capture_source,
12467 [ALC262_BENQ_ED8] = {
12468 .mixers = { alc262_base_mixer },
12469 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12470 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12471 .dac_nids = alc262_dac_nids,
12473 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12474 .channel_mode = alc262_modes,
12475 .input_mux = &alc262_capture_source,
12477 [ALC262_SONY_ASSAMD] = {
12478 .mixers = { alc262_sony_mixer },
12479 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12480 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12481 .dac_nids = alc262_dac_nids,
12483 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12484 .channel_mode = alc262_modes,
12485 .input_mux = &alc262_capture_source,
12486 .unsol_event = alc_sku_unsol_event,
12487 .setup = alc262_hippo_setup,
12488 .init_hook = alc_inithook,
12490 [ALC262_BENQ_T31] = {
12491 .mixers = { alc262_benq_t31_mixer },
12492 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12493 alc_hp15_unsol_verbs },
12494 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12495 .dac_nids = alc262_dac_nids,
12497 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12498 .channel_mode = alc262_modes,
12499 .input_mux = &alc262_capture_source,
12500 .unsol_event = alc_sku_unsol_event,
12501 .setup = alc262_hippo_setup,
12502 .init_hook = alc_inithook,
12505 .mixers = { alc262_ultra_mixer },
12506 .cap_mixer = alc262_ultra_capture_mixer,
12507 .init_verbs = { alc262_ultra_verbs },
12508 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12509 .dac_nids = alc262_dac_nids,
12510 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12511 .channel_mode = alc262_modes,
12512 .input_mux = &alc262_ultra_capture_source,
12513 .adc_nids = alc262_adc_nids, /* ADC0 */
12514 .capsrc_nids = alc262_capsrc_nids,
12515 .num_adc_nids = 1, /* single ADC */
12516 .unsol_event = alc262_ultra_unsol_event,
12517 .init_hook = alc262_ultra_automute,
12519 [ALC262_LENOVO_3000] = {
12520 .mixers = { alc262_lenovo_3000_mixer },
12521 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12522 alc262_lenovo_3000_unsol_verbs,
12523 alc262_lenovo_3000_init_verbs },
12524 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12525 .dac_nids = alc262_dac_nids,
12527 .dig_out_nid = ALC262_DIGOUT_NID,
12528 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12529 .channel_mode = alc262_modes,
12530 .input_mux = &alc262_fujitsu_capture_source,
12531 .unsol_event = alc_sku_unsol_event,
12532 .setup = alc262_lenovo_3000_setup,
12533 .init_hook = alc_inithook,
12536 .mixers = { alc262_nec_mixer },
12537 .init_verbs = { alc262_nec_verbs },
12538 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12539 .dac_nids = alc262_dac_nids,
12541 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12542 .channel_mode = alc262_modes,
12543 .input_mux = &alc262_capture_source,
12545 [ALC262_TOSHIBA_S06] = {
12546 .mixers = { alc262_toshiba_s06_mixer },
12547 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12548 alc262_eapd_verbs },
12549 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12550 .capsrc_nids = alc262_dmic_capsrc_nids,
12551 .dac_nids = alc262_dac_nids,
12552 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12553 .num_adc_nids = 1, /* single ADC */
12554 .dig_out_nid = ALC262_DIGOUT_NID,
12555 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12556 .channel_mode = alc262_modes,
12557 .unsol_event = alc_sku_unsol_event,
12558 .setup = alc262_toshiba_s06_setup,
12559 .init_hook = alc_inithook,
12561 [ALC262_TOSHIBA_RX1] = {
12562 .mixers = { alc262_toshiba_rx1_mixer },
12563 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12564 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12565 .dac_nids = alc262_dac_nids,
12567 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12568 .channel_mode = alc262_modes,
12569 .input_mux = &alc262_capture_source,
12570 .unsol_event = alc_sku_unsol_event,
12571 .setup = alc262_hippo_setup,
12572 .init_hook = alc_inithook,
12575 .mixers = { alc262_tyan_mixer },
12576 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12577 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12578 .dac_nids = alc262_dac_nids,
12580 .dig_out_nid = ALC262_DIGOUT_NID,
12581 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12582 .channel_mode = alc262_modes,
12583 .input_mux = &alc262_capture_source,
12584 .unsol_event = alc_sku_unsol_event,
12585 .setup = alc262_tyan_setup,
12586 .init_hook = alc_hp_automute,
12590 static int patch_alc262(struct hda_codec *codec)
12592 struct alc_spec *spec;
12596 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12600 codec->spec = spec;
12602 spec->mixer_nid = 0x0b;
12605 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12610 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12611 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12612 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12613 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12616 alc_auto_parse_customize_define(codec);
12618 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12620 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12624 if (board_config < 0) {
12625 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12627 board_config = ALC262_AUTO;
12630 if (board_config == ALC262_AUTO) {
12631 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12632 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12635 if (board_config == ALC262_AUTO) {
12636 /* automatic parse from the BIOS config */
12637 err = alc262_parse_auto_config(codec);
12643 "hda_codec: Cannot set up configuration "
12644 "from BIOS. Using base mode...\n");
12645 board_config = ALC262_BASIC;
12649 if (!spec->no_analog && has_cdefine_beep(codec)) {
12650 err = snd_hda_attach_beep_device(codec, 0x1);
12657 if (board_config != ALC262_AUTO)
12658 setup_preset(codec, &alc262_presets[board_config]);
12660 if (!spec->adc_nids && spec->input_mux) {
12661 alc_auto_fill_adc_caps(codec);
12662 alc_remove_invalid_adc_nids(codec);
12664 if (!spec->cap_mixer && !spec->no_analog)
12665 set_capture_mixer(codec);
12666 if (!spec->no_analog && has_cdefine_beep(codec))
12667 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12669 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
12671 spec->vmaster_nid = 0x0c;
12673 codec->patch_ops = alc_patch_ops;
12674 if (board_config == ALC262_AUTO)
12675 spec->init_hook = alc262_auto_init;
12676 spec->shutup = alc_eapd_shutup;
12678 alc_init_jacks(codec);
12679 #ifdef CONFIG_SND_HDA_POWER_SAVE
12680 if (!spec->loopback.amplist)
12681 spec->loopback.amplist = alc262_loopbacks;
12688 * ALC268 channel source setting (2 channel)
12690 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12691 #define alc268_modes alc260_modes
12693 static const hda_nid_t alc268_dac_nids[2] = {
12698 static const hda_nid_t alc268_adc_nids[2] = {
12703 static const hda_nid_t alc268_adc_nids_alt[1] = {
12708 static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12710 static const struct snd_kcontrol_new alc268_base_mixer[] = {
12711 /* output mixer control */
12712 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12713 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12714 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12715 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12716 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12717 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12718 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12722 static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12723 /* output mixer control */
12724 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12726 ALC262_HIPPO_MASTER_SWITCH,
12727 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12729 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12733 /* bind Beep switches of both NID 0x0f and 0x10 */
12734 static const struct hda_bind_ctls alc268_bind_beep_sw = {
12735 .ops = &snd_hda_bind_sw,
12737 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12738 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12743 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
12744 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12745 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12749 static const struct hda_verb alc268_eapd_verbs[] = {
12750 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12751 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12755 /* Toshiba specific */
12756 static const struct hda_verb alc268_toshiba_verbs[] = {
12757 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12761 /* Acer specific */
12762 /* bind volumes of both NID 0x02 and 0x03 */
12763 static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
12764 .ops = &snd_hda_bind_vol,
12766 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12767 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12772 static void alc268_acer_setup(struct hda_codec *codec)
12774 struct alc_spec *spec = codec->spec;
12776 spec->autocfg.hp_pins[0] = 0x14;
12777 spec->autocfg.speaker_pins[0] = 0x15;
12778 spec->automute = 1;
12779 spec->automute_mode = ALC_AUTOMUTE_AMP;
12782 #define alc268_acer_master_sw_get alc262_hp_master_sw_get
12783 #define alc268_acer_master_sw_put alc262_hp_master_sw_put
12785 static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12786 /* output mixer control */
12787 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12790 .name = "Master Playback Switch",
12791 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12792 .info = snd_ctl_boolean_mono_info,
12793 .get = alc268_acer_master_sw_get,
12794 .put = alc268_acer_master_sw_put,
12796 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12800 static const struct snd_kcontrol_new alc268_acer_mixer[] = {
12801 /* output mixer control */
12802 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12805 .name = "Master Playback Switch",
12806 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12807 .info = snd_ctl_boolean_mono_info,
12808 .get = alc268_acer_master_sw_get,
12809 .put = alc268_acer_master_sw_put,
12811 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12812 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12813 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12817 static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12818 /* output mixer control */
12819 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12821 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12822 .name = "Master Playback Switch",
12823 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12824 .info = snd_ctl_boolean_mono_info,
12825 .get = alc268_acer_master_sw_get,
12826 .put = alc268_acer_master_sw_put,
12828 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12829 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12833 static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
12834 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12835 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12836 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12837 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12838 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12843 static const struct hda_verb alc268_acer_verbs[] = {
12844 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12845 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12846 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12848 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12849 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12850 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12854 /* unsolicited event for HP jack sensing */
12855 #define alc268_toshiba_setup alc262_hippo_setup
12857 static void alc268_acer_lc_setup(struct hda_codec *codec)
12859 struct alc_spec *spec = codec->spec;
12860 spec->autocfg.hp_pins[0] = 0x15;
12861 spec->autocfg.speaker_pins[0] = 0x14;
12862 spec->automute = 1;
12863 spec->automute_mode = ALC_AUTOMUTE_AMP;
12864 spec->ext_mic.pin = 0x18;
12865 spec->ext_mic.mux_idx = 0;
12866 spec->int_mic.pin = 0x12;
12867 spec->int_mic.mux_idx = 6;
12868 spec->auto_mic = 1;
12871 static const struct snd_kcontrol_new alc268_dell_mixer[] = {
12872 /* output mixer control */
12873 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12874 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12875 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12877 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12878 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12882 static const struct hda_verb alc268_dell_verbs[] = {
12883 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12885 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12886 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12890 /* mute/unmute internal speaker according to the hp jack and mute state */
12891 static void alc268_dell_setup(struct hda_codec *codec)
12893 struct alc_spec *spec = codec->spec;
12895 spec->autocfg.hp_pins[0] = 0x15;
12896 spec->autocfg.speaker_pins[0] = 0x14;
12897 spec->ext_mic.pin = 0x18;
12898 spec->ext_mic.mux_idx = 0;
12899 spec->int_mic.pin = 0x19;
12900 spec->int_mic.mux_idx = 1;
12901 spec->auto_mic = 1;
12902 spec->automute = 1;
12903 spec->automute_mode = ALC_AUTOMUTE_PIN;
12906 static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12907 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12908 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12909 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12910 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12912 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12913 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12914 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12918 static const struct hda_verb alc267_quanta_il1_verbs[] = {
12919 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12920 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12924 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12926 struct alc_spec *spec = codec->spec;
12927 spec->autocfg.hp_pins[0] = 0x15;
12928 spec->autocfg.speaker_pins[0] = 0x14;
12929 spec->ext_mic.pin = 0x18;
12930 spec->ext_mic.mux_idx = 0;
12931 spec->int_mic.pin = 0x19;
12932 spec->int_mic.mux_idx = 1;
12933 spec->auto_mic = 1;
12934 spec->automute = 1;
12935 spec->automute_mode = ALC_AUTOMUTE_PIN;
12939 * generic initialization of ADC, input mixers and output mixers
12941 static const struct hda_verb alc268_base_init_verbs[] = {
12942 /* Unmute DAC0-1 and set vol = 0 */
12943 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12944 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12947 * Set up output mixers (0x0c - 0x0e)
12949 /* set vol=0 to output mixers */
12950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12951 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12953 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12957 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12958 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12959 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12960 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12961 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12962 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12963 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12965 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12966 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12967 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12968 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12969 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12971 /* set PCBEEP vol = 0, mute connections */
12972 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12973 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12974 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12976 /* Unmute Selector 23h,24h and set the default input to mic-in */
12978 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12979 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12980 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12981 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12986 /* only for model=test */
12987 #ifdef CONFIG_SND_DEBUG
12989 * generic initialization of ADC, input mixers and output mixers
12991 static const struct hda_verb alc268_volume_init_verbs[] = {
12992 /* set output DAC */
12993 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12994 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12996 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12998 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12999 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13000 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13010 #endif /* CONFIG_SND_DEBUG */
13012 /* set PCBEEP vol = 0, mute connections */
13013 static const struct hda_verb alc268_beep_init_verbs[] = {
13014 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13015 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13016 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13020 static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13021 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13022 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13026 static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13027 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13028 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13033 static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13034 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13035 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13036 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13037 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13042 static const struct hda_input_mux alc268_capture_source = {
13046 { "Front Mic", 0x1 },
13052 static const struct hda_input_mux alc268_acer_capture_source = {
13056 { "Internal Mic", 0x1 },
13061 static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13065 { "Internal Mic", 0x6 },
13070 #ifdef CONFIG_SND_DEBUG
13071 static const struct snd_kcontrol_new alc268_test_mixer[] = {
13072 /* Volume widgets */
13073 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13074 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13075 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13076 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13077 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13078 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13079 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13080 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13081 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13082 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13083 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13084 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13085 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13086 /* The below appears problematic on some hardwares */
13087 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13088 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13089 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13090 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13091 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13093 /* Modes for retasking pin widgets */
13094 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13095 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13096 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13097 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13099 /* Controls for GPIO pins, assuming they are configured as outputs */
13100 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13101 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13102 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13103 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13105 /* Switches to allow the digital SPDIF output pin to be enabled.
13106 * The ALC268 does not have an SPDIF input.
13108 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13110 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13111 * this output to turn on an external amplifier.
13113 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13114 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13120 /* create input playback/capture controls for the given pin */
13121 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13122 const char *ctlname, int idx)
13133 case 0x1a: /* ALC259/269 only */
13134 case 0x1b: /* ALC259/269 only */
13135 case 0x21: /* ALC269vb has this pin, too */
13139 snd_printd(KERN_WARNING "hda_codec: "
13140 "ignoring pin 0x%x as unknown\n", nid);
13143 if (spec->multiout.dac_nids[0] != dac &&
13144 spec->multiout.dac_nids[1] != dac) {
13145 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13146 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13150 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13154 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13155 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13157 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13158 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13164 /* add playback controls from the parsed DAC table */
13165 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13166 const struct auto_pin_cfg *cfg)
13171 spec->multiout.dac_nids = spec->private_dac_nids;
13173 nid = cfg->line_out_pins[0];
13177 name = alc_get_line_out_pfx(spec, 0, true, &index);
13178 err = alc268_new_analog_output(spec, nid, name, 0);
13183 nid = cfg->speaker_pins[0];
13185 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13186 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13190 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13194 nid = cfg->hp_pins[0];
13196 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13201 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13203 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13204 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13211 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13212 hda_nid_t nid, int pin_type)
13216 alc_set_pin_output(codec, nid, pin_type);
13217 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
13219 if (nid == 0x14 || nid == 0x16)
13223 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13226 static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13230 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13234 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13236 struct alc_spec *spec = codec->spec;
13239 for (i = 0; i < spec->autocfg.line_outs; i++) {
13240 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13241 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13242 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13245 for (i = 0; i < spec->multiout.num_dacs; i++)
13246 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
13249 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13251 struct alc_spec *spec = codec->spec;
13255 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13256 pin = spec->autocfg.hp_pins[i];
13257 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13259 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13260 pin = spec->autocfg.speaker_pins[i];
13261 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13263 if (spec->autocfg.mono_out_pin)
13264 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13265 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13267 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13268 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13269 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
13272 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13274 struct alc_spec *spec = codec->spec;
13275 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13276 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13277 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13278 unsigned int dac_vol1, dac_vol2;
13280 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13281 snd_hda_codec_write(codec, speaker_nid, 0,
13282 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13283 /* mute mixer inputs from 0x1d */
13284 snd_hda_codec_write(codec, 0x0f, 0,
13285 AC_VERB_SET_AMP_GAIN_MUTE,
13287 snd_hda_codec_write(codec, 0x10, 0,
13288 AC_VERB_SET_AMP_GAIN_MUTE,
13291 /* unmute mixer inputs from 0x1d */
13292 snd_hda_codec_write(codec, 0x0f, 0,
13293 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13294 snd_hda_codec_write(codec, 0x10, 0,
13295 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13298 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13299 if (line_nid == 0x14)
13300 dac_vol2 = AMP_OUT_ZERO;
13301 else if (line_nid == 0x15)
13302 dac_vol1 = AMP_OUT_ZERO;
13303 if (hp_nid == 0x14)
13304 dac_vol2 = AMP_OUT_ZERO;
13305 else if (hp_nid == 0x15)
13306 dac_vol1 = AMP_OUT_ZERO;
13307 if (line_nid != 0x16 || hp_nid != 0x16 ||
13308 spec->autocfg.line_out_pins[1] != 0x16 ||
13309 spec->autocfg.line_out_pins[2] != 0x16)
13310 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13312 snd_hda_codec_write(codec, 0x02, 0,
13313 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13314 snd_hda_codec_write(codec, 0x03, 0,
13315 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13319 * BIOS auto configuration
13321 static int alc268_parse_auto_config(struct hda_codec *codec)
13323 struct alc_spec *spec = codec->spec;
13325 static const hda_nid_t alc268_ignore[] = { 0 };
13327 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13331 if (!spec->autocfg.line_outs) {
13332 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13333 spec->multiout.max_channels = 2;
13334 spec->no_analog = 1;
13337 return 0; /* can't find valid BIOS pin config */
13339 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13342 err = alc_auto_create_input_ctls(codec);
13346 spec->multiout.max_channels = 2;
13349 /* digital only support output */
13350 alc_auto_parse_digital(codec);
13351 if (spec->kctls.list)
13352 add_mixer(spec, spec->kctls.list);
13354 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
13355 add_mixer(spec, alc268_beep_mixer);
13356 add_verb(spec, alc268_beep_init_verbs);
13359 spec->num_mux_defs = 1;
13360 spec->input_mux = &spec->private_imux[0];
13362 if (!spec->dual_adc_switch)
13363 alc_remove_invalid_adc_nids(codec);
13365 err = alc_auto_add_mic_boost(codec);
13369 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13374 /* init callback for auto-configuration model -- overriding the default init */
13375 static void alc268_auto_init(struct hda_codec *codec)
13377 struct alc_spec *spec = codec->spec;
13378 alc268_auto_init_multi_out(codec);
13379 alc268_auto_init_hp_out(codec);
13380 alc268_auto_init_mono_speaker_out(codec);
13381 alc_auto_init_analog_input(codec);
13382 alc_auto_init_input_src(codec);
13383 alc_auto_init_digital(codec);
13384 if (spec->unsol_event)
13385 alc_inithook(codec);
13389 * configuration and preset
13391 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13392 [ALC267_QUANTA_IL1] = "quanta-il1",
13393 [ALC268_3ST] = "3stack",
13394 [ALC268_TOSHIBA] = "toshiba",
13395 [ALC268_ACER] = "acer",
13396 [ALC268_ACER_DMIC] = "acer-dmic",
13397 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13398 [ALC268_DELL] = "dell",
13399 [ALC268_ZEPTO] = "zepto",
13400 #ifdef CONFIG_SND_DEBUG
13401 [ALC268_TEST] = "test",
13403 [ALC268_AUTO] = "auto",
13406 static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13407 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13408 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13409 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13410 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13411 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13412 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13413 ALC268_ACER_ASPIRE_ONE),
13414 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13415 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13416 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13417 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13418 /* almost compatible with toshiba but with optional digital outs;
13419 * auto-probing seems working fine
13421 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13423 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13424 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13425 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13426 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13430 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13431 static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13432 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13433 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13434 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13439 static const struct alc_config_preset alc268_presets[] = {
13440 [ALC267_QUANTA_IL1] = {
13441 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13442 alc268_capture_nosrc_mixer },
13443 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13444 alc267_quanta_il1_verbs },
13445 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13446 .dac_nids = alc268_dac_nids,
13447 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13448 .adc_nids = alc268_adc_nids_alt,
13450 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13451 .channel_mode = alc268_modes,
13452 .unsol_event = alc_sku_unsol_event,
13453 .setup = alc267_quanta_il1_setup,
13454 .init_hook = alc_inithook,
13457 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13458 alc268_beep_mixer },
13459 .init_verbs = { alc268_base_init_verbs },
13460 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13461 .dac_nids = alc268_dac_nids,
13462 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13463 .adc_nids = alc268_adc_nids_alt,
13464 .capsrc_nids = alc268_capsrc_nids,
13466 .dig_out_nid = ALC268_DIGOUT_NID,
13467 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13468 .channel_mode = alc268_modes,
13469 .input_mux = &alc268_capture_source,
13471 [ALC268_TOSHIBA] = {
13472 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13473 alc268_beep_mixer },
13474 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13475 alc268_toshiba_verbs },
13476 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13477 .dac_nids = alc268_dac_nids,
13478 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13479 .adc_nids = alc268_adc_nids_alt,
13480 .capsrc_nids = alc268_capsrc_nids,
13482 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13483 .channel_mode = alc268_modes,
13484 .input_mux = &alc268_capture_source,
13485 .unsol_event = alc_sku_unsol_event,
13486 .setup = alc268_toshiba_setup,
13487 .init_hook = alc_inithook,
13490 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13491 alc268_beep_mixer },
13492 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13493 alc268_acer_verbs },
13494 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13495 .dac_nids = alc268_dac_nids,
13496 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13497 .adc_nids = alc268_adc_nids_alt,
13498 .capsrc_nids = alc268_capsrc_nids,
13500 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13501 .channel_mode = alc268_modes,
13502 .input_mux = &alc268_acer_capture_source,
13503 .unsol_event = alc_sku_unsol_event,
13504 .setup = alc268_acer_setup,
13505 .init_hook = alc_inithook,
13507 [ALC268_ACER_DMIC] = {
13508 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13509 alc268_beep_mixer },
13510 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13511 alc268_acer_verbs },
13512 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13513 .dac_nids = alc268_dac_nids,
13514 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13515 .adc_nids = alc268_adc_nids_alt,
13516 .capsrc_nids = alc268_capsrc_nids,
13518 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13519 .channel_mode = alc268_modes,
13520 .input_mux = &alc268_acer_dmic_capture_source,
13521 .unsol_event = alc_sku_unsol_event,
13522 .setup = alc268_acer_setup,
13523 .init_hook = alc_inithook,
13525 [ALC268_ACER_ASPIRE_ONE] = {
13526 .mixers = { alc268_acer_aspire_one_mixer,
13528 alc268_capture_nosrc_mixer },
13529 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13530 alc268_acer_aspire_one_verbs },
13531 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13532 .dac_nids = alc268_dac_nids,
13533 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13534 .adc_nids = alc268_adc_nids_alt,
13535 .capsrc_nids = alc268_capsrc_nids,
13537 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13538 .channel_mode = alc268_modes,
13539 .unsol_event = alc_sku_unsol_event,
13540 .setup = alc268_acer_lc_setup,
13541 .init_hook = alc_inithook,
13544 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13545 alc268_capture_nosrc_mixer },
13546 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13547 alc268_dell_verbs },
13548 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13549 .dac_nids = alc268_dac_nids,
13550 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13551 .adc_nids = alc268_adc_nids_alt,
13552 .capsrc_nids = alc268_capsrc_nids,
13554 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13555 .channel_mode = alc268_modes,
13556 .unsol_event = alc_sku_unsol_event,
13557 .setup = alc268_dell_setup,
13558 .init_hook = alc_inithook,
13561 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13562 alc268_beep_mixer },
13563 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13564 alc268_toshiba_verbs },
13565 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13566 .dac_nids = alc268_dac_nids,
13567 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13568 .adc_nids = alc268_adc_nids_alt,
13569 .capsrc_nids = alc268_capsrc_nids,
13571 .dig_out_nid = ALC268_DIGOUT_NID,
13572 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13573 .channel_mode = alc268_modes,
13574 .input_mux = &alc268_capture_source,
13575 .unsol_event = alc_sku_unsol_event,
13576 .setup = alc268_toshiba_setup,
13577 .init_hook = alc_inithook,
13579 #ifdef CONFIG_SND_DEBUG
13581 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13582 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13583 alc268_volume_init_verbs,
13584 alc268_beep_init_verbs },
13585 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13586 .dac_nids = alc268_dac_nids,
13587 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13588 .adc_nids = alc268_adc_nids_alt,
13589 .capsrc_nids = alc268_capsrc_nids,
13591 .dig_out_nid = ALC268_DIGOUT_NID,
13592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13593 .channel_mode = alc268_modes,
13594 .input_mux = &alc268_capture_source,
13599 static int patch_alc268(struct hda_codec *codec)
13601 struct alc_spec *spec;
13603 int i, has_beep, err;
13605 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13609 codec->spec = spec;
13611 /* ALC268 has no aa-loopback mixer */
13613 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13617 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13618 board_config = snd_hda_check_board_codec_sid_config(codec,
13619 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13621 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13622 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13624 board_config = ALC268_AUTO;
13627 if (board_config == ALC268_AUTO) {
13628 /* automatic parse from the BIOS config */
13629 err = alc268_parse_auto_config(codec);
13635 "hda_codec: Cannot set up configuration "
13636 "from BIOS. Using base mode...\n");
13637 board_config = ALC268_3ST;
13641 if (board_config != ALC268_AUTO)
13642 setup_preset(codec, &alc268_presets[board_config]);
13645 for (i = 0; i < spec->num_mixers; i++) {
13646 if (spec->mixers[i] == alc268_beep_mixer) {
13653 err = snd_hda_attach_beep_device(codec, 0x1);
13658 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13659 /* override the amp caps for beep generator */
13660 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13661 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13662 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13663 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13664 (0 << AC_AMPCAP_MUTE_SHIFT));
13667 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13668 alc_auto_fill_adc_caps(codec);
13669 alc_remove_invalid_adc_nids(codec);
13672 if (!spec->cap_mixer && !spec->no_analog)
13673 set_capture_mixer(codec);
13675 spec->vmaster_nid = 0x02;
13677 codec->patch_ops = alc_patch_ops;
13678 if (board_config == ALC268_AUTO)
13679 spec->init_hook = alc268_auto_init;
13680 spec->shutup = alc_eapd_shutup;
13682 alc_init_jacks(codec);
13688 * ALC269 channel source setting (2 channel)
13690 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13692 #define alc269_dac_nids alc260_dac_nids
13694 static const hda_nid_t alc269_adc_nids[1] = {
13699 static const hda_nid_t alc269_capsrc_nids[1] = {
13703 static const hda_nid_t alc269vb_adc_nids[1] = {
13708 static const hda_nid_t alc269vb_capsrc_nids[1] = {
13712 #define alc269_modes alc260_modes
13713 #define alc269_capture_source alc880_lg_lw_capture_source
13715 static const struct snd_kcontrol_new alc269_base_mixer[] = {
13716 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13717 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13718 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13719 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13722 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13723 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13724 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13725 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13727 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13731 static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13732 /* output mixer control */
13733 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13736 .name = "Master Playback Switch",
13737 .subdevice = HDA_SUBDEV_AMP_FLAG,
13738 .info = snd_hda_mixer_amp_switch_info,
13739 .get = snd_hda_mixer_amp_switch_get,
13740 .put = alc268_acer_master_sw_put,
13741 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13745 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13746 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13747 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13748 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13752 static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13753 /* output mixer control */
13754 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13757 .name = "Master Playback Switch",
13758 .subdevice = HDA_SUBDEV_AMP_FLAG,
13759 .info = snd_hda_mixer_amp_switch_info,
13760 .get = snd_hda_mixer_amp_switch_get,
13761 .put = alc268_acer_master_sw_put,
13762 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13766 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13767 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13768 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13770 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13771 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
13776 static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
13777 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13778 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13780 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13784 static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13785 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13786 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13787 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13788 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13792 static const struct snd_kcontrol_new alc269_asus_mixer[] = {
13793 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13794 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13798 /* capture mixer elements */
13799 static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13800 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13801 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13802 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13803 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13807 static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13808 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13809 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13810 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13814 static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13815 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13816 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13817 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13818 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13822 static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13823 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13824 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13825 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13830 #define alc269_fujitsu_mixer alc269_laptop_mixer
13832 static const struct hda_verb alc269_quanta_fl1_verbs[] = {
13833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13834 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13835 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13836 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13837 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13838 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13842 static const struct hda_verb alc269_lifebook_verbs[] = {
13843 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13844 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13847 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13848 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13849 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13850 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13851 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13852 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13856 /* toggle speaker-output according to the hp-jack state */
13857 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13859 alc_hp_automute(codec);
13861 snd_hda_codec_write(codec, 0x20, 0,
13862 AC_VERB_SET_COEF_INDEX, 0x0c);
13863 snd_hda_codec_write(codec, 0x20, 0,
13864 AC_VERB_SET_PROC_COEF, 0x680);
13866 snd_hda_codec_write(codec, 0x20, 0,
13867 AC_VERB_SET_COEF_INDEX, 0x0c);
13868 snd_hda_codec_write(codec, 0x20, 0,
13869 AC_VERB_SET_PROC_COEF, 0x480);
13872 #define alc269_lifebook_speaker_automute \
13873 alc269_quanta_fl1_speaker_automute
13875 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13877 unsigned int present_laptop;
13878 unsigned int present_dock;
13880 present_laptop = snd_hda_jack_detect(codec, 0x18);
13881 present_dock = snd_hda_jack_detect(codec, 0x1b);
13883 /* Laptop mic port overrides dock mic port, design decision */
13885 snd_hda_codec_write(codec, 0x23, 0,
13886 AC_VERB_SET_CONNECT_SEL, 0x3);
13887 if (present_laptop)
13888 snd_hda_codec_write(codec, 0x23, 0,
13889 AC_VERB_SET_CONNECT_SEL, 0x0);
13890 if (!present_dock && !present_laptop)
13891 snd_hda_codec_write(codec, 0x23, 0,
13892 AC_VERB_SET_CONNECT_SEL, 0x1);
13895 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13898 switch (res >> 26) {
13899 case ALC880_HP_EVENT:
13900 alc269_quanta_fl1_speaker_automute(codec);
13902 case ALC880_MIC_EVENT:
13903 alc_mic_automute(codec);
13908 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13911 if ((res >> 26) == ALC880_HP_EVENT)
13912 alc269_lifebook_speaker_automute(codec);
13913 if ((res >> 26) == ALC880_MIC_EVENT)
13914 alc269_lifebook_mic_autoswitch(codec);
13917 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13919 struct alc_spec *spec = codec->spec;
13920 spec->autocfg.hp_pins[0] = 0x15;
13921 spec->autocfg.speaker_pins[0] = 0x14;
13922 spec->automute_mixer_nid[0] = 0x0c;
13923 spec->automute = 1;
13924 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13925 spec->ext_mic.pin = 0x18;
13926 spec->ext_mic.mux_idx = 0;
13927 spec->int_mic.pin = 0x19;
13928 spec->int_mic.mux_idx = 1;
13929 spec->auto_mic = 1;
13932 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13934 alc269_quanta_fl1_speaker_automute(codec);
13935 alc_mic_automute(codec);
13938 static void alc269_lifebook_setup(struct hda_codec *codec)
13940 struct alc_spec *spec = codec->spec;
13941 spec->autocfg.hp_pins[0] = 0x15;
13942 spec->autocfg.hp_pins[1] = 0x1a;
13943 spec->autocfg.speaker_pins[0] = 0x14;
13944 spec->automute_mixer_nid[0] = 0x0c;
13945 spec->automute = 1;
13946 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13949 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13951 alc269_lifebook_speaker_automute(codec);
13952 alc269_lifebook_mic_autoswitch(codec);
13955 static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13956 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13957 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13958 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13959 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13960 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13961 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13962 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13966 static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
13967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13968 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13969 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13970 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13971 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13972 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13976 static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13977 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13978 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13979 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13980 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13981 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13982 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13983 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13987 static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13988 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13989 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13990 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13991 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13992 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13993 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13994 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13998 static const struct hda_verb alc271_acer_dmic_verbs[] = {
13999 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14000 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14001 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14003 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14004 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14005 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14006 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14007 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14008 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14012 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14014 struct alc_spec *spec = codec->spec;
14015 spec->autocfg.hp_pins[0] = 0x15;
14016 spec->autocfg.speaker_pins[0] = 0x14;
14017 spec->automute_mixer_nid[0] = 0x0c;
14018 spec->automute = 1;
14019 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14020 spec->ext_mic.pin = 0x18;
14021 spec->ext_mic.mux_idx = 0;
14022 spec->int_mic.pin = 0x19;
14023 spec->int_mic.mux_idx = 1;
14024 spec->auto_mic = 1;
14027 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14029 struct alc_spec *spec = codec->spec;
14030 spec->autocfg.hp_pins[0] = 0x15;
14031 spec->autocfg.speaker_pins[0] = 0x14;
14032 spec->automute_mixer_nid[0] = 0x0c;
14033 spec->automute = 1;
14034 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14035 spec->ext_mic.pin = 0x18;
14036 spec->ext_mic.mux_idx = 0;
14037 spec->int_mic.pin = 0x12;
14038 spec->int_mic.mux_idx = 5;
14039 spec->auto_mic = 1;
14042 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14044 struct alc_spec *spec = codec->spec;
14045 spec->autocfg.hp_pins[0] = 0x21;
14046 spec->autocfg.speaker_pins[0] = 0x14;
14047 spec->automute_mixer_nid[0] = 0x0c;
14048 spec->automute = 1;
14049 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14050 spec->ext_mic.pin = 0x18;
14051 spec->ext_mic.mux_idx = 0;
14052 spec->int_mic.pin = 0x19;
14053 spec->int_mic.mux_idx = 1;
14054 spec->auto_mic = 1;
14057 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14059 struct alc_spec *spec = codec->spec;
14060 spec->autocfg.hp_pins[0] = 0x21;
14061 spec->autocfg.speaker_pins[0] = 0x14;
14062 spec->automute_mixer_nid[0] = 0x0c;
14063 spec->automute = 1;
14064 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14065 spec->ext_mic.pin = 0x18;
14066 spec->ext_mic.mux_idx = 0;
14067 spec->int_mic.pin = 0x12;
14068 spec->int_mic.mux_idx = 6;
14069 spec->auto_mic = 1;
14073 * generic initialization of ADC, input mixers and output mixers
14075 static const struct hda_verb alc269_init_verbs[] = {
14077 * Unmute ADC0 and set the default input to mic-in
14079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14082 * Set up output mixers (0x02 - 0x03)
14084 /* set vol=0 to output mixers */
14085 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14086 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14088 /* set up input amps for analog loopback */
14089 /* Amp Indices: DAC = 0, mixer = 1 */
14090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14092 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14093 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14094 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14095 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14097 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14098 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14099 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14100 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14102 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14103 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14108 /* FIXME: use Mux-type input source selection */
14109 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14110 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14111 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14114 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14118 static const struct hda_verb alc269vb_init_verbs[] = {
14120 * Unmute ADC0 and set the default input to mic-in
14122 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14125 * Set up output mixers (0x02 - 0x03)
14127 /* set vol=0 to output mixers */
14128 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14129 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14131 /* set up input amps for analog loopback */
14132 /* Amp Indices: DAC = 0, mixer = 1 */
14133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14136 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14137 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14138 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14141 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14142 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14143 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14144 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14145 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14146 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14148 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14149 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14151 /* FIXME: use Mux-type input source selection */
14152 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14153 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14154 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14157 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14161 #define alc269_auto_create_multi_out_ctls \
14162 alc268_auto_create_multi_out_ctls
14164 #ifdef CONFIG_SND_HDA_POWER_SAVE
14165 #define alc269_loopbacks alc880_loopbacks
14168 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14172 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14173 /* NID is set in alc_build_pcms */
14175 .open = alc_playback_pcm_open,
14176 .prepare = alc_playback_pcm_prepare,
14177 .cleanup = alc_playback_pcm_cleanup
14181 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14185 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14186 /* NID is set in alc_build_pcms */
14189 #ifdef CONFIG_SND_HDA_POWER_SAVE
14190 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14192 switch (codec->subsystem_id) {
14199 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14201 /* update mute-LED according to the speaker mute state */
14202 if (nid == 0x01 || nid == 0x14) {
14204 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14209 /* mic2 vref pin is used for mute LED control */
14210 snd_hda_codec_update_cache(codec, 0x19, 0,
14211 AC_VERB_SET_PIN_WIDGET_CONTROL,
14214 return alc_check_power_status(codec, nid);
14216 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14218 static int alc275_setup_dual_adc(struct hda_codec *codec)
14220 struct alc_spec *spec = codec->spec;
14222 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14224 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14225 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14226 if (spec->ext_mic.pin <= 0x12) {
14227 spec->private_adc_nids[0] = 0x08;
14228 spec->private_adc_nids[1] = 0x11;
14229 spec->private_capsrc_nids[0] = 0x23;
14230 spec->private_capsrc_nids[1] = 0x22;
14232 spec->private_adc_nids[0] = 0x11;
14233 spec->private_adc_nids[1] = 0x08;
14234 spec->private_capsrc_nids[0] = 0x22;
14235 spec->private_capsrc_nids[1] = 0x23;
14237 spec->adc_nids = spec->private_adc_nids;
14238 spec->capsrc_nids = spec->private_capsrc_nids;
14239 spec->num_adc_nids = 2;
14240 spec->dual_adc_switch = 1;
14241 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14242 spec->adc_nids[0], spec->adc_nids[1]);
14248 /* different alc269-variants */
14250 ALC269_TYPE_ALC269VA,
14251 ALC269_TYPE_ALC269VB,
14252 ALC269_TYPE_ALC269VC,
14256 * BIOS auto configuration
14258 static int alc269_parse_auto_config(struct hda_codec *codec)
14260 struct alc_spec *spec = codec->spec;
14262 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14264 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14269 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14272 err = alc_auto_create_input_ctls(codec);
14276 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14278 alc_auto_parse_digital(codec);
14280 if (spec->kctls.list)
14281 add_mixer(spec, spec->kctls.list);
14283 if (spec->codec_variant != ALC269_TYPE_ALC269VA)
14284 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14286 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14288 spec->num_mux_defs = 1;
14289 spec->input_mux = &spec->private_imux[0];
14291 alc275_setup_dual_adc(codec);
14292 if (!spec->dual_adc_switch)
14293 alc_remove_invalid_adc_nids(codec);
14295 err = alc_auto_add_mic_boost(codec);
14299 if (!spec->cap_mixer && !spec->no_analog)
14300 set_capture_mixer(codec);
14305 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14306 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14309 /* init callback for auto-configuration model -- overriding the default init */
14310 static void alc269_auto_init(struct hda_codec *codec)
14312 struct alc_spec *spec = codec->spec;
14313 alc269_auto_init_multi_out(codec);
14314 alc269_auto_init_hp_out(codec);
14315 alc_auto_init_analog_input(codec);
14316 alc_auto_init_input_src(codec);
14317 alc_auto_init_digital(codec);
14318 if (spec->unsol_event)
14319 alc_inithook(codec);
14322 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14324 int val = alc_read_coef_idx(codec, 0x04);
14329 alc_write_coef_idx(codec, 0x04, val);
14332 static void alc269_shutup(struct hda_codec *codec)
14334 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14335 alc269_toggle_power_output(codec, 0);
14336 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14337 alc269_toggle_power_output(codec, 0);
14342 #ifdef SND_HDA_NEEDS_RESUME
14343 static int alc269_resume(struct hda_codec *codec)
14345 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14346 alc269_toggle_power_output(codec, 0);
14350 codec->patch_ops.init(codec);
14352 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14353 alc269_toggle_power_output(codec, 1);
14357 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14358 alc269_toggle_power_output(codec, 1);
14360 snd_hda_codec_resume_amp(codec);
14361 snd_hda_codec_resume_cache(codec);
14362 hda_call_check_power_status(codec, 0x01);
14365 #endif /* SND_HDA_NEEDS_RESUME */
14367 static void alc269_fixup_hweq(struct hda_codec *codec,
14368 const struct alc_fixup *fix, int action)
14372 if (action != ALC_FIXUP_ACT_INIT)
14374 coef = alc_read_coef_idx(codec, 0x1e);
14375 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14378 static void alc271_fixup_dmic(struct hda_codec *codec,
14379 const struct alc_fixup *fix, int action)
14381 static const struct hda_verb verbs[] = {
14382 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14383 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14388 if (strcmp(codec->chip_name, "ALC271X"))
14390 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14391 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14392 snd_hda_sequence_write(codec, verbs);
14396 ALC269_FIXUP_SONY_VAIO,
14397 ALC275_FIXUP_SONY_VAIO_GPIO2,
14398 ALC269_FIXUP_DELL_M101Z,
14399 ALC269_FIXUP_SKU_IGNORE,
14400 ALC269_FIXUP_ASUS_G73JW,
14401 ALC269_FIXUP_LENOVO_EAPD,
14402 ALC275_FIXUP_SONY_HWEQ,
14406 static const struct alc_fixup alc269_fixups[] = {
14407 [ALC269_FIXUP_SONY_VAIO] = {
14408 .type = ALC_FIXUP_VERBS,
14409 .v.verbs = (const struct hda_verb[]) {
14410 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14414 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14415 .type = ALC_FIXUP_VERBS,
14416 .v.verbs = (const struct hda_verb[]) {
14417 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14418 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14419 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14423 .chain_id = ALC269_FIXUP_SONY_VAIO
14425 [ALC269_FIXUP_DELL_M101Z] = {
14426 .type = ALC_FIXUP_VERBS,
14427 .v.verbs = (const struct hda_verb[]) {
14428 /* Enables internal speaker */
14429 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14430 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14434 [ALC269_FIXUP_SKU_IGNORE] = {
14435 .type = ALC_FIXUP_SKU,
14436 .v.sku = ALC_FIXUP_SKU_IGNORE,
14438 [ALC269_FIXUP_ASUS_G73JW] = {
14439 .type = ALC_FIXUP_PINS,
14440 .v.pins = (const struct alc_pincfg[]) {
14441 { 0x17, 0x99130111 }, /* subwoofer */
14445 [ALC269_FIXUP_LENOVO_EAPD] = {
14446 .type = ALC_FIXUP_VERBS,
14447 .v.verbs = (const struct hda_verb[]) {
14448 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14452 [ALC275_FIXUP_SONY_HWEQ] = {
14453 .type = ALC_FIXUP_FUNC,
14454 .v.func = alc269_fixup_hweq,
14456 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14458 [ALC271_FIXUP_DMIC] = {
14459 .type = ALC_FIXUP_FUNC,
14460 .v.func = alc271_fixup_dmic,
14464 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14465 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14466 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14467 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14468 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14469 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14470 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14471 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14472 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14473 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14474 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14475 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14476 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14477 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14483 * configuration and preset
14485 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14486 [ALC269_BASIC] = "basic",
14487 [ALC269_QUANTA_FL1] = "quanta",
14488 [ALC269_AMIC] = "laptop-amic",
14489 [ALC269_DMIC] = "laptop-dmic",
14490 [ALC269_FUJITSU] = "fujitsu",
14491 [ALC269_LIFEBOOK] = "lifebook",
14492 [ALC269_AUTO] = "auto",
14495 static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14496 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14497 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14498 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14500 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14501 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14502 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14503 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14504 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14505 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14506 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14507 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14508 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14509 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14510 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14511 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14512 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14513 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14514 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14515 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14516 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14517 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14518 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14519 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14520 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14521 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14522 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14523 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14524 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14525 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14526 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14527 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14528 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14529 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14530 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14531 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14532 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14533 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14534 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14535 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14536 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14538 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14540 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14541 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14542 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14543 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14544 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14545 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14546 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14547 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14548 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14549 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14553 static const struct alc_config_preset alc269_presets[] = {
14555 .mixers = { alc269_base_mixer },
14556 .init_verbs = { alc269_init_verbs },
14557 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14558 .dac_nids = alc269_dac_nids,
14560 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14561 .channel_mode = alc269_modes,
14562 .input_mux = &alc269_capture_source,
14564 [ALC269_QUANTA_FL1] = {
14565 .mixers = { alc269_quanta_fl1_mixer },
14566 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14567 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14568 .dac_nids = alc269_dac_nids,
14570 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14571 .channel_mode = alc269_modes,
14572 .input_mux = &alc269_capture_source,
14573 .unsol_event = alc269_quanta_fl1_unsol_event,
14574 .setup = alc269_quanta_fl1_setup,
14575 .init_hook = alc269_quanta_fl1_init_hook,
14578 .mixers = { alc269_laptop_mixer },
14579 .cap_mixer = alc269_laptop_analog_capture_mixer,
14580 .init_verbs = { alc269_init_verbs,
14581 alc269_laptop_amic_init_verbs },
14582 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14583 .dac_nids = alc269_dac_nids,
14585 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14586 .channel_mode = alc269_modes,
14587 .unsol_event = alc_sku_unsol_event,
14588 .setup = alc269_laptop_amic_setup,
14589 .init_hook = alc_inithook,
14592 .mixers = { alc269_laptop_mixer },
14593 .cap_mixer = alc269_laptop_digital_capture_mixer,
14594 .init_verbs = { alc269_init_verbs,
14595 alc269_laptop_dmic_init_verbs },
14596 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14597 .dac_nids = alc269_dac_nids,
14599 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14600 .channel_mode = alc269_modes,
14601 .unsol_event = alc_sku_unsol_event,
14602 .setup = alc269_laptop_dmic_setup,
14603 .init_hook = alc_inithook,
14605 [ALC269VB_AMIC] = {
14606 .mixers = { alc269vb_laptop_mixer },
14607 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14608 .init_verbs = { alc269vb_init_verbs,
14609 alc269vb_laptop_amic_init_verbs },
14610 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14611 .dac_nids = alc269_dac_nids,
14613 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14614 .channel_mode = alc269_modes,
14615 .unsol_event = alc_sku_unsol_event,
14616 .setup = alc269vb_laptop_amic_setup,
14617 .init_hook = alc_inithook,
14619 [ALC269VB_DMIC] = {
14620 .mixers = { alc269vb_laptop_mixer },
14621 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14622 .init_verbs = { alc269vb_init_verbs,
14623 alc269vb_laptop_dmic_init_verbs },
14624 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14625 .dac_nids = alc269_dac_nids,
14627 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14628 .channel_mode = alc269_modes,
14629 .unsol_event = alc_sku_unsol_event,
14630 .setup = alc269vb_laptop_dmic_setup,
14631 .init_hook = alc_inithook,
14633 [ALC269_FUJITSU] = {
14634 .mixers = { alc269_fujitsu_mixer },
14635 .cap_mixer = alc269_laptop_digital_capture_mixer,
14636 .init_verbs = { alc269_init_verbs,
14637 alc269_laptop_dmic_init_verbs },
14638 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14639 .dac_nids = alc269_dac_nids,
14641 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14642 .channel_mode = alc269_modes,
14643 .unsol_event = alc_sku_unsol_event,
14644 .setup = alc269_laptop_dmic_setup,
14645 .init_hook = alc_inithook,
14647 [ALC269_LIFEBOOK] = {
14648 .mixers = { alc269_lifebook_mixer },
14649 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14650 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14651 .dac_nids = alc269_dac_nids,
14653 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14654 .channel_mode = alc269_modes,
14655 .input_mux = &alc269_capture_source,
14656 .unsol_event = alc269_lifebook_unsol_event,
14657 .setup = alc269_lifebook_setup,
14658 .init_hook = alc269_lifebook_init_hook,
14661 .mixers = { alc269_asus_mixer },
14662 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14663 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14664 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14665 .dac_nids = alc269_dac_nids,
14666 .adc_nids = alc262_dmic_adc_nids,
14667 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14668 .capsrc_nids = alc262_dmic_capsrc_nids,
14669 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14670 .channel_mode = alc269_modes,
14671 .input_mux = &alc269_capture_source,
14672 .dig_out_nid = ALC880_DIGOUT_NID,
14673 .unsol_event = alc_sku_unsol_event,
14674 .setup = alc269vb_laptop_dmic_setup,
14675 .init_hook = alc_inithook,
14679 static int alc269_fill_coef(struct hda_codec *codec)
14683 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14684 alc_write_coef_idx(codec, 0xf, 0x960b);
14685 alc_write_coef_idx(codec, 0xe, 0x8817);
14688 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14689 alc_write_coef_idx(codec, 0xf, 0x960b);
14690 alc_write_coef_idx(codec, 0xe, 0x8814);
14693 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14694 val = alc_read_coef_idx(codec, 0x04);
14695 /* Power up output pin */
14696 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14699 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14700 val = alc_read_coef_idx(codec, 0xd);
14701 if ((val & 0x0c00) >> 10 != 0x1) {
14702 /* Capless ramp up clock control */
14703 alc_write_coef_idx(codec, 0xd, val | (1<<10));
14705 val = alc_read_coef_idx(codec, 0x17);
14706 if ((val & 0x01c0) >> 6 != 0x4) {
14707 /* Class D power on reset */
14708 alc_write_coef_idx(codec, 0x17, val | (1<<7));
14712 val = alc_read_coef_idx(codec, 0xd); /* Class D */
14713 alc_write_coef_idx(codec, 0xd, val | (1<<14));
14715 val = alc_read_coef_idx(codec, 0x4); /* HP */
14716 alc_write_coef_idx(codec, 0x4, val | (1<<11));
14721 static int patch_alc269(struct hda_codec *codec)
14723 struct alc_spec *spec;
14724 int board_config, coef;
14727 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14731 codec->spec = spec;
14733 spec->mixer_nid = 0x0b;
14735 alc_auto_parse_customize_define(codec);
14737 if (codec->vendor_id == 0x10ec0269) {
14738 spec->codec_variant = ALC269_TYPE_ALC269VA;
14739 coef = alc_read_coef_idx(codec, 0);
14740 if ((coef & 0x00f0) == 0x0010) {
14741 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14742 spec->cdefine.platform_type == 1) {
14743 alc_codec_rename(codec, "ALC271X");
14744 } else if ((coef & 0xf000) == 0x2000) {
14745 alc_codec_rename(codec, "ALC259");
14746 } else if ((coef & 0xf000) == 0x3000) {
14747 alc_codec_rename(codec, "ALC258");
14748 } else if ((coef & 0xfff0) == 0x3010) {
14749 alc_codec_rename(codec, "ALC277");
14751 alc_codec_rename(codec, "ALC269VB");
14753 spec->codec_variant = ALC269_TYPE_ALC269VB;
14754 } else if ((coef & 0x00f0) == 0x0020) {
14755 if (coef == 0xa023)
14756 alc_codec_rename(codec, "ALC259");
14757 else if (coef == 0x6023)
14758 alc_codec_rename(codec, "ALC281X");
14759 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
14760 codec->bus->pci->subsystem_device == 0x21f3)
14761 alc_codec_rename(codec, "ALC3202");
14763 alc_codec_rename(codec, "ALC269VC");
14764 spec->codec_variant = ALC269_TYPE_ALC269VC;
14766 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14767 alc269_fill_coef(codec);
14770 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14774 if (board_config < 0) {
14775 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14777 board_config = ALC269_AUTO;
14780 if (board_config == ALC269_AUTO) {
14781 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
14782 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
14785 if (board_config == ALC269_AUTO) {
14786 /* automatic parse from the BIOS config */
14787 err = alc269_parse_auto_config(codec);
14793 "hda_codec: Cannot set up configuration "
14794 "from BIOS. Using base mode...\n");
14795 board_config = ALC269_BASIC;
14799 if (has_cdefine_beep(codec)) {
14800 err = snd_hda_attach_beep_device(codec, 0x1);
14807 if (board_config != ALC269_AUTO)
14808 setup_preset(codec, &alc269_presets[board_config]);
14810 if (board_config == ALC269_QUANTA_FL1) {
14811 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14812 * fix the sample rate of analog I/O to 44.1kHz
14814 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14815 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14818 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14819 alc_auto_fill_adc_caps(codec);
14820 alc_remove_invalid_adc_nids(codec);
14823 if (!spec->cap_mixer)
14824 set_capture_mixer(codec);
14825 if (has_cdefine_beep(codec))
14826 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14828 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
14830 spec->vmaster_nid = 0x02;
14832 codec->patch_ops = alc_patch_ops;
14833 #ifdef SND_HDA_NEEDS_RESUME
14834 codec->patch_ops.resume = alc269_resume;
14836 if (board_config == ALC269_AUTO)
14837 spec->init_hook = alc269_auto_init;
14838 spec->shutup = alc269_shutup;
14840 alc_init_jacks(codec);
14841 #ifdef CONFIG_SND_HDA_POWER_SAVE
14842 if (!spec->loopback.amplist)
14843 spec->loopback.amplist = alc269_loopbacks;
14844 if (alc269_mic2_for_mute_led(codec))
14845 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14852 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14856 * set the path ways for 2 channel output
14857 * need to set the codec line out and mic 1 pin widgets to inputs
14859 static const struct hda_verb alc861_threestack_ch2_init[] = {
14860 /* set pin widget 1Ah (line in) for input */
14861 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14862 /* set pin widget 18h (mic1/2) for input, for mic also enable
14865 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14867 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14869 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14870 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14876 * need to set the codec line out and mic 1 pin widgets to outputs
14878 static const struct hda_verb alc861_threestack_ch6_init[] = {
14879 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14880 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14881 /* set pin widget 18h (mic1) for output (CLFE)*/
14882 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14884 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14885 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14887 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14889 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14890 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14895 static const struct hda_channel_mode alc861_threestack_modes[2] = {
14896 { 2, alc861_threestack_ch2_init },
14897 { 6, alc861_threestack_ch6_init },
14899 /* Set mic1 as input and unmute the mixer */
14900 static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14901 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14902 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14905 /* Set mic1 as output and mute mixer */
14906 static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14907 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14908 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14912 static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14913 { 2, alc861_uniwill_m31_ch2_init },
14914 { 4, alc861_uniwill_m31_ch4_init },
14917 /* Set mic1 and line-in as input and unmute the mixer */
14918 static const struct hda_verb alc861_asus_ch2_init[] = {
14919 /* set pin widget 1Ah (line in) for input */
14920 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14921 /* set pin widget 18h (mic1/2) for input, for mic also enable
14924 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14926 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14928 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14929 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14933 /* Set mic1 nad line-in as output and mute mixer */
14934 static const struct hda_verb alc861_asus_ch6_init[] = {
14935 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14936 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14937 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14938 /* set pin widget 18h (mic1) for output (CLFE)*/
14939 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14940 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14941 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14942 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14944 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14946 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14947 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14952 static const struct hda_channel_mode alc861_asus_modes[2] = {
14953 { 2, alc861_asus_ch2_init },
14954 { 6, alc861_asus_ch6_init },
14959 static const struct snd_kcontrol_new alc861_base_mixer[] = {
14960 /* output mixer control */
14961 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14962 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14963 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14964 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14965 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14967 /*Input mixer control */
14968 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14969 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14970 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14971 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14972 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14973 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14975 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14982 static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
14983 /* output mixer control */
14984 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14985 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14986 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14987 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14988 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14990 /* Input mixer control */
14991 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14993 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14994 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14995 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14996 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14998 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15004 .name = "Channel Mode",
15005 .info = alc_ch_mode_info,
15006 .get = alc_ch_mode_get,
15007 .put = alc_ch_mode_put,
15008 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15013 static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15014 /* output mixer control */
15015 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15017 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15022 static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15023 /* output mixer control */
15024 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15025 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15026 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15027 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15028 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15030 /* Input mixer control */
15031 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15032 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15033 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15034 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15035 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15036 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15038 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15040 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15043 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15044 .name = "Channel Mode",
15045 .info = alc_ch_mode_info,
15046 .get = alc_ch_mode_get,
15047 .put = alc_ch_mode_put,
15048 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15053 static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15054 /* output mixer control */
15055 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15056 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15057 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15058 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15059 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15061 /* Input mixer control */
15062 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15063 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15064 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15065 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15066 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15067 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15069 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15070 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15074 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15075 .name = "Channel Mode",
15076 .info = alc_ch_mode_info,
15077 .get = alc_ch_mode_get,
15078 .put = alc_ch_mode_put,
15079 .private_value = ARRAY_SIZE(alc861_asus_modes),
15084 /* additional mixer */
15085 static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15086 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15087 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15092 * generic initialization of ADC, input mixers and output mixers
15094 static const struct hda_verb alc861_base_init_verbs[] = {
15096 * Unmute ADC0 and set the default input to mic-in
15098 /* port-A for surround (rear panel) */
15099 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15100 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15101 /* port-B for mic-in (rear panel) with vref */
15102 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15103 /* port-C for line-in (rear panel) */
15104 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15105 /* port-D for Front */
15106 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15107 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15108 /* port-E for HP out (front panel) */
15109 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15110 /* route front PCM to HP */
15111 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15112 /* port-F for mic-in (front panel) with vref */
15113 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15114 /* port-G for CLFE (rear panel) */
15115 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15116 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15117 /* port-H for side (rear panel) */
15118 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15119 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15121 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15122 /* route front mic to ADC1*/
15123 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15126 /* Unmute DAC0~3 & spdif out*/
15127 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15128 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15129 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15130 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15133 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15134 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15135 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15136 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15137 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15139 /* Unmute Stereo Mixer 15 */
15140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15141 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15143 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15145 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15146 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15149 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15150 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15151 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15152 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15153 /* hp used DAC 3 (Front) */
15154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15155 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15160 static const struct hda_verb alc861_threestack_init_verbs[] = {
15162 * Unmute ADC0 and set the default input to mic-in
15164 /* port-A for surround (rear panel) */
15165 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15166 /* port-B for mic-in (rear panel) with vref */
15167 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15168 /* port-C for line-in (rear panel) */
15169 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15170 /* port-D for Front */
15171 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15172 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15173 /* port-E for HP out (front panel) */
15174 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15175 /* route front PCM to HP */
15176 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15177 /* port-F for mic-in (front panel) with vref */
15178 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15179 /* port-G for CLFE (rear panel) */
15180 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15181 /* port-H for side (rear panel) */
15182 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15184 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15185 /* route front mic to ADC1*/
15186 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15188 /* Unmute DAC0~3 & spdif out*/
15189 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15190 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15191 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15192 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15195 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15196 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15197 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15198 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15199 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15201 /* Unmute Stereo Mixer 15 */
15202 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15207 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15208 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15210 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15212 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15213 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15215 /* hp used DAC 3 (Front) */
15216 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15221 static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15223 * Unmute ADC0 and set the default input to mic-in
15225 /* port-A for surround (rear panel) */
15226 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15227 /* port-B for mic-in (rear panel) with vref */
15228 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15229 /* port-C for line-in (rear panel) */
15230 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15231 /* port-D for Front */
15232 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15233 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15234 /* port-E for HP out (front panel) */
15235 /* this has to be set to VREF80 */
15236 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15237 /* route front PCM to HP */
15238 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15239 /* port-F for mic-in (front panel) with vref */
15240 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15241 /* port-G for CLFE (rear panel) */
15242 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15243 /* port-H for side (rear panel) */
15244 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15246 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15247 /* route front mic to ADC1*/
15248 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15250 /* Unmute DAC0~3 & spdif out*/
15251 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15252 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15253 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15254 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15257 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15258 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15259 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15260 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15261 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15263 /* Unmute Stereo Mixer 15 */
15264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15267 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15269 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15270 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15271 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15272 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15273 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15276 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15277 /* hp used DAC 3 (Front) */
15278 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15279 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15283 static const struct hda_verb alc861_asus_init_verbs[] = {
15285 * Unmute ADC0 and set the default input to mic-in
15287 /* port-A for surround (rear panel)
15288 * according to codec#0 this is the HP jack
15290 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15291 /* route front PCM to HP */
15292 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15293 /* port-B for mic-in (rear panel) with vref */
15294 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15295 /* port-C for line-in (rear panel) */
15296 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15297 /* port-D for Front */
15298 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15299 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15300 /* port-E for HP out (front panel) */
15301 /* this has to be set to VREF80 */
15302 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15303 /* route front PCM to HP */
15304 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15305 /* port-F for mic-in (front panel) with vref */
15306 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15307 /* port-G for CLFE (rear panel) */
15308 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15309 /* port-H for side (rear panel) */
15310 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15312 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15313 /* route front mic to ADC1*/
15314 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15315 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15316 /* Unmute DAC0~3 & spdif out*/
15317 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15318 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15319 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15320 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15322 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15323 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15324 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15325 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15326 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15328 /* Unmute Stereo Mixer 15 */
15329 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15334 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15337 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15342 /* hp used DAC 3 (Front) */
15343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15348 /* additional init verbs for ASUS laptops */
15349 static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15350 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15351 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15355 static const struct hda_verb alc861_toshiba_init_verbs[] = {
15356 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15361 /* toggle speaker-output according to the hp-jack state */
15362 static void alc861_toshiba_automute(struct hda_codec *codec)
15364 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15366 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15367 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15368 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15369 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15372 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15375 if ((res >> 26) == ALC880_HP_EVENT)
15376 alc861_toshiba_automute(codec);
15379 #define ALC861_DIGOUT_NID 0x07
15381 static const struct hda_channel_mode alc861_8ch_modes[1] = {
15385 static const hda_nid_t alc861_dac_nids[4] = {
15386 /* front, surround, clfe, side */
15387 0x03, 0x06, 0x05, 0x04
15390 static const hda_nid_t alc660_dac_nids[3] = {
15391 /* front, clfe, surround */
15395 static const hda_nid_t alc861_adc_nids[1] = {
15400 static const struct hda_input_mux alc861_capture_source = {
15404 { "Front Mic", 0x3 },
15411 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15413 struct alc_spec *spec = codec->spec;
15414 hda_nid_t mix, srcs[5];
15417 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15419 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15422 for (i = 0; i < num; i++) {
15424 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15425 if (type != AC_WID_AUD_OUT)
15427 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15428 spec->multiout.num_dacs))
15434 /* fill in the dac_nids table from the parsed pin configuration */
15435 static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
15437 struct alc_spec *spec = codec->spec;
15438 const struct auto_pin_cfg *cfg = &spec->autocfg;
15440 hda_nid_t nid, dac;
15442 spec->multiout.dac_nids = spec->private_dac_nids;
15443 for (i = 0; i < cfg->line_outs; i++) {
15444 nid = cfg->line_out_pins[i];
15445 dac = alc861_look_for_dac(codec, nid);
15448 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
15453 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15454 hda_nid_t nid, int idx, unsigned int chs)
15456 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15457 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15460 #define alc861_create_out_sw(codec, pfx, nid, chs) \
15461 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15463 /* add playback controls from the parsed DAC table */
15464 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15465 const struct auto_pin_cfg *cfg)
15467 struct alc_spec *spec = codec->spec;
15469 int i, err, noutputs;
15471 noutputs = cfg->line_outs;
15472 if (spec->multi_ios > 0)
15473 noutputs += spec->multi_ios;
15475 for (i = 0; i < noutputs; i++) {
15478 nid = spec->multiout.dac_nids[i];
15481 name = alc_get_line_out_pfx(spec, i, true, &index);
15484 err = alc861_create_out_sw(codec, "Center", nid, 1);
15487 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15491 err = __alc861_create_out_sw(codec, name, nid, index, 3);
15499 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15501 struct alc_spec *spec = codec->spec;
15508 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15509 nid = alc861_look_for_dac(codec, pin);
15511 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15514 spec->multiout.hp_nid = nid;
15520 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15522 int pin_type, hda_nid_t dac)
15524 hda_nid_t mix, srcs[5];
15527 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15529 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15531 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15533 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15536 for (i = 0; i < num; i++) {
15538 if (srcs[i] == dac || srcs[i] == 0x15)
15539 mute = AMP_IN_UNMUTE(i);
15541 mute = AMP_IN_MUTE(i);
15542 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15547 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15549 struct alc_spec *spec = codec->spec;
15552 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
15553 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15554 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15556 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15557 spec->multiout.dac_nids[i]);
15561 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15563 struct alc_spec *spec = codec->spec;
15565 if (spec->autocfg.hp_outs)
15566 alc861_auto_set_output_and_unmute(codec,
15567 spec->autocfg.hp_pins[0],
15569 spec->multiout.hp_nid);
15570 if (spec->autocfg.speaker_outs)
15571 alc861_auto_set_output_and_unmute(codec,
15572 spec->autocfg.speaker_pins[0],
15574 spec->multiout.dac_nids[0]);
15577 /* parse the BIOS configuration and set up the alc_spec */
15578 /* return 1 if successful, 0 if the proper config is not found,
15579 * or a negative error code
15581 static int alc861_parse_auto_config(struct hda_codec *codec)
15583 struct alc_spec *spec = codec->spec;
15585 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15587 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15591 if (!spec->autocfg.line_outs)
15592 return 0; /* can't find valid BIOS pin config */
15594 err = alc861_auto_fill_dac_nids(codec);
15597 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
15600 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15603 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
15606 err = alc_auto_create_input_ctls(codec);
15610 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15612 alc_auto_parse_digital(codec);
15614 if (spec->kctls.list)
15615 add_mixer(spec, spec->kctls.list);
15617 spec->num_mux_defs = 1;
15618 spec->input_mux = &spec->private_imux[0];
15620 if (!spec->dual_adc_switch)
15621 alc_remove_invalid_adc_nids(codec);
15623 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
15625 set_capture_mixer(codec);
15630 /* additional initialization for auto-configuration model */
15631 static void alc861_auto_init(struct hda_codec *codec)
15633 struct alc_spec *spec = codec->spec;
15634 alc861_auto_init_multi_out(codec);
15635 alc861_auto_init_hp_out(codec);
15636 alc_auto_init_analog_input(codec);
15637 alc_auto_init_digital(codec);
15638 if (spec->unsol_event)
15639 alc_inithook(codec);
15642 #ifdef CONFIG_SND_HDA_POWER_SAVE
15643 static const struct hda_amp_list alc861_loopbacks[] = {
15644 { 0x15, HDA_INPUT, 0 },
15645 { 0x15, HDA_INPUT, 1 },
15646 { 0x15, HDA_INPUT, 2 },
15647 { 0x15, HDA_INPUT, 3 },
15654 * configuration and preset
15656 static const char * const alc861_models[ALC861_MODEL_LAST] = {
15657 [ALC861_3ST] = "3stack",
15658 [ALC660_3ST] = "3stack-660",
15659 [ALC861_3ST_DIG] = "3stack-dig",
15660 [ALC861_6ST_DIG] = "6stack-dig",
15661 [ALC861_UNIWILL_M31] = "uniwill-m31",
15662 [ALC861_TOSHIBA] = "toshiba",
15663 [ALC861_ASUS] = "asus",
15664 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15665 [ALC861_AUTO] = "auto",
15668 static const struct snd_pci_quirk alc861_cfg_tbl[] = {
15669 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15670 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15671 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15672 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15673 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15674 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15675 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15676 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15677 * Any other models that need this preset?
15679 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15680 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15681 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15682 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15683 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15684 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15685 /* FIXME: the below seems conflict */
15686 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15687 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15688 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15692 static const struct alc_config_preset alc861_presets[] = {
15694 .mixers = { alc861_3ST_mixer },
15695 .init_verbs = { alc861_threestack_init_verbs },
15696 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15697 .dac_nids = alc861_dac_nids,
15698 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15699 .channel_mode = alc861_threestack_modes,
15701 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15702 .adc_nids = alc861_adc_nids,
15703 .input_mux = &alc861_capture_source,
15705 [ALC861_3ST_DIG] = {
15706 .mixers = { alc861_base_mixer },
15707 .init_verbs = { alc861_threestack_init_verbs },
15708 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15709 .dac_nids = alc861_dac_nids,
15710 .dig_out_nid = ALC861_DIGOUT_NID,
15711 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15712 .channel_mode = alc861_threestack_modes,
15714 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15715 .adc_nids = alc861_adc_nids,
15716 .input_mux = &alc861_capture_source,
15718 [ALC861_6ST_DIG] = {
15719 .mixers = { alc861_base_mixer },
15720 .init_verbs = { alc861_base_init_verbs },
15721 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15722 .dac_nids = alc861_dac_nids,
15723 .dig_out_nid = ALC861_DIGOUT_NID,
15724 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15725 .channel_mode = alc861_8ch_modes,
15726 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15727 .adc_nids = alc861_adc_nids,
15728 .input_mux = &alc861_capture_source,
15731 .mixers = { alc861_3ST_mixer },
15732 .init_verbs = { alc861_threestack_init_verbs },
15733 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15734 .dac_nids = alc660_dac_nids,
15735 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15736 .channel_mode = alc861_threestack_modes,
15738 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15739 .adc_nids = alc861_adc_nids,
15740 .input_mux = &alc861_capture_source,
15742 [ALC861_UNIWILL_M31] = {
15743 .mixers = { alc861_uniwill_m31_mixer },
15744 .init_verbs = { alc861_uniwill_m31_init_verbs },
15745 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15746 .dac_nids = alc861_dac_nids,
15747 .dig_out_nid = ALC861_DIGOUT_NID,
15748 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15749 .channel_mode = alc861_uniwill_m31_modes,
15751 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15752 .adc_nids = alc861_adc_nids,
15753 .input_mux = &alc861_capture_source,
15755 [ALC861_TOSHIBA] = {
15756 .mixers = { alc861_toshiba_mixer },
15757 .init_verbs = { alc861_base_init_verbs,
15758 alc861_toshiba_init_verbs },
15759 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15760 .dac_nids = alc861_dac_nids,
15761 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15762 .channel_mode = alc883_3ST_2ch_modes,
15763 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15764 .adc_nids = alc861_adc_nids,
15765 .input_mux = &alc861_capture_source,
15766 .unsol_event = alc861_toshiba_unsol_event,
15767 .init_hook = alc861_toshiba_automute,
15770 .mixers = { alc861_asus_mixer },
15771 .init_verbs = { alc861_asus_init_verbs },
15772 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15773 .dac_nids = alc861_dac_nids,
15774 .dig_out_nid = ALC861_DIGOUT_NID,
15775 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15776 .channel_mode = alc861_asus_modes,
15779 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15780 .adc_nids = alc861_adc_nids,
15781 .input_mux = &alc861_capture_source,
15783 [ALC861_ASUS_LAPTOP] = {
15784 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15785 .init_verbs = { alc861_asus_init_verbs,
15786 alc861_asus_laptop_init_verbs },
15787 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15788 .dac_nids = alc861_dac_nids,
15789 .dig_out_nid = ALC861_DIGOUT_NID,
15790 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15791 .channel_mode = alc883_3ST_2ch_modes,
15793 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15794 .adc_nids = alc861_adc_nids,
15795 .input_mux = &alc861_capture_source,
15799 /* Pin config fixes */
15801 PINFIX_FSC_AMILO_PI1505,
15804 static const struct alc_fixup alc861_fixups[] = {
15805 [PINFIX_FSC_AMILO_PI1505] = {
15806 .type = ALC_FIXUP_PINS,
15807 .v.pins = (const struct alc_pincfg[]) {
15808 { 0x0b, 0x0221101f }, /* HP */
15809 { 0x0f, 0x90170310 }, /* speaker */
15815 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
15816 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15820 static int patch_alc861(struct hda_codec *codec)
15822 struct alc_spec *spec;
15826 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15830 codec->spec = spec;
15832 spec->mixer_nid = 0x15;
15834 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15838 if (board_config < 0) {
15839 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15841 board_config = ALC861_AUTO;
15844 if (board_config == ALC861_AUTO) {
15845 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
15846 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15849 if (board_config == ALC861_AUTO) {
15850 /* automatic parse from the BIOS config */
15851 err = alc861_parse_auto_config(codec);
15857 "hda_codec: Cannot set up configuration "
15858 "from BIOS. Using base mode...\n");
15859 board_config = ALC861_3ST_DIG;
15863 err = snd_hda_attach_beep_device(codec, 0x23);
15869 if (board_config != ALC861_AUTO)
15870 setup_preset(codec, &alc861_presets[board_config]);
15872 if (!spec->cap_mixer)
15873 set_capture_mixer(codec);
15874 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15876 spec->vmaster_nid = 0x03;
15878 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15880 codec->patch_ops = alc_patch_ops;
15881 if (board_config == ALC861_AUTO) {
15882 spec->init_hook = alc861_auto_init;
15883 #ifdef CONFIG_SND_HDA_POWER_SAVE
15884 spec->power_hook = alc_power_eapd;
15887 #ifdef CONFIG_SND_HDA_POWER_SAVE
15888 if (!spec->loopback.amplist)
15889 spec->loopback.amplist = alc861_loopbacks;
15896 * ALC861-VD support
15900 * In addition, an independent DAC
15902 #define ALC861VD_DIGOUT_NID 0x06
15904 static const hda_nid_t alc861vd_dac_nids[4] = {
15905 /* front, surr, clfe, side surr */
15906 0x02, 0x03, 0x04, 0x05
15909 /* dac_nids for ALC660vd are in a different order - according to
15910 * Realtek's driver.
15911 * This should probably result in a different mixer for 6stack models
15912 * of ALC660vd codecs, but for now there is only 3stack mixer
15913 * - and it is the same as in 861vd.
15914 * adc_nids in ALC660vd are (is) the same as in 861vd
15916 static const hda_nid_t alc660vd_dac_nids[3] = {
15917 /* front, rear, clfe, rear_surr */
15921 static const hda_nid_t alc861vd_adc_nids[1] = {
15926 static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15929 /* FIXME: should be a matrix-type input source selection */
15930 static const struct hda_input_mux alc861vd_capture_source = {
15934 { "Front Mic", 0x1 },
15940 static const struct hda_input_mux alc861vd_dallas_capture_source = {
15944 { "Internal Mic", 0x1 },
15948 static const struct hda_input_mux alc861vd_hp_capture_source = {
15951 { "Front Mic", 0x0 },
15952 { "ATAPI Mic", 0x1 },
15959 static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15966 static const struct hda_verb alc861vd_6stack_ch6_init[] = {
15967 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15968 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15969 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15970 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15977 static const struct hda_verb alc861vd_6stack_ch8_init[] = {
15978 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15979 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15980 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15981 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15985 static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
15986 { 6, alc861vd_6stack_ch6_init },
15987 { 8, alc861vd_6stack_ch8_init },
15990 static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15993 .name = "Channel Mode",
15994 .info = alc_ch_mode_info,
15995 .get = alc_ch_mode_get,
15996 .put = alc_ch_mode_put,
16001 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16002 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16004 static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16005 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16006 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16008 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16009 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16011 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16013 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16015 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16016 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16018 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16019 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16021 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16023 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16027 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16028 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16029 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16040 static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16041 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16042 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16050 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16051 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16052 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16054 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16055 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16063 static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16064 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16065 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16066 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16068 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16070 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16071 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16074 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16075 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16076 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16078 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16079 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16084 /* Pin assignment: Speaker=0x14, HP = 0x15,
16085 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16087 static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16088 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16089 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16090 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16091 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16092 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16095 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16096 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16097 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16101 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16102 * Front Mic=0x18, ATAPI Mic = 0x19,
16104 static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16105 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16106 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16107 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16108 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16109 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16110 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16111 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16112 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16118 * generic initialization of ADC, input mixers and output mixers
16120 static const struct hda_verb alc861vd_volume_init_verbs[] = {
16122 * Unmute ADC0 and set the default input to mic-in
16124 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16127 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16128 * the analog-loopback mixer widget
16130 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16132 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16133 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16137 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16138 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16144 * Set up output mixers (0x02 - 0x05)
16146 /* set vol=0 to output mixers */
16147 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16148 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16149 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16150 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16152 /* set up input amps for analog loopback */
16153 /* Amp Indices: DAC = 0, mixer = 1 */
16154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16156 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16157 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16158 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16159 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16161 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16167 * 3-stack pin configuration:
16168 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16170 static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16172 * Set pin mode and muting
16174 /* set front pin widgets 0x14 for output */
16175 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16176 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16177 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16179 /* Mic (rear) pin: input vref at 80% */
16180 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16181 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16182 /* Front Mic pin: input vref at 80% */
16183 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16184 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16185 /* Line In pin: input */
16186 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16187 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16188 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16189 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16190 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16191 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16192 /* CD pin widget for input */
16193 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16199 * 6-stack pin configuration:
16201 static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16203 * Set pin mode and muting
16205 /* set front pin widgets 0x14 for output */
16206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16208 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16210 /* Rear Pin: output 1 (0x0d) */
16211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16212 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16214 /* CLFE Pin: output 2 (0x0e) */
16215 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16216 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16217 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16218 /* Side Pin: output 3 (0x0f) */
16219 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16220 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16221 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16223 /* Mic (rear) pin: input vref at 80% */
16224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16225 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16226 /* Front Mic pin: input vref at 80% */
16227 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16228 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16229 /* Line In pin: input */
16230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16232 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16233 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16234 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16235 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16236 /* CD pin widget for input */
16237 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16242 static const struct hda_verb alc861vd_eapd_verbs[] = {
16243 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16247 static const struct hda_verb alc660vd_eapd_verbs[] = {
16248 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16249 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16253 static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16256 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16257 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16258 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16262 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16264 struct alc_spec *spec = codec->spec;
16265 spec->autocfg.hp_pins[0] = 0x1b;
16266 spec->autocfg.speaker_pins[0] = 0x14;
16267 spec->automute = 1;
16268 spec->automute_mode = ALC_AUTOMUTE_AMP;
16271 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16273 alc_hp_automute(codec);
16274 alc88x_simple_mic_automute(codec);
16277 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16280 switch (res >> 26) {
16281 case ALC880_MIC_EVENT:
16282 alc88x_simple_mic_automute(codec);
16285 alc_sku_unsol_event(codec, res);
16290 static const struct hda_verb alc861vd_dallas_verbs[] = {
16291 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16292 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16293 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16294 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16299 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16300 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16301 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16302 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16303 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16305 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16306 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16309 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16310 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16311 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16312 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16314 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16320 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16321 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16329 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16335 /* toggle speaker-output according to the hp-jack state */
16336 static void alc861vd_dallas_setup(struct hda_codec *codec)
16338 struct alc_spec *spec = codec->spec;
16340 spec->autocfg.hp_pins[0] = 0x15;
16341 spec->autocfg.speaker_pins[0] = 0x14;
16342 spec->automute = 1;
16343 spec->automute_mode = ALC_AUTOMUTE_AMP;
16346 #ifdef CONFIG_SND_HDA_POWER_SAVE
16347 #define alc861vd_loopbacks alc880_loopbacks
16351 * configuration and preset
16353 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16354 [ALC660VD_3ST] = "3stack-660",
16355 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16356 [ALC660VD_ASUS_V1S] = "asus-v1s",
16357 [ALC861VD_3ST] = "3stack",
16358 [ALC861VD_3ST_DIG] = "3stack-digout",
16359 [ALC861VD_6ST_DIG] = "6stack-digout",
16360 [ALC861VD_LENOVO] = "lenovo",
16361 [ALC861VD_DALLAS] = "dallas",
16362 [ALC861VD_HP] = "hp",
16363 [ALC861VD_AUTO] = "auto",
16366 static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16367 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16368 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16369 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16370 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16371 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16372 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16373 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16374 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16375 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16376 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16377 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16378 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16379 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16380 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16381 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16385 static const struct alc_config_preset alc861vd_presets[] = {
16387 .mixers = { alc861vd_3st_mixer },
16388 .init_verbs = { alc861vd_volume_init_verbs,
16389 alc861vd_3stack_init_verbs },
16390 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16391 .dac_nids = alc660vd_dac_nids,
16392 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16393 .channel_mode = alc861vd_3stack_2ch_modes,
16394 .input_mux = &alc861vd_capture_source,
16396 [ALC660VD_3ST_DIG] = {
16397 .mixers = { alc861vd_3st_mixer },
16398 .init_verbs = { alc861vd_volume_init_verbs,
16399 alc861vd_3stack_init_verbs },
16400 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16401 .dac_nids = alc660vd_dac_nids,
16402 .dig_out_nid = ALC861VD_DIGOUT_NID,
16403 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16404 .channel_mode = alc861vd_3stack_2ch_modes,
16405 .input_mux = &alc861vd_capture_source,
16408 .mixers = { alc861vd_3st_mixer },
16409 .init_verbs = { alc861vd_volume_init_verbs,
16410 alc861vd_3stack_init_verbs },
16411 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16412 .dac_nids = alc861vd_dac_nids,
16413 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16414 .channel_mode = alc861vd_3stack_2ch_modes,
16415 .input_mux = &alc861vd_capture_source,
16417 [ALC861VD_3ST_DIG] = {
16418 .mixers = { alc861vd_3st_mixer },
16419 .init_verbs = { alc861vd_volume_init_verbs,
16420 alc861vd_3stack_init_verbs },
16421 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16422 .dac_nids = alc861vd_dac_nids,
16423 .dig_out_nid = ALC861VD_DIGOUT_NID,
16424 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16425 .channel_mode = alc861vd_3stack_2ch_modes,
16426 .input_mux = &alc861vd_capture_source,
16428 [ALC861VD_6ST_DIG] = {
16429 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16430 .init_verbs = { alc861vd_volume_init_verbs,
16431 alc861vd_6stack_init_verbs },
16432 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16433 .dac_nids = alc861vd_dac_nids,
16434 .dig_out_nid = ALC861VD_DIGOUT_NID,
16435 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16436 .channel_mode = alc861vd_6stack_modes,
16437 .input_mux = &alc861vd_capture_source,
16439 [ALC861VD_LENOVO] = {
16440 .mixers = { alc861vd_lenovo_mixer },
16441 .init_verbs = { alc861vd_volume_init_verbs,
16442 alc861vd_3stack_init_verbs,
16443 alc861vd_eapd_verbs,
16444 alc861vd_lenovo_unsol_verbs },
16445 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16446 .dac_nids = alc660vd_dac_nids,
16447 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16448 .channel_mode = alc861vd_3stack_2ch_modes,
16449 .input_mux = &alc861vd_capture_source,
16450 .unsol_event = alc861vd_lenovo_unsol_event,
16451 .setup = alc861vd_lenovo_setup,
16452 .init_hook = alc861vd_lenovo_init_hook,
16454 [ALC861VD_DALLAS] = {
16455 .mixers = { alc861vd_dallas_mixer },
16456 .init_verbs = { alc861vd_dallas_verbs },
16457 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16458 .dac_nids = alc861vd_dac_nids,
16459 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16460 .channel_mode = alc861vd_3stack_2ch_modes,
16461 .input_mux = &alc861vd_dallas_capture_source,
16462 .unsol_event = alc_sku_unsol_event,
16463 .setup = alc861vd_dallas_setup,
16464 .init_hook = alc_hp_automute,
16467 .mixers = { alc861vd_hp_mixer },
16468 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16469 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16470 .dac_nids = alc861vd_dac_nids,
16471 .dig_out_nid = ALC861VD_DIGOUT_NID,
16472 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16473 .channel_mode = alc861vd_3stack_2ch_modes,
16474 .input_mux = &alc861vd_hp_capture_source,
16475 .unsol_event = alc_sku_unsol_event,
16476 .setup = alc861vd_dallas_setup,
16477 .init_hook = alc_hp_automute,
16479 [ALC660VD_ASUS_V1S] = {
16480 .mixers = { alc861vd_lenovo_mixer },
16481 .init_verbs = { alc861vd_volume_init_verbs,
16482 alc861vd_3stack_init_verbs,
16483 alc861vd_eapd_verbs,
16484 alc861vd_lenovo_unsol_verbs },
16485 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16486 .dac_nids = alc660vd_dac_nids,
16487 .dig_out_nid = ALC861VD_DIGOUT_NID,
16488 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16489 .channel_mode = alc861vd_3stack_2ch_modes,
16490 .input_mux = &alc861vd_capture_source,
16491 .unsol_event = alc861vd_lenovo_unsol_event,
16492 .setup = alc861vd_lenovo_setup,
16493 .init_hook = alc861vd_lenovo_init_hook,
16498 * BIOS auto configuration
16500 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16501 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16503 /* add playback controls from the parsed DAC table */
16504 /* Based on ALC880 version. But ALC861VD has separate,
16505 * different NIDs for mute/unmute switch and volume control */
16506 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16507 const struct auto_pin_cfg *cfg)
16509 hda_nid_t nid_v, nid_s;
16510 int i, err, noutputs;
16512 noutputs = cfg->line_outs;
16513 if (spec->multi_ios > 0)
16514 noutputs += spec->multi_ios;
16516 for (i = 0; i < noutputs; i++) {
16519 if (!spec->multiout.dac_nids[i])
16521 nid_v = alc861vd_idx_to_mixer_vol(
16523 spec->multiout.dac_nids[i]));
16524 nid_s = alc861vd_idx_to_mixer_switch(
16526 spec->multiout.dac_nids[i]));
16528 name = alc_get_line_out_pfx(spec, i, true, &index);
16531 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16533 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16537 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16539 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16543 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16545 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16549 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16551 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16556 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16558 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16562 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16564 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16573 /* add playback controls for speaker and HP outputs */
16574 /* Based on ALC880 version. But ALC861VD has separate,
16575 * different NIDs for mute/unmute switch and volume control */
16576 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16577 hda_nid_t pin, const char *pfx)
16579 hda_nid_t nid_v, nid_s;
16585 if (alc880_is_fixed_pin(pin)) {
16586 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16587 /* specify the DAC as the extra output */
16588 if (!spec->multiout.hp_nid)
16589 spec->multiout.hp_nid = nid_v;
16591 spec->multiout.extra_out_nid[0] = nid_v;
16592 /* control HP volume/switch on the output mixer amp */
16593 nid_v = alc861vd_idx_to_mixer_vol(
16594 alc880_fixed_pin_idx(pin));
16595 nid_s = alc861vd_idx_to_mixer_switch(
16596 alc880_fixed_pin_idx(pin));
16598 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16599 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16602 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16603 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16606 } else if (alc880_is_multi_pin(pin)) {
16607 /* set manual connection */
16608 /* we have only a switch on HP-out PIN */
16609 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
16610 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16617 /* parse the BIOS configuration and set up the alc_spec
16618 * return 1 if successful, 0 if the proper config is not found,
16619 * or a negative error code
16620 * Based on ALC880 version - had to change it to override
16621 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16622 static int alc861vd_parse_auto_config(struct hda_codec *codec)
16624 struct alc_spec *spec = codec->spec;
16626 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16628 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16632 if (!spec->autocfg.line_outs)
16633 return 0; /* can't find valid BIOS pin config */
16635 err = alc_auto_fill_dac_nids(codec);
16638 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
16641 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16644 err = alc861vd_auto_create_extra_out(spec,
16645 spec->autocfg.speaker_pins[0],
16649 err = alc861vd_auto_create_extra_out(spec,
16650 spec->autocfg.hp_pins[0],
16654 err = alc_auto_create_input_ctls(codec);
16658 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16660 alc_auto_parse_digital(codec);
16662 if (spec->kctls.list)
16663 add_mixer(spec, spec->kctls.list);
16665 spec->num_mux_defs = 1;
16666 spec->input_mux = &spec->private_imux[0];
16668 if (!spec->dual_adc_switch)
16669 alc_remove_invalid_adc_nids(codec);
16671 err = alc_auto_add_mic_boost(codec);
16675 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
16680 /* additional initialization for auto-configuration model */
16681 static void alc861vd_auto_init(struct hda_codec *codec)
16683 struct alc_spec *spec = codec->spec;
16684 alc_auto_init_multi_out(codec);
16685 alc_auto_init_extra_out(codec);
16686 alc_auto_init_analog_input(codec);
16687 alc_auto_init_input_src(codec);
16688 alc_auto_init_digital(codec);
16689 if (spec->unsol_event)
16690 alc_inithook(codec);
16694 ALC660VD_FIX_ASUS_GPIO1
16698 static const struct alc_fixup alc861vd_fixups[] = {
16699 [ALC660VD_FIX_ASUS_GPIO1] = {
16700 .type = ALC_FIXUP_VERBS,
16701 .v.verbs = (const struct hda_verb[]) {
16702 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16703 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16704 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16710 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16711 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16715 static int patch_alc861vd(struct hda_codec *codec)
16717 struct alc_spec *spec;
16718 int err, board_config;
16720 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16724 codec->spec = spec;
16726 spec->mixer_nid = 0x0b;
16728 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16732 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
16733 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16735 board_config = ALC861VD_AUTO;
16738 if (board_config == ALC861VD_AUTO) {
16739 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
16740 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16743 if (board_config == ALC861VD_AUTO) {
16744 /* automatic parse from the BIOS config */
16745 err = alc861vd_parse_auto_config(codec);
16751 "hda_codec: Cannot set up configuration "
16752 "from BIOS. Using base mode...\n");
16753 board_config = ALC861VD_3ST;
16757 err = snd_hda_attach_beep_device(codec, 0x23);
16763 if (board_config != ALC861VD_AUTO)
16764 setup_preset(codec, &alc861vd_presets[board_config]);
16766 if (codec->vendor_id == 0x10ec0660) {
16767 /* always turn on EAPD */
16768 add_verb(spec, alc660vd_eapd_verbs);
16771 if (!spec->adc_nids) {
16772 alc_auto_fill_adc_caps(codec);
16773 alc_remove_invalid_adc_nids(codec);
16776 set_capture_mixer(codec);
16777 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16779 spec->vmaster_nid = 0x02;
16781 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16783 codec->patch_ops = alc_patch_ops;
16785 if (board_config == ALC861VD_AUTO)
16786 spec->init_hook = alc861vd_auto_init;
16787 spec->shutup = alc_eapd_shutup;
16788 #ifdef CONFIG_SND_HDA_POWER_SAVE
16789 if (!spec->loopback.amplist)
16790 spec->loopback.amplist = alc861vd_loopbacks;
16799 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16800 * configuration. Each pin widget can choose any input DACs and a mixer.
16801 * Each ADC is connected from a mixer of all inputs. This makes possible
16802 * 6-channel independent captures.
16804 * In addition, an independent DAC for the multi-playback (not used in this
16807 #define ALC662_DIGOUT_NID 0x06
16808 #define ALC662_DIGIN_NID 0x0a
16810 static const hda_nid_t alc662_dac_nids[3] = {
16811 /* front, rear, clfe */
16815 static const hda_nid_t alc272_dac_nids[2] = {
16819 static const hda_nid_t alc662_adc_nids[2] = {
16824 static const hda_nid_t alc272_adc_nids[1] = {
16829 static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16830 static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16834 /* FIXME: should be a matrix-type input source selection */
16835 static const struct hda_input_mux alc662_capture_source = {
16839 { "Front Mic", 0x1 },
16845 static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
16853 static const struct hda_input_mux alc663_capture_source = {
16857 { "Front Mic", 0x1 },
16862 #if 0 /* set to 1 for testing other input sources below */
16863 static const struct hda_input_mux alc272_nc10_capture_source = {
16866 { "Autoselect Mic", 0x0 },
16867 { "Internal Mic", 0x1 },
16868 { "In-0x02", 0x2 },
16869 { "In-0x03", 0x3 },
16870 { "In-0x04", 0x4 },
16871 { "In-0x05", 0x5 },
16872 { "In-0x06", 0x6 },
16873 { "In-0x07", 0x7 },
16874 { "In-0x08", 0x8 },
16875 { "In-0x09", 0x9 },
16876 { "In-0x0a", 0x0a },
16877 { "In-0x0b", 0x0b },
16878 { "In-0x0c", 0x0c },
16879 { "In-0x0d", 0x0d },
16880 { "In-0x0e", 0x0e },
16881 { "In-0x0f", 0x0f },
16889 static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16896 static const struct hda_verb alc662_3ST_ch2_init[] = {
16897 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16898 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16899 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16900 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16907 static const struct hda_verb alc662_3ST_ch6_init[] = {
16908 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16909 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16910 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16911 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16912 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16913 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16917 static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16918 { 2, alc662_3ST_ch2_init },
16919 { 6, alc662_3ST_ch6_init },
16925 static const struct hda_verb alc662_sixstack_ch6_init[] = {
16926 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16927 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16928 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16935 static const struct hda_verb alc662_sixstack_ch8_init[] = {
16936 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16937 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16938 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16942 static const struct hda_channel_mode alc662_5stack_modes[2] = {
16943 { 2, alc662_sixstack_ch6_init },
16944 { 6, alc662_sixstack_ch8_init },
16947 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16948 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16951 static const struct snd_kcontrol_new alc662_base_mixer[] = {
16952 /* output mixer control */
16953 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16954 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16955 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16956 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16957 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16958 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16959 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16960 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16961 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16963 /*Input mixer control */
16964 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16965 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16966 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16967 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16968 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16969 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16970 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16971 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16975 static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16976 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16977 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16978 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16979 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16980 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16981 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16982 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16990 static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16991 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16992 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16993 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16994 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16995 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16996 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16997 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16998 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16999 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17000 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17001 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17006 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17007 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17011 static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17012 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17013 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17014 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17015 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17024 static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17025 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17026 ALC262_HIPPO_MASTER_SWITCH,
17028 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17032 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17033 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17034 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17038 static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17039 ALC262_HIPPO_MASTER_SWITCH,
17040 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17042 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17043 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17044 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17052 static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17053 .ops = &snd_hda_bind_vol,
17055 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17056 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17061 static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17062 .ops = &snd_hda_bind_sw,
17064 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17065 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17070 static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17071 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17072 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17078 static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17079 .ops = &snd_hda_bind_sw,
17081 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17082 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17083 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17088 static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17089 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17090 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17093 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17094 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17099 static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17100 .ops = &snd_hda_bind_sw,
17102 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17103 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17104 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17109 static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17110 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17111 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17114 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17115 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17119 static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17121 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17125 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17126 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17130 static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17131 .ops = &snd_hda_bind_vol,
17133 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17134 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17139 static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17140 .ops = &snd_hda_bind_sw,
17142 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17143 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17148 static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17149 HDA_BIND_VOL("Master Playback Volume",
17150 &alc663_asus_two_bind_master_vol),
17151 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17159 static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17160 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17161 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17162 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17169 static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17170 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17171 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17172 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17173 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17178 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17179 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17183 static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17184 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17185 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17186 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17190 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17191 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17193 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17197 static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17198 .ops = &snd_hda_bind_sw,
17200 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17201 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17202 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17203 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17204 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17209 static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17210 .ops = &snd_hda_bind_sw,
17212 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17213 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17218 static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17219 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17220 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17221 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17222 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17223 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17224 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17225 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17226 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17231 static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17232 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17233 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17234 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17235 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17236 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17238 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17243 static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17246 .name = "Channel Mode",
17247 .info = alc_ch_mode_info,
17248 .get = alc_ch_mode_get,
17249 .put = alc_ch_mode_put,
17254 static const struct hda_verb alc662_init_verbs[] = {
17255 /* ADC: mute amp left and right */
17256 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17257 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17260 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17262 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17266 /* Front Pin: output 0 (0x0c) */
17267 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17268 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17270 /* Rear Pin: output 1 (0x0d) */
17271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17272 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17274 /* CLFE Pin: output 2 (0x0e) */
17275 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17276 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17278 /* Mic (rear) pin: input vref at 80% */
17279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17281 /* Front Mic pin: input vref at 80% */
17282 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17283 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17284 /* Line In pin: input */
17285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17287 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17288 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17289 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17290 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17291 /* CD pin widget for input */
17292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17294 /* FIXME: use matrix-type input source selection */
17295 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17298 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17303 static const struct hda_verb alc662_eapd_init_verbs[] = {
17304 /* always trun on EAPD */
17305 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17306 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17310 static const struct hda_verb alc662_sue_init_verbs[] = {
17311 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17312 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17316 static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17317 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17318 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17322 /* Set Unsolicited Event*/
17323 static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17324 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17325 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17329 static const struct hda_verb alc663_m51va_init_verbs[] = {
17330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17331 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17332 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17333 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17334 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17335 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17337 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17338 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17342 static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17343 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17344 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17345 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17348 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17349 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17353 static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17356 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17358 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17360 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17361 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17365 static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17376 static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17377 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17378 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17379 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17380 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17381 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17386 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17387 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17392 static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17393 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17394 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17395 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17396 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17398 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17399 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17402 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17403 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17404 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17408 static const struct hda_verb alc663_g71v_init_verbs[] = {
17409 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17410 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17411 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17413 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17414 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17415 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17417 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17418 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17419 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17423 static const struct hda_verb alc663_g50v_init_verbs[] = {
17424 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17425 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17426 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17428 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17429 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17433 static const struct hda_verb alc662_ecs_init_verbs[] = {
17434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17436 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17437 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17441 static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17442 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17443 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17445 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17446 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17447 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17449 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17450 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17451 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17452 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17456 static const struct hda_verb alc272_dell_init_verbs[] = {
17457 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17458 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17459 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17461 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17462 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17463 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17471 static const struct hda_verb alc663_mode7_init_verbs[] = {
17472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17473 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17474 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17475 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17476 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17477 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17478 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17479 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17480 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17481 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17484 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17485 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17486 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17490 static const struct hda_verb alc663_mode8_init_verbs[] = {
17491 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17495 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17496 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17497 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17498 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17499 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17500 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17501 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17502 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17503 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17504 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17505 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17506 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17510 static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17511 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17512 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17516 static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17517 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17518 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17522 static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17524 struct alc_spec *spec = codec->spec;
17526 spec->autocfg.hp_pins[0] = 0x1b;
17527 spec->autocfg.line_out_pins[0] = 0x14;
17528 spec->autocfg.speaker_pins[0] = 0x15;
17529 spec->automute = 1;
17530 spec->detect_line = 1;
17531 spec->automute_lines = 1;
17532 spec->automute_mode = ALC_AUTOMUTE_AMP;
17535 static void alc662_eeepc_setup(struct hda_codec *codec)
17537 struct alc_spec *spec = codec->spec;
17539 alc262_hippo1_setup(codec);
17540 spec->ext_mic.pin = 0x18;
17541 spec->ext_mic.mux_idx = 0;
17542 spec->int_mic.pin = 0x19;
17543 spec->int_mic.mux_idx = 1;
17544 spec->auto_mic = 1;
17547 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17549 struct alc_spec *spec = codec->spec;
17551 spec->autocfg.hp_pins[0] = 0x14;
17552 spec->autocfg.speaker_pins[0] = 0x1b;
17553 spec->automute = 1;
17554 spec->automute_mode = ALC_AUTOMUTE_AMP;
17557 static void alc663_m51va_setup(struct hda_codec *codec)
17559 struct alc_spec *spec = codec->spec;
17560 spec->autocfg.hp_pins[0] = 0x21;
17561 spec->autocfg.speaker_pins[0] = 0x14;
17562 spec->automute_mixer_nid[0] = 0x0c;
17563 spec->automute = 1;
17564 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17565 spec->ext_mic.pin = 0x18;
17566 spec->ext_mic.mux_idx = 0;
17567 spec->int_mic.pin = 0x12;
17568 spec->int_mic.mux_idx = 9;
17569 spec->auto_mic = 1;
17572 /* ***************** Mode1 ******************************/
17573 static void alc663_mode1_setup(struct hda_codec *codec)
17575 struct alc_spec *spec = codec->spec;
17576 spec->autocfg.hp_pins[0] = 0x21;
17577 spec->autocfg.speaker_pins[0] = 0x14;
17578 spec->automute_mixer_nid[0] = 0x0c;
17579 spec->automute = 1;
17580 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17581 spec->ext_mic.pin = 0x18;
17582 spec->ext_mic.mux_idx = 0;
17583 spec->int_mic.pin = 0x19;
17584 spec->int_mic.mux_idx = 1;
17585 spec->auto_mic = 1;
17588 /* ***************** Mode2 ******************************/
17589 static void alc662_mode2_setup(struct hda_codec *codec)
17591 struct alc_spec *spec = codec->spec;
17592 spec->autocfg.hp_pins[0] = 0x1b;
17593 spec->autocfg.speaker_pins[0] = 0x14;
17594 spec->automute = 1;
17595 spec->automute_mode = ALC_AUTOMUTE_PIN;
17596 spec->ext_mic.pin = 0x18;
17597 spec->ext_mic.mux_idx = 0;
17598 spec->int_mic.pin = 0x19;
17599 spec->int_mic.mux_idx = 1;
17600 spec->auto_mic = 1;
17603 /* ***************** Mode3 ******************************/
17604 static void alc663_mode3_setup(struct hda_codec *codec)
17606 struct alc_spec *spec = codec->spec;
17607 spec->autocfg.hp_pins[0] = 0x21;
17608 spec->autocfg.hp_pins[0] = 0x15;
17609 spec->autocfg.speaker_pins[0] = 0x14;
17610 spec->automute = 1;
17611 spec->automute_mode = ALC_AUTOMUTE_PIN;
17612 spec->ext_mic.pin = 0x18;
17613 spec->ext_mic.mux_idx = 0;
17614 spec->int_mic.pin = 0x19;
17615 spec->int_mic.mux_idx = 1;
17616 spec->auto_mic = 1;
17619 /* ***************** Mode4 ******************************/
17620 static void alc663_mode4_setup(struct hda_codec *codec)
17622 struct alc_spec *spec = codec->spec;
17623 spec->autocfg.hp_pins[0] = 0x21;
17624 spec->autocfg.speaker_pins[0] = 0x14;
17625 spec->autocfg.speaker_pins[1] = 0x16;
17626 spec->automute_mixer_nid[0] = 0x0c;
17627 spec->automute_mixer_nid[1] = 0x0e;
17628 spec->automute = 1;
17629 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17630 spec->ext_mic.pin = 0x18;
17631 spec->ext_mic.mux_idx = 0;
17632 spec->int_mic.pin = 0x19;
17633 spec->int_mic.mux_idx = 1;
17634 spec->auto_mic = 1;
17637 /* ***************** Mode5 ******************************/
17638 static void alc663_mode5_setup(struct hda_codec *codec)
17640 struct alc_spec *spec = codec->spec;
17641 spec->autocfg.hp_pins[0] = 0x15;
17642 spec->autocfg.speaker_pins[0] = 0x14;
17643 spec->autocfg.speaker_pins[1] = 0x16;
17644 spec->automute_mixer_nid[0] = 0x0c;
17645 spec->automute_mixer_nid[1] = 0x0e;
17646 spec->automute = 1;
17647 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17648 spec->ext_mic.pin = 0x18;
17649 spec->ext_mic.mux_idx = 0;
17650 spec->int_mic.pin = 0x19;
17651 spec->int_mic.mux_idx = 1;
17652 spec->auto_mic = 1;
17655 /* ***************** Mode6 ******************************/
17656 static void alc663_mode6_setup(struct hda_codec *codec)
17658 struct alc_spec *spec = codec->spec;
17659 spec->autocfg.hp_pins[0] = 0x1b;
17660 spec->autocfg.hp_pins[0] = 0x15;
17661 spec->autocfg.speaker_pins[0] = 0x14;
17662 spec->automute_mixer_nid[0] = 0x0c;
17663 spec->automute = 1;
17664 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17665 spec->ext_mic.pin = 0x18;
17666 spec->ext_mic.mux_idx = 0;
17667 spec->int_mic.pin = 0x19;
17668 spec->int_mic.mux_idx = 1;
17669 spec->auto_mic = 1;
17672 /* ***************** Mode7 ******************************/
17673 static void alc663_mode7_setup(struct hda_codec *codec)
17675 struct alc_spec *spec = codec->spec;
17676 spec->autocfg.hp_pins[0] = 0x1b;
17677 spec->autocfg.hp_pins[0] = 0x21;
17678 spec->autocfg.speaker_pins[0] = 0x14;
17679 spec->autocfg.speaker_pins[0] = 0x17;
17680 spec->automute = 1;
17681 spec->automute_mode = ALC_AUTOMUTE_PIN;
17682 spec->ext_mic.pin = 0x18;
17683 spec->ext_mic.mux_idx = 0;
17684 spec->int_mic.pin = 0x19;
17685 spec->int_mic.mux_idx = 1;
17686 spec->auto_mic = 1;
17689 /* ***************** Mode8 ******************************/
17690 static void alc663_mode8_setup(struct hda_codec *codec)
17692 struct alc_spec *spec = codec->spec;
17693 spec->autocfg.hp_pins[0] = 0x21;
17694 spec->autocfg.hp_pins[1] = 0x15;
17695 spec->autocfg.speaker_pins[0] = 0x14;
17696 spec->autocfg.speaker_pins[0] = 0x17;
17697 spec->automute = 1;
17698 spec->automute_mode = ALC_AUTOMUTE_PIN;
17699 spec->ext_mic.pin = 0x18;
17700 spec->ext_mic.mux_idx = 0;
17701 spec->int_mic.pin = 0x12;
17702 spec->int_mic.mux_idx = 9;
17703 spec->auto_mic = 1;
17706 static void alc663_g71v_setup(struct hda_codec *codec)
17708 struct alc_spec *spec = codec->spec;
17709 spec->autocfg.hp_pins[0] = 0x21;
17710 spec->autocfg.line_out_pins[0] = 0x15;
17711 spec->autocfg.speaker_pins[0] = 0x14;
17712 spec->automute = 1;
17713 spec->automute_mode = ALC_AUTOMUTE_AMP;
17714 spec->detect_line = 1;
17715 spec->automute_lines = 1;
17716 spec->ext_mic.pin = 0x18;
17717 spec->ext_mic.mux_idx = 0;
17718 spec->int_mic.pin = 0x12;
17719 spec->int_mic.mux_idx = 9;
17720 spec->auto_mic = 1;
17723 #define alc663_g50v_setup alc663_m51va_setup
17725 static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
17726 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17727 ALC262_HIPPO_MASTER_SWITCH,
17729 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
17730 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17731 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17733 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17734 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17735 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17739 static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
17740 /* Master Playback automatically created from Speaker and Headphone */
17741 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17742 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17743 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17748 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17750 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17751 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17752 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17756 #ifdef CONFIG_SND_HDA_POWER_SAVE
17757 #define alc662_loopbacks alc880_loopbacks
17762 * configuration and preset
17764 static const char * const alc662_models[ALC662_MODEL_LAST] = {
17765 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17766 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17767 [ALC662_3ST_6ch] = "3stack-6ch",
17768 [ALC662_5ST_DIG] = "5stack-dig",
17769 [ALC662_LENOVO_101E] = "lenovo-101e",
17770 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17771 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17772 [ALC662_ECS] = "ecs",
17773 [ALC663_ASUS_M51VA] = "m51va",
17774 [ALC663_ASUS_G71V] = "g71v",
17775 [ALC663_ASUS_H13] = "h13",
17776 [ALC663_ASUS_G50V] = "g50v",
17777 [ALC663_ASUS_MODE1] = "asus-mode1",
17778 [ALC662_ASUS_MODE2] = "asus-mode2",
17779 [ALC663_ASUS_MODE3] = "asus-mode3",
17780 [ALC663_ASUS_MODE4] = "asus-mode4",
17781 [ALC663_ASUS_MODE5] = "asus-mode5",
17782 [ALC663_ASUS_MODE6] = "asus-mode6",
17783 [ALC663_ASUS_MODE7] = "asus-mode7",
17784 [ALC663_ASUS_MODE8] = "asus-mode8",
17785 [ALC272_DELL] = "dell",
17786 [ALC272_DELL_ZM1] = "dell-zm1",
17787 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17788 [ALC662_AUTO] = "auto",
17791 static const struct snd_pci_quirk alc662_cfg_tbl[] = {
17792 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17793 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17794 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17795 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17796 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17797 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17798 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17799 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17800 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17801 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17802 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17803 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17804 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17805 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17806 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17807 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17808 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17809 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17810 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17811 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17812 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17813 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17814 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17815 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17816 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17817 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17818 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17819 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17820 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17821 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17822 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17823 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17824 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17825 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17826 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
17827 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17828 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17829 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
17830 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17831 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17832 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17833 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17834 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17835 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17836 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17837 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17838 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
17839 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
17840 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17841 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
17842 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
17843 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17844 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17845 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17846 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17847 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
17848 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
17849 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
17850 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
17851 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17852 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17853 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17854 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
17855 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17856 ALC662_3ST_6ch_DIG),
17857 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
17858 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17859 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17860 ALC662_3ST_6ch_DIG),
17861 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17862 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17863 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17864 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
17865 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
17866 ALC662_3ST_6ch_DIG),
17867 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17869 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
17873 static const struct alc_config_preset alc662_presets[] = {
17874 [ALC662_3ST_2ch_DIG] = {
17875 .mixers = { alc662_3ST_2ch_mixer },
17876 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17877 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17878 .dac_nids = alc662_dac_nids,
17879 .dig_out_nid = ALC662_DIGOUT_NID,
17880 .dig_in_nid = ALC662_DIGIN_NID,
17881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17882 .channel_mode = alc662_3ST_2ch_modes,
17883 .input_mux = &alc662_capture_source,
17885 [ALC662_3ST_6ch_DIG] = {
17886 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17887 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17888 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17889 .dac_nids = alc662_dac_nids,
17890 .dig_out_nid = ALC662_DIGOUT_NID,
17891 .dig_in_nid = ALC662_DIGIN_NID,
17892 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17893 .channel_mode = alc662_3ST_6ch_modes,
17895 .input_mux = &alc662_capture_source,
17897 [ALC662_3ST_6ch] = {
17898 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17899 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17900 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17901 .dac_nids = alc662_dac_nids,
17902 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17903 .channel_mode = alc662_3ST_6ch_modes,
17905 .input_mux = &alc662_capture_source,
17907 [ALC662_5ST_DIG] = {
17908 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
17909 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17910 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17911 .dac_nids = alc662_dac_nids,
17912 .dig_out_nid = ALC662_DIGOUT_NID,
17913 .dig_in_nid = ALC662_DIGIN_NID,
17914 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17915 .channel_mode = alc662_5stack_modes,
17916 .input_mux = &alc662_capture_source,
17918 [ALC662_LENOVO_101E] = {
17919 .mixers = { alc662_lenovo_101e_mixer },
17920 .init_verbs = { alc662_init_verbs,
17921 alc662_eapd_init_verbs,
17922 alc662_sue_init_verbs },
17923 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17924 .dac_nids = alc662_dac_nids,
17925 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17926 .channel_mode = alc662_3ST_2ch_modes,
17927 .input_mux = &alc662_lenovo_101e_capture_source,
17928 .unsol_event = alc_sku_unsol_event,
17929 .setup = alc662_lenovo_101e_setup,
17930 .init_hook = alc_inithook,
17932 [ALC662_ASUS_EEEPC_P701] = {
17933 .mixers = { alc662_eeepc_p701_mixer },
17934 .init_verbs = { alc662_init_verbs,
17935 alc662_eapd_init_verbs,
17936 alc662_eeepc_sue_init_verbs },
17937 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17938 .dac_nids = alc662_dac_nids,
17939 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17940 .channel_mode = alc662_3ST_2ch_modes,
17941 .unsol_event = alc_sku_unsol_event,
17942 .setup = alc662_eeepc_setup,
17943 .init_hook = alc_inithook,
17945 [ALC662_ASUS_EEEPC_EP20] = {
17946 .mixers = { alc662_eeepc_ep20_mixer,
17947 alc662_chmode_mixer },
17948 .init_verbs = { alc662_init_verbs,
17949 alc662_eapd_init_verbs,
17950 alc662_eeepc_ep20_sue_init_verbs },
17951 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17952 .dac_nids = alc662_dac_nids,
17953 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17954 .channel_mode = alc662_3ST_6ch_modes,
17955 .input_mux = &alc662_lenovo_101e_capture_source,
17956 .unsol_event = alc_sku_unsol_event,
17957 .setup = alc662_eeepc_ep20_setup,
17958 .init_hook = alc_inithook,
17961 .mixers = { alc662_ecs_mixer },
17962 .init_verbs = { alc662_init_verbs,
17963 alc662_eapd_init_verbs,
17964 alc662_ecs_init_verbs },
17965 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17966 .dac_nids = alc662_dac_nids,
17967 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17968 .channel_mode = alc662_3ST_2ch_modes,
17969 .unsol_event = alc_sku_unsol_event,
17970 .setup = alc662_eeepc_setup,
17971 .init_hook = alc_inithook,
17973 [ALC663_ASUS_M51VA] = {
17974 .mixers = { alc663_m51va_mixer },
17975 .init_verbs = { alc662_init_verbs,
17976 alc662_eapd_init_verbs,
17977 alc663_m51va_init_verbs },
17978 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17979 .dac_nids = alc662_dac_nids,
17980 .dig_out_nid = ALC662_DIGOUT_NID,
17981 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17982 .channel_mode = alc662_3ST_2ch_modes,
17983 .unsol_event = alc_sku_unsol_event,
17984 .setup = alc663_m51va_setup,
17985 .init_hook = alc_inithook,
17987 [ALC663_ASUS_G71V] = {
17988 .mixers = { alc663_g71v_mixer },
17989 .init_verbs = { alc662_init_verbs,
17990 alc662_eapd_init_verbs,
17991 alc663_g71v_init_verbs },
17992 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17993 .dac_nids = alc662_dac_nids,
17994 .dig_out_nid = ALC662_DIGOUT_NID,
17995 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17996 .channel_mode = alc662_3ST_2ch_modes,
17997 .unsol_event = alc_sku_unsol_event,
17998 .setup = alc663_g71v_setup,
17999 .init_hook = alc_inithook,
18001 [ALC663_ASUS_H13] = {
18002 .mixers = { alc663_m51va_mixer },
18003 .init_verbs = { alc662_init_verbs,
18004 alc662_eapd_init_verbs,
18005 alc663_m51va_init_verbs },
18006 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18007 .dac_nids = alc662_dac_nids,
18008 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18009 .channel_mode = alc662_3ST_2ch_modes,
18010 .setup = alc663_m51va_setup,
18011 .unsol_event = alc_sku_unsol_event,
18012 .init_hook = alc_inithook,
18014 [ALC663_ASUS_G50V] = {
18015 .mixers = { alc663_g50v_mixer },
18016 .init_verbs = { alc662_init_verbs,
18017 alc662_eapd_init_verbs,
18018 alc663_g50v_init_verbs },
18019 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18020 .dac_nids = alc662_dac_nids,
18021 .dig_out_nid = ALC662_DIGOUT_NID,
18022 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18023 .channel_mode = alc662_3ST_6ch_modes,
18024 .input_mux = &alc663_capture_source,
18025 .unsol_event = alc_sku_unsol_event,
18026 .setup = alc663_g50v_setup,
18027 .init_hook = alc_inithook,
18029 [ALC663_ASUS_MODE1] = {
18030 .mixers = { alc663_m51va_mixer },
18031 .cap_mixer = alc662_auto_capture_mixer,
18032 .init_verbs = { alc662_init_verbs,
18033 alc662_eapd_init_verbs,
18034 alc663_21jd_amic_init_verbs },
18035 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18037 .dac_nids = alc662_dac_nids,
18038 .dig_out_nid = ALC662_DIGOUT_NID,
18039 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18040 .channel_mode = alc662_3ST_2ch_modes,
18041 .unsol_event = alc_sku_unsol_event,
18042 .setup = alc663_mode1_setup,
18043 .init_hook = alc_inithook,
18045 [ALC662_ASUS_MODE2] = {
18046 .mixers = { alc662_1bjd_mixer },
18047 .cap_mixer = alc662_auto_capture_mixer,
18048 .init_verbs = { alc662_init_verbs,
18049 alc662_eapd_init_verbs,
18050 alc662_1bjd_amic_init_verbs },
18051 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18052 .dac_nids = alc662_dac_nids,
18053 .dig_out_nid = ALC662_DIGOUT_NID,
18054 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18055 .channel_mode = alc662_3ST_2ch_modes,
18056 .unsol_event = alc_sku_unsol_event,
18057 .setup = alc662_mode2_setup,
18058 .init_hook = alc_inithook,
18060 [ALC663_ASUS_MODE3] = {
18061 .mixers = { alc663_two_hp_m1_mixer },
18062 .cap_mixer = alc662_auto_capture_mixer,
18063 .init_verbs = { alc662_init_verbs,
18064 alc662_eapd_init_verbs,
18065 alc663_two_hp_amic_m1_init_verbs },
18066 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18068 .dac_nids = alc662_dac_nids,
18069 .dig_out_nid = ALC662_DIGOUT_NID,
18070 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18071 .channel_mode = alc662_3ST_2ch_modes,
18072 .unsol_event = alc_sku_unsol_event,
18073 .setup = alc663_mode3_setup,
18074 .init_hook = alc_inithook,
18076 [ALC663_ASUS_MODE4] = {
18077 .mixers = { alc663_asus_21jd_clfe_mixer },
18078 .cap_mixer = alc662_auto_capture_mixer,
18079 .init_verbs = { alc662_init_verbs,
18080 alc662_eapd_init_verbs,
18081 alc663_21jd_amic_init_verbs},
18082 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18084 .dac_nids = alc662_dac_nids,
18085 .dig_out_nid = ALC662_DIGOUT_NID,
18086 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18087 .channel_mode = alc662_3ST_2ch_modes,
18088 .unsol_event = alc_sku_unsol_event,
18089 .setup = alc663_mode4_setup,
18090 .init_hook = alc_inithook,
18092 [ALC663_ASUS_MODE5] = {
18093 .mixers = { alc663_asus_15jd_clfe_mixer },
18094 .cap_mixer = alc662_auto_capture_mixer,
18095 .init_verbs = { alc662_init_verbs,
18096 alc662_eapd_init_verbs,
18097 alc663_15jd_amic_init_verbs },
18098 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18100 .dac_nids = alc662_dac_nids,
18101 .dig_out_nid = ALC662_DIGOUT_NID,
18102 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18103 .channel_mode = alc662_3ST_2ch_modes,
18104 .unsol_event = alc_sku_unsol_event,
18105 .setup = alc663_mode5_setup,
18106 .init_hook = alc_inithook,
18108 [ALC663_ASUS_MODE6] = {
18109 .mixers = { alc663_two_hp_m2_mixer },
18110 .cap_mixer = alc662_auto_capture_mixer,
18111 .init_verbs = { alc662_init_verbs,
18112 alc662_eapd_init_verbs,
18113 alc663_two_hp_amic_m2_init_verbs },
18114 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18116 .dac_nids = alc662_dac_nids,
18117 .dig_out_nid = ALC662_DIGOUT_NID,
18118 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18119 .channel_mode = alc662_3ST_2ch_modes,
18120 .unsol_event = alc_sku_unsol_event,
18121 .setup = alc663_mode6_setup,
18122 .init_hook = alc_inithook,
18124 [ALC663_ASUS_MODE7] = {
18125 .mixers = { alc663_mode7_mixer },
18126 .cap_mixer = alc662_auto_capture_mixer,
18127 .init_verbs = { alc662_init_verbs,
18128 alc662_eapd_init_verbs,
18129 alc663_mode7_init_verbs },
18130 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18132 .dac_nids = alc662_dac_nids,
18133 .dig_out_nid = ALC662_DIGOUT_NID,
18134 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18135 .channel_mode = alc662_3ST_2ch_modes,
18136 .unsol_event = alc_sku_unsol_event,
18137 .setup = alc663_mode7_setup,
18138 .init_hook = alc_inithook,
18140 [ALC663_ASUS_MODE8] = {
18141 .mixers = { alc663_mode8_mixer },
18142 .cap_mixer = alc662_auto_capture_mixer,
18143 .init_verbs = { alc662_init_verbs,
18144 alc662_eapd_init_verbs,
18145 alc663_mode8_init_verbs },
18146 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18148 .dac_nids = alc662_dac_nids,
18149 .dig_out_nid = ALC662_DIGOUT_NID,
18150 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18151 .channel_mode = alc662_3ST_2ch_modes,
18152 .unsol_event = alc_sku_unsol_event,
18153 .setup = alc663_mode8_setup,
18154 .init_hook = alc_inithook,
18157 .mixers = { alc663_m51va_mixer },
18158 .cap_mixer = alc272_auto_capture_mixer,
18159 .init_verbs = { alc662_init_verbs,
18160 alc662_eapd_init_verbs,
18161 alc272_dell_init_verbs },
18162 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18163 .dac_nids = alc272_dac_nids,
18164 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18165 .adc_nids = alc272_adc_nids,
18166 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18167 .capsrc_nids = alc272_capsrc_nids,
18168 .channel_mode = alc662_3ST_2ch_modes,
18169 .unsol_event = alc_sku_unsol_event,
18170 .setup = alc663_m51va_setup,
18171 .init_hook = alc_inithook,
18173 [ALC272_DELL_ZM1] = {
18174 .mixers = { alc663_m51va_mixer },
18175 .cap_mixer = alc662_auto_capture_mixer,
18176 .init_verbs = { alc662_init_verbs,
18177 alc662_eapd_init_verbs,
18178 alc272_dell_zm1_init_verbs },
18179 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18180 .dac_nids = alc272_dac_nids,
18181 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18182 .adc_nids = alc662_adc_nids,
18184 .capsrc_nids = alc662_capsrc_nids,
18185 .channel_mode = alc662_3ST_2ch_modes,
18186 .unsol_event = alc_sku_unsol_event,
18187 .setup = alc663_m51va_setup,
18188 .init_hook = alc_inithook,
18190 [ALC272_SAMSUNG_NC10] = {
18191 .mixers = { alc272_nc10_mixer },
18192 .init_verbs = { alc662_init_verbs,
18193 alc662_eapd_init_verbs,
18194 alc663_21jd_amic_init_verbs },
18195 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18196 .dac_nids = alc272_dac_nids,
18197 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18198 .channel_mode = alc662_3ST_2ch_modes,
18199 /*.input_mux = &alc272_nc10_capture_source,*/
18200 .unsol_event = alc_sku_unsol_event,
18201 .setup = alc663_mode4_setup,
18202 .init_hook = alc_inithook,
18208 * BIOS auto configuration
18211 /* convert from MIX nid to DAC */
18212 static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18217 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18218 for (i = 0; i < num; i++) {
18219 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18225 /* go down to the selector widget before the mixer */
18226 static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18229 int num = snd_hda_get_connections(codec, pin, srcs,
18232 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18237 /* get MIX nid connected to the given pin targeted to DAC */
18238 static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18244 pin = alc_go_down_to_selector(codec, pin);
18245 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18246 for (i = 0; i < num; i++) {
18247 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18253 /* select the connection from pin to DAC if needed */
18254 static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18260 pin = alc_go_down_to_selector(codec, pin);
18261 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18264 for (i = 0; i < num; i++) {
18265 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18266 snd_hda_codec_update_cache(codec, pin, 0,
18267 AC_VERB_SET_CONNECT_SEL, i);
18274 /* look for an empty DAC slot */
18275 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18277 struct alc_spec *spec = codec->spec;
18281 pin = alc_go_down_to_selector(codec, pin);
18282 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18283 for (i = 0; i < num; i++) {
18284 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18287 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18288 spec->multiout.num_dacs))
18290 if (spec->multiout.hp_nid == nid)
18292 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18293 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18300 static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18302 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18303 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18304 return alc_auto_look_for_dac(codec, pin);
18308 /* fill in the dac_nids table from the parsed pin configuration */
18309 static int alc_auto_fill_dac_nids(struct hda_codec *codec)
18311 struct alc_spec *spec = codec->spec;
18312 const struct auto_pin_cfg *cfg = &spec->autocfg;
18313 bool redone = false;
18317 spec->multiout.num_dacs = 0;
18318 spec->multiout.hp_nid = 0;
18319 spec->multiout.extra_out_nid[0] = 0;
18320 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18321 spec->multiout.dac_nids = spec->private_dac_nids;
18323 /* fill hard-wired DACs first */
18325 for (i = 0; i < cfg->line_outs; i++)
18326 spec->private_dac_nids[i] =
18327 get_dac_if_single(codec, cfg->line_out_pins[i]);
18329 spec->multiout.hp_nid =
18330 get_dac_if_single(codec, cfg->hp_pins[0]);
18331 if (cfg->speaker_outs)
18332 spec->multiout.extra_out_nid[0] =
18333 get_dac_if_single(codec, cfg->speaker_pins[0]);
18336 for (i = 0; i < cfg->line_outs; i++) {
18337 hda_nid_t pin = cfg->line_out_pins[i];
18338 if (spec->private_dac_nids[i])
18340 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18341 if (!spec->private_dac_nids[i] && !redone) {
18342 /* if we can't find primary DACs, re-probe without
18343 * checking the hard-wired DACs
18350 for (i = 0; i < cfg->line_outs; i++) {
18351 if (spec->private_dac_nids[i])
18352 spec->multiout.num_dacs++;
18354 memmove(spec->private_dac_nids + i,
18355 spec->private_dac_nids + i + 1,
18356 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
18359 if (cfg->hp_outs && !spec->multiout.hp_nid)
18360 spec->multiout.hp_nid =
18361 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
18362 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
18363 spec->multiout.extra_out_nid[0] =
18364 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
18369 static int alc_auto_add_vol_ctl(struct hda_codec *codec,
18370 const char *pfx, int cidx,
18371 hda_nid_t nid, unsigned int chs)
18373 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
18374 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18377 #define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
18378 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
18380 /* create a mute-switch for the given mixer widget;
18381 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
18383 static int alc_auto_add_sw_ctl(struct hda_codec *codec,
18384 const char *pfx, int cidx,
18385 hda_nid_t nid, unsigned int chs)
18389 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
18390 type = ALC_CTL_WIDGET_MUTE;
18391 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
18393 type = ALC_CTL_BIND_MUTE;
18394 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
18396 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
18399 #define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
18400 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
18402 /* add playback controls from the parsed DAC table */
18403 static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
18404 const struct auto_pin_cfg *cfg)
18406 struct alc_spec *spec = codec->spec;
18407 hda_nid_t nid, mix, pin;
18408 int i, err, noutputs;
18410 noutputs = cfg->line_outs;
18411 if (spec->multi_ios > 0)
18412 noutputs += spec->multi_ios;
18414 for (i = 0; i < noutputs; i++) {
18417 nid = spec->multiout.dac_nids[i];
18420 if (i >= cfg->line_outs)
18421 pin = spec->multi_io[i - 1].pin;
18423 pin = cfg->line_out_pins[i];
18424 mix = alc_auto_dac_to_mix(codec, pin, nid);
18427 name = alc_get_line_out_pfx(spec, i, true, &index);
18430 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
18433 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
18436 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
18439 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
18443 err = alc_auto_add_stereo_vol(codec, name, index, nid);
18446 err = alc_auto_add_stereo_sw(codec, name, index, mix);
18454 /* add playback controls for speaker and HP outputs */
18455 static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18456 hda_nid_t dac, const char *pfx)
18458 struct alc_spec *spec = codec->spec;
18465 /* the corresponding DAC is already occupied */
18466 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18467 return 0; /* no way */
18468 /* create a switch only */
18469 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18470 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18473 mix = alc_auto_dac_to_mix(codec, pin, dac);
18476 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
18479 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
18485 static int alc_auto_create_hp_out(struct hda_codec *codec)
18487 struct alc_spec *spec = codec->spec;
18488 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18489 spec->multiout.hp_nid,
18493 static int alc_auto_create_speaker_out(struct hda_codec *codec)
18495 struct alc_spec *spec = codec->spec;
18496 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
18497 spec->multiout.extra_out_nid[0],
18501 static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
18502 hda_nid_t nid, int pin_type,
18507 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18509 alc_set_pin_output(codec, nid, pin_type);
18510 nid = alc_go_down_to_selector(codec, nid);
18511 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18512 for (i = 0; i < num; i++) {
18513 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18521 /* need the manual connection? */
18523 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18524 /* unmute mixer widget inputs */
18525 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18527 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18529 /* initialize volume */
18530 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18532 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18536 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18540 static void alc_auto_init_multi_out(struct hda_codec *codec)
18542 struct alc_spec *spec = codec->spec;
18543 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18546 for (i = 0; i <= HDA_SIDE; i++) {
18547 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18549 alc_auto_set_output_and_unmute(codec, nid, pin_type,
18550 spec->multiout.dac_nids[i]);
18554 static void alc_auto_init_extra_out(struct hda_codec *codec)
18556 struct alc_spec *spec = codec->spec;
18559 pin = spec->autocfg.hp_pins[0];
18561 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
18562 spec->multiout.hp_nid);
18563 pin = spec->autocfg.speaker_pins[0];
18565 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18566 spec->multiout.extra_out_nid[0]);
18572 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18573 unsigned int location)
18575 struct alc_spec *spec = codec->spec;
18576 struct auto_pin_cfg *cfg = &spec->autocfg;
18577 int type, i, num_pins = 0;
18579 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18580 for (i = 0; i < cfg->num_inputs; i++) {
18581 hda_nid_t nid = cfg->inputs[i].pin;
18583 unsigned int defcfg, caps;
18584 if (cfg->inputs[i].type != type)
18586 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18587 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18589 if (location && get_defcfg_location(defcfg) != location)
18591 caps = snd_hda_query_pin_caps(codec, nid);
18592 if (!(caps & AC_PINCAP_OUT))
18594 dac = alc_auto_look_for_dac(codec, nid);
18597 spec->multi_io[num_pins].pin = nid;
18598 spec->multi_io[num_pins].dac = dac;
18600 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18603 spec->multiout.num_dacs = 1;
18609 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18610 struct snd_ctl_elem_info *uinfo)
18612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18613 struct alc_spec *spec = codec->spec;
18615 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
18617 uinfo->value.enumerated.items = spec->multi_ios + 1;
18618 if (uinfo->value.enumerated.item > spec->multi_ios)
18619 uinfo->value.enumerated.item = spec->multi_ios;
18620 sprintf(uinfo->value.enumerated.name, "%dch",
18621 (uinfo->value.enumerated.item + 1) * 2);
18625 static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
18626 struct snd_ctl_elem_value *ucontrol)
18628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18629 struct alc_spec *spec = codec->spec;
18630 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
18634 static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
18636 struct alc_spec *spec = codec->spec;
18637 hda_nid_t nid = spec->multi_io[idx].pin;
18639 if (!spec->multi_io[idx].ctl_in)
18640 spec->multi_io[idx].ctl_in =
18641 snd_hda_codec_read(codec, nid, 0,
18642 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
18644 snd_hda_codec_update_cache(codec, nid, 0,
18645 AC_VERB_SET_PIN_WIDGET_CONTROL,
18647 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18648 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18650 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
18652 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18653 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18654 HDA_AMP_MUTE, HDA_AMP_MUTE);
18655 snd_hda_codec_update_cache(codec, nid, 0,
18656 AC_VERB_SET_PIN_WIDGET_CONTROL,
18657 spec->multi_io[idx].ctl_in);
18662 static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
18663 struct snd_ctl_elem_value *ucontrol)
18665 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18666 struct alc_spec *spec = codec->spec;
18669 ch = ucontrol->value.enumerated.item[0];
18670 if (ch < 0 || ch > spec->multi_ios)
18672 if (ch == (spec->ext_channel_count - 1) / 2)
18674 spec->ext_channel_count = (ch + 1) * 2;
18675 for (i = 0; i < spec->multi_ios; i++)
18676 alc_set_multi_io(codec, i, i < ch);
18677 spec->multiout.max_channels = spec->ext_channel_count;
18681 static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
18682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
18683 .name = "Channel Mode",
18684 .info = alc_auto_ch_mode_info,
18685 .get = alc_auto_ch_mode_get,
18686 .put = alc_auto_ch_mode_put,
18689 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
18690 int (*fill_dac)(struct hda_codec *))
18692 struct alc_spec *spec = codec->spec;
18693 struct auto_pin_cfg *cfg = &spec->autocfg;
18694 unsigned int location, defcfg;
18697 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
18698 /* use HP as primary out */
18699 cfg->speaker_outs = cfg->line_outs;
18700 memcpy(cfg->speaker_pins, cfg->line_out_pins,
18701 sizeof(cfg->speaker_pins));
18702 cfg->line_outs = cfg->hp_outs;
18703 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
18705 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
18706 cfg->line_out_type = AUTO_PIN_HP_OUT;
18710 if (cfg->line_outs != 1 ||
18711 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18714 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
18715 location = get_defcfg_location(defcfg);
18717 num_pins = alc_auto_fill_multi_ios(codec, location);
18718 if (num_pins > 0) {
18719 struct snd_kcontrol_new *knew;
18721 knew = alc_kcontrol_new(spec);
18724 *knew = alc_auto_channel_mode_enum;
18725 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
18729 spec->multi_ios = num_pins;
18730 spec->ext_channel_count = 2;
18731 spec->multiout.num_dacs = num_pins + 1;
18736 static int alc662_parse_auto_config(struct hda_codec *codec)
18738 struct alc_spec *spec = codec->spec;
18740 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18742 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18746 if (!spec->autocfg.line_outs)
18747 return 0; /* can't find valid BIOS pin config */
18749 err = alc_auto_fill_dac_nids(codec);
18752 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
18755 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
18758 err = alc_auto_create_extra_out(codec,
18759 spec->autocfg.speaker_pins[0],
18760 spec->multiout.extra_out_nid[0],
18764 err = alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18765 spec->multiout.hp_nid,
18769 err = alc_auto_create_input_ctls(codec);
18773 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18775 alc_auto_parse_digital(codec);
18777 if (spec->kctls.list)
18778 add_mixer(spec, spec->kctls.list);
18780 spec->num_mux_defs = 1;
18781 spec->input_mux = &spec->private_imux[0];
18783 if (!spec->dual_adc_switch)
18784 alc_remove_invalid_adc_nids(codec);
18786 err = alc_auto_add_mic_boost(codec);
18790 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18791 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18792 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18794 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18799 /* additional initialization for auto-configuration model */
18800 static void alc662_auto_init(struct hda_codec *codec)
18802 struct alc_spec *spec = codec->spec;
18803 alc_auto_init_multi_out(codec);
18804 alc_auto_init_extra_out(codec);
18805 alc_auto_init_analog_input(codec);
18806 alc_auto_init_input_src(codec);
18807 alc_auto_init_digital(codec);
18808 if (spec->unsol_event)
18809 alc_inithook(codec);
18812 static void alc272_fixup_mario(struct hda_codec *codec,
18813 const struct alc_fixup *fix, int action)
18815 if (action != ALC_FIXUP_ACT_PROBE)
18817 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
18818 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
18819 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
18820 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
18821 (0 << AC_AMPCAP_MUTE_SHIFT)))
18822 printk(KERN_WARNING
18823 "hda_codec: failed to override amp caps for NID 0x2\n");
18827 ALC662_FIXUP_ASPIRE,
18828 ALC662_FIXUP_IDEAPAD,
18829 ALC272_FIXUP_MARIO,
18830 ALC662_FIXUP_CZC_P10T,
18831 ALC662_FIXUP_SKU_IGNORE,
18834 static const struct alc_fixup alc662_fixups[] = {
18835 [ALC662_FIXUP_ASPIRE] = {
18836 .type = ALC_FIXUP_PINS,
18837 .v.pins = (const struct alc_pincfg[]) {
18838 { 0x15, 0x99130112 }, /* subwoofer */
18842 [ALC662_FIXUP_IDEAPAD] = {
18843 .type = ALC_FIXUP_PINS,
18844 .v.pins = (const struct alc_pincfg[]) {
18845 { 0x17, 0x99130112 }, /* subwoofer */
18849 [ALC272_FIXUP_MARIO] = {
18850 .type = ALC_FIXUP_FUNC,
18851 .v.func = alc272_fixup_mario,
18853 [ALC662_FIXUP_CZC_P10T] = {
18854 .type = ALC_FIXUP_VERBS,
18855 .v.verbs = (const struct hda_verb[]) {
18856 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
18860 [ALC662_FIXUP_SKU_IGNORE] = {
18861 .type = ALC_FIXUP_SKU,
18862 .v.sku = ALC_FIXUP_SKU_IGNORE,
18866 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
18867 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
18868 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
18869 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
18870 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
18871 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
18872 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
18873 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
18877 static const struct alc_model_fixup alc662_fixup_models[] = {
18878 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
18883 static int patch_alc662(struct hda_codec *codec)
18885 struct alc_spec *spec;
18886 int err, board_config;
18889 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18893 codec->spec = spec;
18895 spec->mixer_nid = 0x0b;
18897 alc_auto_parse_customize_define(codec);
18899 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18901 coef = alc_read_coef_idx(codec, 0);
18902 if (coef == 0x8020 || coef == 0x8011)
18903 alc_codec_rename(codec, "ALC661");
18904 else if (coef & (1 << 14) &&
18905 codec->bus->pci->subsystem_vendor == 0x1025 &&
18906 spec->cdefine.platform_type == 1)
18907 alc_codec_rename(codec, "ALC272X");
18908 else if (coef == 0x4011)
18909 alc_codec_rename(codec, "ALC656");
18911 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18914 if (board_config < 0) {
18915 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18917 board_config = ALC662_AUTO;
18920 if (board_config == ALC662_AUTO) {
18921 alc_pick_fixup(codec, alc662_fixup_models,
18922 alc662_fixup_tbl, alc662_fixups);
18923 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
18924 /* automatic parse from the BIOS config */
18925 err = alc662_parse_auto_config(codec);
18931 "hda_codec: Cannot set up configuration "
18932 "from BIOS. Using base mode...\n");
18933 board_config = ALC662_3ST_2ch_DIG;
18937 if (has_cdefine_beep(codec)) {
18938 err = snd_hda_attach_beep_device(codec, 0x1);
18945 if (board_config != ALC662_AUTO)
18946 setup_preset(codec, &alc662_presets[board_config]);
18948 if (!spec->adc_nids) {
18949 alc_auto_fill_adc_caps(codec);
18950 alc_remove_invalid_adc_nids(codec);
18953 if (!spec->cap_mixer)
18954 set_capture_mixer(codec);
18956 if (has_cdefine_beep(codec)) {
18957 switch (codec->vendor_id) {
18959 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18964 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18967 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18971 spec->vmaster_nid = 0x02;
18973 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18975 codec->patch_ops = alc_patch_ops;
18976 if (board_config == ALC662_AUTO)
18977 spec->init_hook = alc662_auto_init;
18978 spec->shutup = alc_eapd_shutup;
18980 alc_init_jacks(codec);
18982 #ifdef CONFIG_SND_HDA_POWER_SAVE
18983 if (!spec->loopback.amplist)
18984 spec->loopback.amplist = alc662_loopbacks;
18990 static int patch_alc888(struct hda_codec *codec)
18992 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18993 kfree(codec->chip_name);
18994 if (codec->vendor_id == 0x10ec0887)
18995 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
18997 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
18998 if (!codec->chip_name) {
19002 return patch_alc662(codec);
19004 return patch_alc882(codec);
19007 static int patch_alc899(struct hda_codec *codec)
19009 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19010 kfree(codec->chip_name);
19011 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19013 return patch_alc882(codec);
19019 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19020 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19021 #define alc680_modes alc260_modes
19023 static const hda_nid_t alc680_dac_nids[3] = {
19024 /* Lout1, Lout2, hp */
19028 static const hda_nid_t alc680_adc_nids[3] = {
19030 /* DMIC, MIC, Line-in*/
19035 * Analog capture ADC cgange
19037 static void alc680_rec_autoswitch(struct hda_codec *codec)
19039 struct alc_spec *spec = codec->spec;
19040 struct auto_pin_cfg *cfg = &spec->autocfg;
19042 int type_found = AUTO_PIN_LAST;
19046 for (i = 0; i < cfg->num_inputs; i++) {
19047 nid = cfg->inputs[i].pin;
19048 if (!is_jack_detectable(codec, nid))
19050 if (snd_hda_jack_detect(codec, nid)) {
19051 if (cfg->inputs[i].type < type_found) {
19052 type_found = cfg->inputs[i].type;
19060 snd_hda_get_connections(codec, pin_found, &nid, 1);
19062 if (nid != spec->cur_adc)
19063 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19064 spec->cur_adc = nid;
19065 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19066 spec->cur_adc_format);
19069 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19070 struct hda_codec *codec,
19071 unsigned int stream_tag,
19072 unsigned int format,
19073 struct snd_pcm_substream *substream)
19075 struct alc_spec *spec = codec->spec;
19077 spec->cur_adc = 0x07;
19078 spec->cur_adc_stream_tag = stream_tag;
19079 spec->cur_adc_format = format;
19081 alc680_rec_autoswitch(codec);
19085 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19086 struct hda_codec *codec,
19087 struct snd_pcm_substream *substream)
19089 snd_hda_codec_cleanup_stream(codec, 0x07);
19090 snd_hda_codec_cleanup_stream(codec, 0x08);
19091 snd_hda_codec_cleanup_stream(codec, 0x09);
19095 static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19096 .substreams = 1, /* can be overridden */
19099 /* NID is set in alc_build_pcms */
19101 .prepare = alc680_capture_pcm_prepare,
19102 .cleanup = alc680_capture_pcm_cleanup
19106 static const struct snd_kcontrol_new alc680_base_mixer[] = {
19107 /* output mixer control */
19108 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19109 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19110 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19112 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19113 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19114 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19118 static const struct hda_bind_ctls alc680_bind_cap_vol = {
19119 .ops = &snd_hda_bind_vol,
19121 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19122 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19123 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19128 static const struct hda_bind_ctls alc680_bind_cap_switch = {
19129 .ops = &snd_hda_bind_sw,
19131 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19132 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19133 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19138 static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19139 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19140 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19145 * generic initialization of ADC, input mixers and output mixers
19147 static const struct hda_verb alc680_init_verbs[] = {
19148 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19149 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19152 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19154 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19155 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19156 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19157 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19159 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19160 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19161 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19162 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19163 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19165 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19166 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19167 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19172 /* toggle speaker-output according to the hp-jack state */
19173 static void alc680_base_setup(struct hda_codec *codec)
19175 struct alc_spec *spec = codec->spec;
19177 spec->autocfg.hp_pins[0] = 0x16;
19178 spec->autocfg.speaker_pins[0] = 0x14;
19179 spec->autocfg.speaker_pins[1] = 0x15;
19180 spec->autocfg.num_inputs = 2;
19181 spec->autocfg.inputs[0].pin = 0x18;
19182 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19183 spec->autocfg.inputs[1].pin = 0x19;
19184 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19185 spec->automute = 1;
19186 spec->automute_mode = ALC_AUTOMUTE_AMP;
19189 static void alc680_unsol_event(struct hda_codec *codec,
19192 if ((res >> 26) == ALC880_HP_EVENT)
19193 alc_hp_automute(codec);
19194 if ((res >> 26) == ALC880_MIC_EVENT)
19195 alc680_rec_autoswitch(codec);
19198 static void alc680_inithook(struct hda_codec *codec)
19200 alc_hp_automute(codec);
19201 alc680_rec_autoswitch(codec);
19204 /* create input playback/capture controls for the given pin */
19205 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19206 const char *ctlname, int idx)
19224 if (spec->multiout.dac_nids[0] != dac &&
19225 spec->multiout.dac_nids[1] != dac) {
19226 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19227 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19232 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19233 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19237 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19243 /* add playback controls from the parsed DAC table */
19244 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19245 const struct auto_pin_cfg *cfg)
19250 spec->multiout.dac_nids = spec->private_dac_nids;
19252 nid = cfg->line_out_pins[0];
19256 name = alc_get_line_out_pfx(spec, 0, true, &index);
19257 err = alc680_new_analog_output(spec, nid, name, 0);
19262 nid = cfg->speaker_pins[0];
19264 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19268 nid = cfg->hp_pins[0];
19270 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19278 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19279 hda_nid_t nid, int pin_type)
19281 alc_set_pin_output(codec, nid, pin_type);
19284 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19286 struct alc_spec *spec = codec->spec;
19287 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19289 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19290 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19294 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19296 struct alc_spec *spec = codec->spec;
19299 pin = spec->autocfg.hp_pins[0];
19301 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19302 pin = spec->autocfg.speaker_pins[0];
19304 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19308 * BIOS auto configuration
19310 static int alc680_parse_auto_config(struct hda_codec *codec)
19312 struct alc_spec *spec = codec->spec;
19314 static const hda_nid_t alc680_ignore[] = { 0 };
19316 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19321 if (!spec->autocfg.line_outs) {
19322 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19323 spec->multiout.max_channels = 2;
19324 spec->no_analog = 1;
19327 return 0; /* can't find valid BIOS pin config */
19329 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19333 spec->multiout.max_channels = 2;
19336 /* digital only support output */
19337 alc_auto_parse_digital(codec);
19338 if (spec->kctls.list)
19339 add_mixer(spec, spec->kctls.list);
19341 err = alc_auto_add_mic_boost(codec);
19348 /* init callback for auto-configuration model -- overriding the default init */
19349 static void alc680_auto_init(struct hda_codec *codec)
19351 struct alc_spec *spec = codec->spec;
19352 alc680_auto_init_multi_out(codec);
19353 alc680_auto_init_hp_out(codec);
19354 alc_auto_init_analog_input(codec);
19355 alc_auto_init_digital(codec);
19356 if (spec->unsol_event)
19357 alc_inithook(codec);
19361 * configuration and preset
19363 static const char * const alc680_models[ALC680_MODEL_LAST] = {
19364 [ALC680_BASE] = "base",
19365 [ALC680_AUTO] = "auto",
19368 static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19369 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19373 static const struct alc_config_preset alc680_presets[] = {
19375 .mixers = { alc680_base_mixer },
19376 .cap_mixer = alc680_master_capture_mixer,
19377 .init_verbs = { alc680_init_verbs },
19378 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19379 .dac_nids = alc680_dac_nids,
19380 .dig_out_nid = ALC680_DIGOUT_NID,
19381 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19382 .channel_mode = alc680_modes,
19383 .unsol_event = alc680_unsol_event,
19384 .setup = alc680_base_setup,
19385 .init_hook = alc680_inithook,
19390 static int patch_alc680(struct hda_codec *codec)
19392 struct alc_spec *spec;
19396 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19400 codec->spec = spec;
19402 /* ALC680 has no aa-loopback mixer */
19404 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19408 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19409 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19411 board_config = ALC680_AUTO;
19414 if (board_config == ALC680_AUTO) {
19415 /* automatic parse from the BIOS config */
19416 err = alc680_parse_auto_config(codec);
19422 "hda_codec: Cannot set up configuration "
19423 "from BIOS. Using base mode...\n");
19424 board_config = ALC680_BASE;
19428 if (board_config != ALC680_AUTO)
19429 setup_preset(codec, &alc680_presets[board_config]);
19431 if (!spec->adc_nids) {
19432 alc_auto_fill_adc_caps(codec);
19433 alc_remove_invalid_adc_nids(codec);
19436 if (!spec->cap_mixer)
19437 set_capture_mixer(codec);
19439 spec->vmaster_nid = 0x02;
19441 codec->patch_ops = alc_patch_ops;
19442 if (board_config == ALC680_AUTO)
19443 spec->init_hook = alc680_auto_init;
19451 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
19452 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
19453 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19454 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19455 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
19456 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
19457 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
19458 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19459 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19460 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
19461 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
19462 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19463 .patch = patch_alc861 },
19464 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19465 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19466 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
19467 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
19468 .patch = patch_alc882 },
19469 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19470 .patch = patch_alc662 },
19471 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
19472 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19473 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19474 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
19475 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
19476 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
19477 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
19478 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
19479 .patch = patch_alc882 },
19480 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19481 .patch = patch_alc882 },
19482 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19483 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
19484 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19485 .patch = patch_alc882 },
19486 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19487 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19488 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
19489 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
19490 {} /* terminator */
19493 MODULE_ALIAS("snd-hda-codec-id:10ec*");
19495 MODULE_LICENSE("GPL");
19496 MODULE_DESCRIPTION("Realtek HD-audio codec");
19498 static struct hda_codec_preset_list realtek_list = {
19499 .preset = snd_hda_preset_realtek,
19500 .owner = THIS_MODULE,
19503 static int __init patch_realtek_init(void)
19505 return snd_hda_add_codec_preset(&realtek_list);
19508 static void __exit patch_realtek_exit(void)
19510 snd_hda_delete_codec_preset(&realtek_list);
19513 module_init(patch_realtek_init)
19514 module_exit(patch_realtek_exit)