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;
409 /* auto-mute control */
411 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
414 int codec_variant; /* flag for other variants */
416 /* for virtual master */
417 hda_nid_t vmaster_nid;
418 #ifdef CONFIG_SND_HDA_POWER_SAVE
419 struct hda_loopback_check loopback;
424 unsigned int pll_coef_idx, pll_coef_bit;
428 const struct alc_fixup *fixup_list;
429 const char *fixup_name;
433 struct alc_multi_io multi_io[4];
437 * configuration template - to be copied to the spec instance
439 struct alc_config_preset {
440 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
443 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
444 const struct hda_verb *init_verbs[5];
445 unsigned int num_dacs;
446 const hda_nid_t *dac_nids;
447 hda_nid_t dig_out_nid; /* optional */
448 hda_nid_t hp_nid; /* optional */
449 const hda_nid_t *slave_dig_outs;
450 unsigned int num_adc_nids;
451 const hda_nid_t *adc_nids;
452 const hda_nid_t *capsrc_nids;
453 hda_nid_t dig_in_nid;
454 unsigned int num_channel_mode;
455 const struct hda_channel_mode *channel_mode;
457 int const_channel_count;
458 unsigned int num_mux_defs;
459 const struct hda_input_mux *input_mux;
460 void (*unsol_event)(struct hda_codec *, unsigned int);
461 void (*setup)(struct hda_codec *);
462 void (*init_hook)(struct hda_codec *);
463 #ifdef CONFIG_SND_HDA_POWER_SAVE
464 const struct hda_amp_list *loopbacks;
465 void (*power_hook)(struct hda_codec *codec);
473 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_info *uinfo)
476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
477 struct alc_spec *spec = codec->spec;
478 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
479 if (mux_idx >= spec->num_mux_defs)
481 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
483 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
486 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_value *ucontrol)
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 struct alc_spec *spec = codec->spec;
491 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
493 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
497 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct alc_spec *spec = codec->spec;
502 const struct hda_input_mux *imux;
503 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
504 unsigned int mux_idx;
505 hda_nid_t nid = spec->capsrc_nids ?
506 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
509 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
510 imux = &spec->input_mux[mux_idx];
511 if (!imux->num_items && mux_idx > 0)
512 imux = &spec->input_mux[0];
514 type = get_wcaps_type(get_wcaps(codec, nid));
515 if (type == AC_WID_AUD_MIX) {
516 /* Matrix-mixer style (e.g. ALC882) */
517 unsigned int *cur_val = &spec->cur_mux[adc_idx];
520 idx = ucontrol->value.enumerated.item[0];
521 if (idx >= imux->num_items)
522 idx = imux->num_items - 1;
525 for (i = 0; i < imux->num_items; i++) {
526 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
527 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
528 imux->items[i].index,
534 /* MUX style (e.g. ALC880) */
535 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
536 &spec->cur_mux[adc_idx]);
541 * channel mode setting
543 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct alc_spec *spec = codec->spec;
548 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
549 spec->num_channel_mode);
552 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
556 struct alc_spec *spec = codec->spec;
557 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
558 spec->num_channel_mode,
559 spec->ext_channel_count);
562 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 struct alc_spec *spec = codec->spec;
567 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
568 spec->num_channel_mode,
569 &spec->ext_channel_count);
570 if (err >= 0 && !spec->const_channel_count) {
571 spec->multiout.max_channels = spec->ext_channel_count;
572 if (spec->need_dac_fix)
573 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
579 * Control the mode of pin widget settings via the mixer. "pc" is used
580 * instead of "%" to avoid consequences of accidentally treating the % as
581 * being part of a format specifier. Maximum allowed length of a value is
582 * 63 characters plus NULL terminator.
584 * Note: some retasking pin complexes seem to ignore requests for input
585 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
586 * are requested. Therefore order this list so that this behaviour will not
587 * cause problems when mixer clients move through the enum sequentially.
588 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
591 static const char * const alc_pin_mode_names[] = {
592 "Mic 50pc bias", "Mic 80pc bias",
593 "Line in", "Line out", "Headphone out",
595 static const unsigned char alc_pin_mode_values[] = {
596 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
598 /* The control can present all 5 options, or it can limit the options based
599 * in the pin being assumed to be exclusively an input or an output pin. In
600 * addition, "input" pins may or may not process the mic bias option
601 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
602 * accept requests for bias as of chip versions up to March 2006) and/or
603 * wiring in the computer.
605 #define ALC_PIN_DIR_IN 0x00
606 #define ALC_PIN_DIR_OUT 0x01
607 #define ALC_PIN_DIR_INOUT 0x02
608 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
609 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
611 /* Info about the pin modes supported by the different pin direction modes.
612 * For each direction the minimum and maximum values are given.
614 static const signed char alc_pin_mode_dir_info[5][2] = {
615 { 0, 2 }, /* ALC_PIN_DIR_IN */
616 { 3, 4 }, /* ALC_PIN_DIR_OUT */
617 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
618 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
619 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
621 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
622 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
623 #define alc_pin_mode_n_items(_dir) \
624 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
626 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_info *uinfo)
629 unsigned int item_num = uinfo->value.enumerated.item;
630 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
634 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
636 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
637 item_num = alc_pin_mode_min(dir);
638 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
642 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
649 long *valp = ucontrol->value.integer.value;
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
654 /* Find enumerated value for current pinctl setting */
655 i = alc_pin_mode_min(dir);
656 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
658 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
662 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_value *ucontrol)
666 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
667 hda_nid_t nid = kcontrol->private_value & 0xffff;
668 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
669 long val = *ucontrol->value.integer.value;
670 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
671 AC_VERB_GET_PIN_WIDGET_CONTROL,
674 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
675 val = alc_pin_mode_min(dir);
677 change = pinctl != alc_pin_mode_values[val];
679 /* Set pin mode to that requested */
680 snd_hda_codec_write_cache(codec, nid, 0,
681 AC_VERB_SET_PIN_WIDGET_CONTROL,
682 alc_pin_mode_values[val]);
684 /* Also enable the retasking pin's input/output as required
685 * for the requested pin mode. Enum values of 2 or less are
688 * Dynamically switching the input/output buffers probably
689 * reduces noise slightly (particularly on input) so we'll
690 * do it. However, having both input and output buffers
691 * enabled simultaneously doesn't seem to be problematic if
692 * this turns out to be necessary in the future.
695 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
696 HDA_AMP_MUTE, HDA_AMP_MUTE);
697 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
701 HDA_AMP_MUTE, HDA_AMP_MUTE);
702 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
709 #define ALC_PIN_MODE(xname, nid, dir) \
710 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
711 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
712 .info = alc_pin_mode_info, \
713 .get = alc_pin_mode_get, \
714 .put = alc_pin_mode_put, \
715 .private_value = nid | (dir<<16) }
717 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
718 * together using a mask with more than one bit set. This control is
719 * currently used only by the ALC260 test model. At this stage they are not
720 * needed for any "production" models.
722 #ifdef CONFIG_SND_DEBUG
723 #define alc_gpio_data_info snd_ctl_boolean_mono_info
725 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
726 struct snd_ctl_elem_value *ucontrol)
728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
729 hda_nid_t nid = kcontrol->private_value & 0xffff;
730 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
731 long *valp = ucontrol->value.integer.value;
732 unsigned int val = snd_hda_codec_read(codec, nid, 0,
733 AC_VERB_GET_GPIO_DATA, 0x00);
735 *valp = (val & mask) != 0;
738 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
739 struct snd_ctl_elem_value *ucontrol)
742 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
743 hda_nid_t nid = kcontrol->private_value & 0xffff;
744 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
745 long val = *ucontrol->value.integer.value;
746 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
747 AC_VERB_GET_GPIO_DATA,
750 /* Set/unset the masked GPIO bit(s) as needed */
751 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
756 snd_hda_codec_write_cache(codec, nid, 0,
757 AC_VERB_SET_GPIO_DATA, gpio_data);
761 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
762 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
763 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
764 .info = alc_gpio_data_info, \
765 .get = alc_gpio_data_get, \
766 .put = alc_gpio_data_put, \
767 .private_value = nid | (mask<<16) }
768 #endif /* CONFIG_SND_DEBUG */
770 /* A switch control to allow the enabling of the digital IO pins on the
771 * ALC260. This is incredibly simplistic; the intention of this control is
772 * to provide something in the test model allowing digital outputs to be
773 * identified if present. If models are found which can utilise these
774 * outputs a more complete mixer control can be devised for those models if
777 #ifdef CONFIG_SND_DEBUG
778 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
780 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
783 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
784 hda_nid_t nid = kcontrol->private_value & 0xffff;
785 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
786 long *valp = ucontrol->value.integer.value;
787 unsigned int val = snd_hda_codec_read(codec, nid, 0,
788 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
790 *valp = (val & mask) != 0;
793 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
798 hda_nid_t nid = kcontrol->private_value & 0xffff;
799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
800 long val = *ucontrol->value.integer.value;
801 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
802 AC_VERB_GET_DIGI_CONVERT_1,
805 /* Set/unset the masked control bit(s) as needed */
806 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
811 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
816 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
817 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
818 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
819 .info = alc_spdif_ctrl_info, \
820 .get = alc_spdif_ctrl_get, \
821 .put = alc_spdif_ctrl_put, \
822 .private_value = nid | (mask<<16) }
823 #endif /* CONFIG_SND_DEBUG */
825 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
826 * Again, this is only used in the ALC26x test models to help identify when
827 * the EAPD line must be asserted for features to work.
829 #ifdef CONFIG_SND_DEBUG
830 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
832 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
833 struct snd_ctl_elem_value *ucontrol)
835 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
836 hda_nid_t nid = kcontrol->private_value & 0xffff;
837 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
838 long *valp = ucontrol->value.integer.value;
839 unsigned int val = snd_hda_codec_read(codec, nid, 0,
840 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
842 *valp = (val & mask) != 0;
846 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
847 struct snd_ctl_elem_value *ucontrol)
850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
851 hda_nid_t nid = kcontrol->private_value & 0xffff;
852 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
853 long val = *ucontrol->value.integer.value;
854 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
855 AC_VERB_GET_EAPD_BTLENABLE,
858 /* Set/unset the masked control bit(s) as needed */
859 change = (!val ? 0 : mask) != (ctrl_data & mask);
864 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
870 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
871 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
872 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
873 .info = alc_eapd_ctrl_info, \
874 .get = alc_eapd_ctrl_get, \
875 .put = alc_eapd_ctrl_put, \
876 .private_value = nid | (mask<<16) }
877 #endif /* CONFIG_SND_DEBUG */
880 * set up the input pin config (depending on the given auto-pin type)
882 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
885 unsigned int val = PIN_IN;
887 if (auto_pin_type == AUTO_PIN_MIC) {
890 oldval = snd_hda_codec_read(codec, nid, 0,
891 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
892 pincap = snd_hda_query_pin_caps(codec, nid);
893 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
894 /* if the default pin setup is vref50, we give it priority */
895 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
897 else if (pincap & AC_PINCAP_VREF_50)
899 else if (pincap & AC_PINCAP_VREF_100)
901 else if (pincap & AC_PINCAP_VREF_GRD)
904 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
907 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
909 struct alc_spec *spec = codec->spec;
910 struct auto_pin_cfg *cfg = &spec->autocfg;
912 if (!cfg->line_outs) {
913 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
914 cfg->line_out_pins[cfg->line_outs])
917 if (!cfg->speaker_outs) {
918 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
919 cfg->speaker_pins[cfg->speaker_outs])
923 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
924 cfg->hp_pins[cfg->hp_outs])
931 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
933 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
935 spec->mixers[spec->num_mixers++] = mix;
938 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
940 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
942 spec->init_verbs[spec->num_init_verbs++] = verb;
946 * set up from the preset table
948 static void setup_preset(struct hda_codec *codec,
949 const struct alc_config_preset *preset)
951 struct alc_spec *spec = codec->spec;
954 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
955 add_mixer(spec, preset->mixers[i]);
956 spec->cap_mixer = preset->cap_mixer;
957 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
959 add_verb(spec, preset->init_verbs[i]);
961 spec->channel_mode = preset->channel_mode;
962 spec->num_channel_mode = preset->num_channel_mode;
963 spec->need_dac_fix = preset->need_dac_fix;
964 spec->const_channel_count = preset->const_channel_count;
966 if (preset->const_channel_count)
967 spec->multiout.max_channels = preset->const_channel_count;
969 spec->multiout.max_channels = spec->channel_mode[0].channels;
970 spec->ext_channel_count = spec->channel_mode[0].channels;
972 spec->multiout.num_dacs = preset->num_dacs;
973 spec->multiout.dac_nids = preset->dac_nids;
974 spec->multiout.dig_out_nid = preset->dig_out_nid;
975 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
976 spec->multiout.hp_nid = preset->hp_nid;
978 spec->num_mux_defs = preset->num_mux_defs;
979 if (!spec->num_mux_defs)
980 spec->num_mux_defs = 1;
981 spec->input_mux = preset->input_mux;
983 spec->num_adc_nids = preset->num_adc_nids;
984 spec->adc_nids = preset->adc_nids;
985 spec->capsrc_nids = preset->capsrc_nids;
986 spec->dig_in_nid = preset->dig_in_nid;
988 spec->unsol_event = preset->unsol_event;
989 spec->init_hook = preset->init_hook;
990 #ifdef CONFIG_SND_HDA_POWER_SAVE
991 spec->power_hook = preset->power_hook;
992 spec->loopback.amplist = preset->loopbacks;
996 preset->setup(codec);
998 alc_fixup_autocfg_pin_nums(codec);
1001 /* Enable GPIO mask and set output */
1002 static const struct hda_verb alc_gpio1_init_verbs[] = {
1003 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1009 static const struct hda_verb alc_gpio2_init_verbs[] = {
1010 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1016 static const struct hda_verb alc_gpio3_init_verbs[] = {
1017 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1024 * Fix hardware PLL issue
1025 * On some codecs, the analog PLL gating control must be off while
1026 * the default value is 1.
1028 static void alc_fix_pll(struct hda_codec *codec)
1030 struct alc_spec *spec = codec->spec;
1035 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1036 spec->pll_coef_idx);
1037 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1038 AC_VERB_GET_PROC_COEF, 0);
1039 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1040 spec->pll_coef_idx);
1041 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1042 val & ~(1 << spec->pll_coef_bit));
1045 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1046 unsigned int coef_idx, unsigned int coef_bit)
1048 struct alc_spec *spec = codec->spec;
1049 spec->pll_nid = nid;
1050 spec->pll_coef_idx = coef_idx;
1051 spec->pll_coef_bit = coef_bit;
1055 static int alc_init_jacks(struct hda_codec *codec)
1057 #ifdef CONFIG_SND_HDA_INPUT_JACK
1058 struct alc_spec *spec = codec->spec;
1060 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1061 unsigned int mic_nid = spec->ext_mic.pin;
1062 unsigned int dock_nid = spec->dock_mic.pin;
1065 err = snd_hda_input_jack_add(codec, hp_nid,
1066 SND_JACK_HEADPHONE, NULL);
1069 snd_hda_input_jack_report(codec, hp_nid);
1073 err = snd_hda_input_jack_add(codec, mic_nid,
1074 SND_JACK_MICROPHONE, NULL);
1077 snd_hda_input_jack_report(codec, mic_nid);
1080 err = snd_hda_input_jack_add(codec, dock_nid,
1081 SND_JACK_MICROPHONE, NULL);
1084 snd_hda_input_jack_report(codec, dock_nid);
1086 #endif /* CONFIG_SND_HDA_INPUT_JACK */
1090 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1094 for (i = 0; i < num_pins; i++) {
1095 hda_nid_t nid = pins[i];
1098 snd_hda_input_jack_report(codec, nid);
1099 present |= snd_hda_jack_detect(codec, nid);
1104 static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1105 bool mute, bool hp_out)
1107 struct alc_spec *spec = codec->spec;
1108 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1109 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1112 for (i = 0; i < num_pins; i++) {
1113 hda_nid_t nid = pins[i];
1116 switch (spec->automute_mode) {
1117 case ALC_AUTOMUTE_PIN:
1118 snd_hda_codec_write(codec, nid, 0,
1119 AC_VERB_SET_PIN_WIDGET_CONTROL,
1122 case ALC_AUTOMUTE_AMP:
1123 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1124 HDA_AMP_MUTE, mute_bits);
1126 case ALC_AUTOMUTE_MIXER:
1127 nid = spec->automute_mixer_nid[i];
1130 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1131 HDA_AMP_MUTE, mute_bits);
1132 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1133 HDA_AMP_MUTE, mute_bits);
1139 /* Toggle internal speakers muting */
1140 static void update_speakers(struct hda_codec *codec)
1142 struct alc_spec *spec = codec->spec;
1145 /* Control HP pins/amps depending on master_mute state;
1146 * in general, HP pins/amps control should be enabled in all cases,
1147 * but currently set only for master_mute, just to be safe
1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1150 spec->autocfg.hp_pins, spec->master_mute, true);
1152 if (!spec->automute)
1155 on = spec->jack_present | spec->line_jack_present;
1156 on |= spec->master_mute;
1157 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1158 spec->autocfg.speaker_pins, on, false);
1160 /* toggle line-out mutes if needed, too */
1161 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1162 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1163 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1165 if (!spec->automute_lines || !spec->automute)
1168 on = spec->jack_present;
1169 on |= spec->master_mute;
1170 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1171 spec->autocfg.line_out_pins, on, false);
1174 static void alc_hp_automute(struct hda_codec *codec)
1176 struct alc_spec *spec = codec->spec;
1178 if (!spec->automute)
1180 spec->jack_present =
1181 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1182 spec->autocfg.hp_pins);
1183 update_speakers(codec);
1186 static void alc_line_automute(struct hda_codec *codec)
1188 struct alc_spec *spec = codec->spec;
1190 if (!spec->automute || !spec->detect_line)
1192 spec->line_jack_present =
1193 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1194 spec->autocfg.line_out_pins);
1195 update_speakers(codec);
1198 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1201 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1204 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1205 for (i = 0; i < nums; i++)
1211 /* switch the current ADC according to the jack state */
1212 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1214 struct alc_spec *spec = codec->spec;
1215 unsigned int present;
1218 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1220 spec->cur_adc_idx = 1;
1222 spec->cur_adc_idx = 0;
1223 new_adc = spec->adc_nids[spec->cur_adc_idx];
1224 if (spec->cur_adc && spec->cur_adc != new_adc) {
1225 /* stream is running, let's swap the current ADC */
1226 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1227 spec->cur_adc = new_adc;
1228 snd_hda_codec_setup_stream(codec, new_adc,
1229 spec->cur_adc_stream_tag, 0,
1230 spec->cur_adc_format);
1234 static void alc_mic_automute(struct hda_codec *codec)
1236 struct alc_spec *spec = codec->spec;
1237 struct alc_mic_route *dead1, *dead2, *alive;
1238 unsigned int present, type;
1241 if (!spec->auto_mic)
1243 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1245 if (snd_BUG_ON(!spec->adc_nids))
1248 if (spec->dual_adc_switch) {
1249 alc_dual_mic_adc_auto_switch(codec);
1253 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1255 alive = &spec->int_mic;
1256 dead1 = &spec->ext_mic;
1257 dead2 = &spec->dock_mic;
1259 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1261 alive = &spec->ext_mic;
1262 dead1 = &spec->int_mic;
1263 dead2 = &spec->dock_mic;
1265 if (!present && spec->dock_mic.pin > 0) {
1266 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1268 alive = &spec->dock_mic;
1269 dead1 = &spec->int_mic;
1270 dead2 = &spec->ext_mic;
1272 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1275 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1276 if (type == AC_WID_AUD_MIX) {
1277 /* Matrix-mixer style (e.g. ALC882) */
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1284 HDA_AMP_MUTE, HDA_AMP_MUTE);
1286 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1288 HDA_AMP_MUTE, HDA_AMP_MUTE);
1290 /* MUX style (e.g. ALC880) */
1291 snd_hda_codec_write_cache(codec, cap_nid, 0,
1292 AC_VERB_SET_CONNECT_SEL,
1295 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1297 /* FIXME: analog mixer */
1300 /* unsolicited event for HP jack sensing */
1301 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1303 if (codec->vendor_id == 0x10ec0880)
1308 case ALC880_HP_EVENT:
1309 alc_hp_automute(codec);
1311 case ALC880_FRONT_EVENT:
1312 alc_line_automute(codec);
1314 case ALC880_MIC_EVENT:
1315 alc_mic_automute(codec);
1320 static void alc_inithook(struct hda_codec *codec)
1322 alc_hp_automute(codec);
1323 alc_line_automute(codec);
1324 alc_mic_automute(codec);
1327 /* additional initialization for ALC888 variants */
1328 static void alc888_coef_init(struct hda_codec *codec)
1332 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1333 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1334 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1335 if ((tmp & 0xf0) == 0x20)
1337 snd_hda_codec_read(codec, 0x20, 0,
1338 AC_VERB_SET_PROC_COEF, 0x830);
1341 snd_hda_codec_read(codec, 0x20, 0,
1342 AC_VERB_SET_PROC_COEF, 0x3030);
1345 static void alc889_coef_init(struct hda_codec *codec)
1349 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1350 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1351 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1352 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1355 /* turn on/off EAPD control (only if available) */
1356 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1358 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1360 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1361 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1365 /* turn on/off EAPD controls of the codec */
1366 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1368 /* We currently only handle front, HP */
1369 switch (codec->vendor_id) {
1371 set_eapd(codec, 0x0f, on);
1372 set_eapd(codec, 0x10, on);
1387 set_eapd(codec, 0x14, on);
1388 set_eapd(codec, 0x15, on);
1393 /* generic shutup callback;
1394 * just turning off EPAD and a little pause for avoiding pop-noise
1396 static void alc_eapd_shutup(struct hda_codec *codec)
1398 alc_auto_setup_eapd(codec, false);
1402 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1407 case ALC_INIT_GPIO1:
1408 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1410 case ALC_INIT_GPIO2:
1411 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1413 case ALC_INIT_GPIO3:
1414 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1416 case ALC_INIT_DEFAULT:
1417 alc_auto_setup_eapd(codec, true);
1418 switch (codec->vendor_id) {
1420 snd_hda_codec_write(codec, 0x1a, 0,
1421 AC_VERB_SET_COEF_INDEX, 7);
1422 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1423 AC_VERB_GET_PROC_COEF, 0);
1424 snd_hda_codec_write(codec, 0x1a, 0,
1425 AC_VERB_SET_COEF_INDEX, 7);
1426 snd_hda_codec_write(codec, 0x1a, 0,
1427 AC_VERB_SET_PROC_COEF,
1436 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1437 alc889_coef_init(codec);
1440 alc888_coef_init(codec);
1442 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1445 snd_hda_codec_write(codec, 0x20, 0,
1446 AC_VERB_SET_COEF_INDEX, 7);
1447 tmp = snd_hda_codec_read(codec, 0x20, 0,
1448 AC_VERB_GET_PROC_COEF, 0);
1449 snd_hda_codec_write(codec, 0x20, 0,
1450 AC_VERB_SET_COEF_INDEX, 7);
1451 snd_hda_codec_write(codec, 0x20, 0,
1452 AC_VERB_SET_PROC_COEF,
1461 static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1462 struct snd_ctl_elem_info *uinfo)
1464 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1465 struct alc_spec *spec = codec->spec;
1466 static const char * const texts2[] = {
1467 "Disabled", "Enabled"
1469 static const char * const texts3[] = {
1470 "Disabled", "Speaker Only", "Line-Out+Speaker"
1472 const char * const *texts;
1474 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1476 if (spec->automute_hp_lo) {
1477 uinfo->value.enumerated.items = 3;
1480 uinfo->value.enumerated.items = 2;
1483 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1484 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1485 strcpy(uinfo->value.enumerated.name,
1486 texts[uinfo->value.enumerated.item]);
1490 static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1491 struct snd_ctl_elem_value *ucontrol)
1493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1494 struct alc_spec *spec = codec->spec;
1496 if (!spec->automute)
1498 else if (!spec->automute_lines)
1502 ucontrol->value.enumerated.item[0] = val;
1506 static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1507 struct snd_ctl_elem_value *ucontrol)
1509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1510 struct alc_spec *spec = codec->spec;
1512 switch (ucontrol->value.enumerated.item[0]) {
1514 if (!spec->automute)
1519 if (spec->automute && !spec->automute_lines)
1522 spec->automute_lines = 0;
1525 if (!spec->automute_hp_lo)
1527 if (spec->automute && spec->automute_lines)
1530 spec->automute_lines = 1;
1535 update_speakers(codec);
1539 static const struct snd_kcontrol_new alc_automute_mode_enum = {
1540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1541 .name = "Auto-Mute Mode",
1542 .info = alc_automute_mode_info,
1543 .get = alc_automute_mode_get,
1544 .put = alc_automute_mode_put,
1547 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1549 static int alc_add_automute_mode_enum(struct hda_codec *codec)
1551 struct alc_spec *spec = codec->spec;
1552 struct snd_kcontrol_new *knew;
1554 knew = alc_kcontrol_new(spec);
1557 *knew = alc_automute_mode_enum;
1558 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1564 static void alc_init_auto_hp(struct hda_codec *codec)
1566 struct alc_spec *spec = codec->spec;
1567 struct auto_pin_cfg *cfg = &spec->autocfg;
1571 if (cfg->hp_pins[0])
1573 if (cfg->line_out_pins[0])
1575 if (cfg->speaker_pins[0])
1577 if (present < 2) /* need two different output types */
1580 spec->automute_hp_lo = 1; /* both HP and LO automute */
1582 if (!cfg->speaker_pins[0]) {
1583 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1584 sizeof(cfg->speaker_pins));
1585 cfg->speaker_outs = cfg->line_outs;
1588 if (!cfg->hp_pins[0]) {
1589 memcpy(cfg->hp_pins, cfg->line_out_pins,
1590 sizeof(cfg->hp_pins));
1591 cfg->hp_outs = cfg->line_outs;
1594 for (i = 0; i < cfg->hp_outs; i++) {
1595 hda_nid_t nid = cfg->hp_pins[i];
1596 if (!is_jack_detectable(codec, nid))
1598 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1600 snd_hda_codec_write_cache(codec, nid, 0,
1601 AC_VERB_SET_UNSOLICITED_ENABLE,
1602 AC_USRSP_EN | ALC880_HP_EVENT);
1604 spec->automute_mode = ALC_AUTOMUTE_PIN;
1606 if (spec->automute && cfg->line_out_pins[0] &&
1607 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1608 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1609 for (i = 0; i < cfg->line_outs; i++) {
1610 hda_nid_t nid = cfg->line_out_pins[i];
1611 if (!is_jack_detectable(codec, nid))
1613 snd_printdd("realtek: Enable Line-Out auto-muting "
1614 "on NID 0x%x\n", nid);
1615 snd_hda_codec_write_cache(codec, nid, 0,
1616 AC_VERB_SET_UNSOLICITED_ENABLE,
1617 AC_USRSP_EN | ALC880_FRONT_EVENT);
1618 spec->detect_line = 1;
1620 spec->automute_lines = spec->detect_line;
1623 if (spec->automute) {
1624 /* create a control for automute mode */
1625 alc_add_automute_mode_enum(codec);
1626 spec->unsol_event = alc_sku_unsol_event;
1630 static void alc_init_auto_mic(struct hda_codec *codec)
1632 struct alc_spec *spec = codec->spec;
1633 struct auto_pin_cfg *cfg = &spec->autocfg;
1634 hda_nid_t fixed, ext, dock;
1637 fixed = ext = dock = 0;
1638 for (i = 0; i < cfg->num_inputs; i++) {
1639 hda_nid_t nid = cfg->inputs[i].pin;
1640 unsigned int defcfg;
1641 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1642 switch (snd_hda_get_input_pin_attr(defcfg)) {
1643 case INPUT_PIN_ATTR_INT:
1645 return; /* already occupied */
1646 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1647 return; /* invalid type */
1650 case INPUT_PIN_ATTR_UNUSED:
1651 return; /* invalid entry */
1652 case INPUT_PIN_ATTR_DOCK:
1654 return; /* already occupied */
1655 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1656 return; /* invalid type */
1661 return; /* already occupied */
1662 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1663 return; /* invalid type */
1674 if (!is_jack_detectable(codec, ext))
1675 return; /* no unsol support */
1676 if (dock && !is_jack_detectable(codec, dock))
1677 return; /* no unsol support */
1678 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1680 spec->ext_mic.pin = ext;
1681 spec->dock_mic.pin = dock;
1682 spec->int_mic.pin = fixed;
1683 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1684 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1685 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1687 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1688 AC_VERB_SET_UNSOLICITED_ENABLE,
1689 AC_USRSP_EN | ALC880_MIC_EVENT);
1690 spec->unsol_event = alc_sku_unsol_event;
1693 /* Could be any non-zero and even value. When used as fixup, tells
1694 * the driver to ignore any present sku defines.
1696 #define ALC_FIXUP_SKU_IGNORE (2)
1698 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1700 unsigned int ass, tmp, i;
1702 struct alc_spec *spec = codec->spec;
1704 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1706 if (spec->cdefine.fixup) {
1707 ass = spec->cdefine.sku_cfg;
1708 if (ass == ALC_FIXUP_SKU_IGNORE)
1713 ass = codec->subsystem_id & 0xffff;
1714 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1718 if (codec->vendor_id == 0x10ec0260)
1720 ass = snd_hda_codec_get_pincfg(codec, nid);
1723 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1724 codec->chip_name, ass);
1730 for (i = 1; i < 16; i++) {
1734 if (((ass >> 16) & 0xf) != tmp)
1737 spec->cdefine.port_connectivity = ass >> 30;
1738 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1739 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1740 spec->cdefine.customization = ass >> 8;
1742 spec->cdefine.sku_cfg = ass;
1743 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1744 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1745 spec->cdefine.swap = (ass & 0x2) >> 1;
1746 spec->cdefine.override = ass & 0x1;
1748 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1749 nid, spec->cdefine.sku_cfg);
1750 snd_printd("SKU: port_connectivity=0x%x\n",
1751 spec->cdefine.port_connectivity);
1752 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1753 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1754 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1755 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1756 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1757 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1758 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1763 /* check subsystem ID and set up device-specific initialization;
1764 * return 1 if initialized, 0 if invalid SSID
1766 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1767 * 31 ~ 16 : Manufacture ID
1769 * 7 ~ 0 : Assembly ID
1770 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1772 static int alc_subsystem_id(struct hda_codec *codec,
1773 hda_nid_t porta, hda_nid_t porte,
1774 hda_nid_t portd, hda_nid_t porti)
1776 unsigned int ass, tmp, i;
1778 struct alc_spec *spec = codec->spec;
1780 if (spec->cdefine.fixup) {
1781 ass = spec->cdefine.sku_cfg;
1782 if (ass == ALC_FIXUP_SKU_IGNORE)
1787 ass = codec->subsystem_id & 0xffff;
1788 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1791 /* invalid SSID, check the special NID pin defcfg instead */
1793 * 31~30 : port connectivity
1796 * 19~16 : Check sum (15:1)
1801 if (codec->vendor_id == 0x10ec0260)
1803 ass = snd_hda_codec_get_pincfg(codec, nid);
1804 snd_printd("realtek: No valid SSID, "
1805 "checking pincfg 0x%08x for NID 0x%x\n",
1809 if ((ass >> 30) != 1) /* no physical connection */
1814 for (i = 1; i < 16; i++) {
1818 if (((ass >> 16) & 0xf) != tmp)
1821 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1822 ass & 0xffff, codec->vendor_id);
1826 * 2 : 0 --> Desktop, 1 --> Laptop
1827 * 3~5 : External Amplifier control
1830 tmp = (ass & 0x38) >> 3; /* external Amp control */
1833 spec->init_amp = ALC_INIT_GPIO1;
1836 spec->init_amp = ALC_INIT_GPIO2;
1839 spec->init_amp = ALC_INIT_GPIO3;
1843 spec->init_amp = ALC_INIT_DEFAULT;
1847 /* is laptop or Desktop and enable the function "Mute internal speaker
1848 * when the external headphone out jack is plugged"
1850 if (!(ass & 0x8000))
1853 * 10~8 : Jack location
1854 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1856 * 15 : 1 --> enable the function "Mute internal speaker
1857 * when the external headphone out jack is plugged"
1859 if (!spec->autocfg.hp_pins[0]) {
1861 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1872 for (i = 0; i < spec->autocfg.line_outs; i++)
1873 if (spec->autocfg.line_out_pins[i] == nid)
1875 spec->autocfg.hp_pins[0] = nid;
1880 static void alc_ssid_check(struct hda_codec *codec,
1881 hda_nid_t porta, hda_nid_t porte,
1882 hda_nid_t portd, hda_nid_t porti)
1884 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1885 struct alc_spec *spec = codec->spec;
1886 snd_printd("realtek: "
1887 "Enable default setup for auto mode as fallback\n");
1888 spec->init_amp = ALC_INIT_DEFAULT;
1891 alc_init_auto_hp(codec);
1892 alc_init_auto_mic(codec);
1896 * Fix-up pin default configurations and add default verbs
1904 struct alc_model_fixup {
1915 const struct alc_pincfg *pins;
1916 const struct hda_verb *verbs;
1917 void (*func)(struct hda_codec *codec,
1918 const struct alc_fixup *fix,
1932 ALC_FIXUP_ACT_PRE_PROBE,
1933 ALC_FIXUP_ACT_PROBE,
1937 static void alc_apply_fixup(struct hda_codec *codec, int action)
1939 struct alc_spec *spec = codec->spec;
1940 int id = spec->fixup_id;
1941 #ifdef CONFIG_SND_DEBUG_VERBOSE
1942 const char *modelname = spec->fixup_name;
1946 if (!spec->fixup_list)
1950 const struct alc_fixup *fix = spec->fixup_list + id;
1951 const struct alc_pincfg *cfg;
1953 switch (fix->type) {
1955 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1957 snd_printdd(KERN_INFO "hda_codec: %s: "
1958 "Apply sku override for %s\n",
1959 codec->chip_name, modelname);
1960 spec->cdefine.sku_cfg = fix->v.sku;
1961 spec->cdefine.fixup = 1;
1963 case ALC_FIXUP_PINS:
1965 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1967 snd_printdd(KERN_INFO "hda_codec: %s: "
1968 "Apply pincfg for %s\n",
1969 codec->chip_name, modelname);
1970 for (; cfg->nid; cfg++)
1971 snd_hda_codec_set_pincfg(codec, cfg->nid,
1974 case ALC_FIXUP_VERBS:
1975 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1977 snd_printdd(KERN_INFO "hda_codec: %s: "
1978 "Apply fix-verbs for %s\n",
1979 codec->chip_name, modelname);
1980 add_verb(codec->spec, fix->v.verbs);
1982 case ALC_FIXUP_FUNC:
1985 snd_printdd(KERN_INFO "hda_codec: %s: "
1986 "Apply fix-func for %s\n",
1987 codec->chip_name, modelname);
1988 fix->v.func(codec, fix, action);
1991 snd_printk(KERN_ERR "hda_codec: %s: "
1992 "Invalid fixup type %d\n",
1993 codec->chip_name, fix->type);
2004 static void alc_pick_fixup(struct hda_codec *codec,
2005 const struct alc_model_fixup *models,
2006 const struct snd_pci_quirk *quirk,
2007 const struct alc_fixup *fixlist)
2009 struct alc_spec *spec = codec->spec;
2011 const char *name = NULL;
2013 if (codec->modelname && models) {
2014 while (models->name) {
2015 if (!strcmp(codec->modelname, models->name)) {
2017 name = models->name;
2024 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2027 #ifdef CONFIG_SND_DEBUG_VERBOSE
2033 spec->fixup_id = id;
2035 spec->fixup_list = fixlist;
2036 spec->fixup_name = name;
2040 static int alc_read_coef_idx(struct hda_codec *codec,
2041 unsigned int coef_idx)
2044 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2046 val = snd_hda_codec_read(codec, 0x20, 0,
2047 AC_VERB_GET_PROC_COEF, 0);
2051 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2052 unsigned int coef_val)
2054 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2056 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2060 /* set right pin controls for digital I/O */
2061 static void alc_auto_init_digital(struct hda_codec *codec)
2063 struct alc_spec *spec = codec->spec;
2067 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2068 pin = spec->autocfg.dig_out_pins[i];
2071 snd_hda_codec_write(codec, pin, 0,
2072 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2074 dac = spec->multiout.dig_out_nid;
2076 dac = spec->slave_dig_outs[i - 1];
2077 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2079 snd_hda_codec_write(codec, dac, 0,
2080 AC_VERB_SET_AMP_GAIN_MUTE,
2083 pin = spec->autocfg.dig_in_pin;
2085 snd_hda_codec_write(codec, pin, 0,
2086 AC_VERB_SET_PIN_WIDGET_CONTROL,
2090 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2091 static void alc_auto_parse_digital(struct hda_codec *codec)
2093 struct alc_spec *spec = codec->spec;
2097 /* support multiple SPDIFs; the secondary is set up as a slave */
2098 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2099 err = snd_hda_get_connections(codec,
2100 spec->autocfg.dig_out_pins[i],
2105 spec->multiout.dig_out_nid = dig_nid;
2106 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2108 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2109 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2111 spec->slave_dig_outs[i - 1] = dig_nid;
2115 if (spec->autocfg.dig_in_pin) {
2116 dig_nid = codec->start_nid;
2117 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2118 unsigned int wcaps = get_wcaps(codec, dig_nid);
2119 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2121 if (!(wcaps & AC_WCAP_DIGITAL))
2123 if (!(wcaps & AC_WCAP_CONN_LIST))
2125 err = get_connection_index(codec, dig_nid,
2126 spec->autocfg.dig_in_pin);
2128 spec->dig_in_nid = dig_nid;
2142 static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2143 /* Mic-in jack as mic in */
2144 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2145 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2146 /* Line-in jack as Line in */
2147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2149 /* Line-Out as Front */
2150 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2157 static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2158 /* Mic-in jack as mic in */
2159 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2160 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2161 /* Line-in jack as Surround */
2162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2164 /* Line-Out as Front */
2165 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2172 static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2173 /* Mic-in jack as CLFE */
2174 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2175 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2176 /* Line-in jack as Surround */
2177 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2178 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2179 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2180 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2187 static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2188 /* Mic-in jack as CLFE */
2189 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2190 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2191 /* Line-in jack as Surround */
2192 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2193 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2194 /* Line-Out as Side */
2195 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2199 static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2200 { 2, alc888_4ST_ch2_intel_init },
2201 { 4, alc888_4ST_ch4_intel_init },
2202 { 6, alc888_4ST_ch6_intel_init },
2203 { 8, alc888_4ST_ch8_intel_init },
2207 * ALC888 Fujitsu Siemens Amillo xa3530
2210 static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2211 /* Front Mic: set to PIN_IN (empty by default) */
2212 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2213 /* Connect Internal HP to Front */
2214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2216 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2217 /* Connect Bass HP to Front */
2218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2221 /* Connect Line-Out side jack (SPDIF) to Side */
2222 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2223 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2224 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2225 /* Connect Mic jack to CLFE */
2226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2228 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2229 /* Connect Line-in jack to Surround */
2230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2232 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2233 /* Connect HP out jack to Front */
2234 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2235 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2237 /* Enable unsolicited event for HP jack and Line-out jack */
2238 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2239 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2243 static void alc889_automute_setup(struct hda_codec *codec)
2245 struct alc_spec *spec = codec->spec;
2247 spec->autocfg.hp_pins[0] = 0x15;
2248 spec->autocfg.speaker_pins[0] = 0x14;
2249 spec->autocfg.speaker_pins[1] = 0x16;
2250 spec->autocfg.speaker_pins[2] = 0x17;
2251 spec->autocfg.speaker_pins[3] = 0x19;
2252 spec->autocfg.speaker_pins[4] = 0x1a;
2254 spec->automute_mode = ALC_AUTOMUTE_AMP;
2257 static void alc889_intel_init_hook(struct hda_codec *codec)
2259 alc889_coef_init(codec);
2260 alc_hp_automute(codec);
2263 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2265 struct alc_spec *spec = codec->spec;
2267 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2268 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2269 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2270 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2272 spec->automute_mode = ALC_AUTOMUTE_AMP;
2276 * ALC888 Acer Aspire 4930G model
2279 static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2280 /* Front Mic: set to PIN_IN (empty by default) */
2281 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2282 /* Unselect Front Mic by default in input mixer 3 */
2283 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2284 /* Enable unsolicited event for HP jack */
2285 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2286 /* Connect Internal HP to front */
2287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2290 /* Connect HP out to front */
2291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2292 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2293 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2294 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2299 * ALC888 Acer Aspire 6530G model
2302 static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2303 /* Route to built-in subwoofer as well as speakers */
2304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2307 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2308 /* Bias voltage on for external mic port */
2309 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2310 /* Front Mic: set to PIN_IN (empty by default) */
2311 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2312 /* Unselect Front Mic by default in input mixer 3 */
2313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2314 /* Enable unsolicited event for HP jack */
2315 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2316 /* Enable speaker output */
2317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2319 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2320 /* Enable headphone output */
2321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2322 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2323 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2324 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329 *ALC888 Acer Aspire 7730G model
2332 static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2333 /* Bias voltage on for external mic port */
2334 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2335 /* Front Mic: set to PIN_IN (empty by default) */
2336 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2337 /* Unselect Front Mic by default in input mixer 3 */
2338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2339 /* Enable unsolicited event for HP jack */
2340 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2341 /* Enable speaker output */
2342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2345 /* Enable headphone output */
2346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2348 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2349 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2350 /*Enable internal subwoofer */
2351 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2352 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2353 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2354 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2359 * ALC889 Acer Aspire 8930G model
2362 static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2363 /* Front Mic: set to PIN_IN (empty by default) */
2364 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2365 /* Unselect Front Mic by default in input mixer 3 */
2366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2367 /* Enable unsolicited event for HP jack */
2368 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2369 /* Connect Internal Front to Front */
2370 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2371 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2372 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2373 /* Connect Internal Rear to Rear */
2374 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2375 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2376 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2377 /* Connect Internal CLFE to CLFE */
2378 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2379 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2380 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2381 /* Connect HP out to Front */
2382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2385 /* Enable all DACs */
2386 /* DAC DISABLE/MUTE 1? */
2387 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2388 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2389 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2390 /* DAC DISABLE/MUTE 2? */
2391 /* some bit here disables the other DACs. Init=0x4900 */
2392 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2393 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2395 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2396 * which makes the stereo useless. However, either the mic or the ALC889
2397 * makes the signal become a difference/sum signal instead of standard
2398 * stereo, which is annoying. So instead we flip this bit which makes the
2399 * codec replicate the sum signal to both channels, turning it into a
2402 /* DMIC_CONTROL? Init value = 0x0001 */
2403 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2404 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2408 static const struct hda_input_mux alc888_2_capture_sources[2] = {
2409 /* Front mic only available on one ADC */
2416 { "Front Mic", 0xb },
2429 static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2430 /* Interal mic only available on one ADC */
2437 { "Input Mix", 0xa },
2438 { "Internal Mic", 0xb },
2447 { "Input Mix", 0xa },
2452 static const struct hda_input_mux alc889_capture_sources[3] = {
2453 /* Digital mic only available on first "ADC" */
2460 { "Front Mic", 0xb },
2461 { "Input Mix", 0xa },
2470 { "Input Mix", 0xa },
2479 { "Input Mix", 0xa },
2484 static const struct snd_kcontrol_new alc888_base_mixer[] = {
2485 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2486 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2487 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2488 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2489 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2491 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2492 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2493 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2494 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2495 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2496 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2497 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2498 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2499 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2501 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2502 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2506 static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2507 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2510 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2511 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2513 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2514 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2515 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2516 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2517 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2518 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2519 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2523 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2524 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2528 static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2529 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2530 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2532 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2533 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2535 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2536 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2537 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2538 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2539 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2540 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2541 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2542 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2547 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2549 struct alc_spec *spec = codec->spec;
2551 spec->autocfg.hp_pins[0] = 0x15;
2552 spec->autocfg.speaker_pins[0] = 0x14;
2553 spec->autocfg.speaker_pins[1] = 0x16;
2554 spec->autocfg.speaker_pins[2] = 0x17;
2556 spec->automute_mode = ALC_AUTOMUTE_AMP;
2559 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2561 struct alc_spec *spec = codec->spec;
2563 spec->autocfg.hp_pins[0] = 0x15;
2564 spec->autocfg.speaker_pins[0] = 0x14;
2565 spec->autocfg.speaker_pins[1] = 0x16;
2566 spec->autocfg.speaker_pins[2] = 0x17;
2568 spec->automute_mode = ALC_AUTOMUTE_AMP;
2571 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2573 struct alc_spec *spec = codec->spec;
2575 spec->autocfg.hp_pins[0] = 0x15;
2576 spec->autocfg.speaker_pins[0] = 0x14;
2577 spec->autocfg.speaker_pins[1] = 0x16;
2578 spec->autocfg.speaker_pins[2] = 0x17;
2580 spec->automute_mode = ALC_AUTOMUTE_AMP;
2583 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2585 struct alc_spec *spec = codec->spec;
2587 spec->autocfg.hp_pins[0] = 0x15;
2588 spec->autocfg.speaker_pins[0] = 0x14;
2589 spec->autocfg.speaker_pins[1] = 0x16;
2590 spec->autocfg.speaker_pins[2] = 0x1b;
2592 spec->automute_mode = ALC_AUTOMUTE_AMP;
2596 * ALC880 3-stack model
2598 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2599 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2600 * F-Mic = 0x1b, HP = 0x19
2603 static const hda_nid_t alc880_dac_nids[4] = {
2604 /* front, rear, clfe, rear_surr */
2605 0x02, 0x05, 0x04, 0x03
2608 static const hda_nid_t alc880_adc_nids[3] = {
2613 /* The datasheet says the node 0x07 is connected from inputs,
2614 * but it shows zero connection in the real implementation on some devices.
2615 * Note: this is a 915GAV bug, fixed on 915GLV
2617 static const hda_nid_t alc880_adc_nids_alt[2] = {
2622 #define ALC880_DIGOUT_NID 0x06
2623 #define ALC880_DIGIN_NID 0x0a
2625 static const struct hda_input_mux alc880_capture_source = {
2629 { "Front Mic", 0x3 },
2635 /* channel source setting (2/6 channel selection for 3-stack) */
2637 static const struct hda_verb alc880_threestack_ch2_init[] = {
2638 /* set line-in to input, mute it */
2639 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2640 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2641 /* set mic-in to input vref 80%, mute it */
2642 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2643 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2648 static const struct hda_verb alc880_threestack_ch6_init[] = {
2649 /* set line-in to output, unmute it */
2650 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2651 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2652 /* set mic-in to output, unmute it */
2653 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2654 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2658 static const struct hda_channel_mode alc880_threestack_modes[2] = {
2659 { 2, alc880_threestack_ch2_init },
2660 { 6, alc880_threestack_ch6_init },
2663 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2664 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2665 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2667 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2668 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2669 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2670 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2671 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2683 .name = "Channel Mode",
2684 .info = alc_ch_mode_info,
2685 .get = alc_ch_mode_get,
2686 .put = alc_ch_mode_put,
2691 /* capture mixer elements */
2692 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2693 struct snd_ctl_elem_info *uinfo)
2695 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2696 struct alc_spec *spec = codec->spec;
2699 mutex_lock(&codec->control_mutex);
2700 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2702 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2703 mutex_unlock(&codec->control_mutex);
2707 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2708 unsigned int size, unsigned int __user *tlv)
2710 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2711 struct alc_spec *spec = codec->spec;
2714 mutex_lock(&codec->control_mutex);
2715 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2717 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2718 mutex_unlock(&codec->control_mutex);
2722 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2723 struct snd_ctl_elem_value *ucontrol);
2725 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2726 struct snd_ctl_elem_value *ucontrol,
2729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2730 struct alc_spec *spec = codec->spec;
2731 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2734 mutex_lock(&codec->control_mutex);
2735 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2737 err = func(kcontrol, ucontrol);
2738 mutex_unlock(&codec->control_mutex);
2742 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2743 struct snd_ctl_elem_value *ucontrol)
2745 return alc_cap_getput_caller(kcontrol, ucontrol,
2746 snd_hda_mixer_amp_volume_get);
2749 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2750 struct snd_ctl_elem_value *ucontrol)
2752 return alc_cap_getput_caller(kcontrol, ucontrol,
2753 snd_hda_mixer_amp_volume_put);
2756 /* capture mixer elements */
2757 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2759 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2760 struct snd_ctl_elem_value *ucontrol)
2762 return alc_cap_getput_caller(kcontrol, ucontrol,
2763 snd_hda_mixer_amp_switch_get);
2766 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2767 struct snd_ctl_elem_value *ucontrol)
2769 return alc_cap_getput_caller(kcontrol, ucontrol,
2770 snd_hda_mixer_amp_switch_put);
2773 #define _DEFINE_CAPMIX(num) \
2775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2776 .name = "Capture Switch", \
2777 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2779 .info = alc_cap_sw_info, \
2780 .get = alc_cap_sw_get, \
2781 .put = alc_cap_sw_put, \
2784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2785 .name = "Capture Volume", \
2786 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2787 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2788 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2790 .info = alc_cap_vol_info, \
2791 .get = alc_cap_vol_get, \
2792 .put = alc_cap_vol_put, \
2793 .tlv = { .c = alc_cap_vol_tlv }, \
2796 #define _DEFINE_CAPSRC(num) \
2798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2799 /* .name = "Capture Source", */ \
2800 .name = "Input Source", \
2802 .info = alc_mux_enum_info, \
2803 .get = alc_mux_enum_get, \
2804 .put = alc_mux_enum_put, \
2807 #define DEFINE_CAPMIX(num) \
2808 static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2809 _DEFINE_CAPMIX(num), \
2810 _DEFINE_CAPSRC(num), \
2814 #define DEFINE_CAPMIX_NOSRC(num) \
2815 static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2816 _DEFINE_CAPMIX(num), \
2820 /* up to three ADCs */
2824 DEFINE_CAPMIX_NOSRC(1);
2825 DEFINE_CAPMIX_NOSRC(2);
2826 DEFINE_CAPMIX_NOSRC(3);
2829 * ALC880 5-stack model
2831 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2833 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2834 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2837 /* additional mixers to alc880_three_stack_mixer */
2838 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2839 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2840 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2844 /* channel source setting (6/8 channel selection for 5-stack) */
2846 static const struct hda_verb alc880_fivestack_ch6_init[] = {
2847 /* set line-in to input, mute it */
2848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2854 static const struct hda_verb alc880_fivestack_ch8_init[] = {
2855 /* set line-in to output, unmute it */
2856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2861 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2862 { 6, alc880_fivestack_ch6_init },
2863 { 8, alc880_fivestack_ch8_init },
2868 * ALC880 6-stack model
2870 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2871 * Side = 0x05 (0x0f)
2872 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2873 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2876 static const hda_nid_t alc880_6st_dac_nids[4] = {
2877 /* front, rear, clfe, rear_surr */
2878 0x02, 0x03, 0x04, 0x05
2881 static const struct hda_input_mux alc880_6stack_capture_source = {
2885 { "Front Mic", 0x1 },
2891 /* fixed 8-channels */
2892 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2896 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2897 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2898 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2899 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2900 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2901 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2902 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2903 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2904 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2905 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2906 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2909 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2910 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2913 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2914 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2916 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2917 .name = "Channel Mode",
2918 .info = alc_ch_mode_info,
2919 .get = alc_ch_mode_get,
2920 .put = alc_ch_mode_put,
2929 * W810 has rear IO for:
2932 * Center/LFE (DAC 04)
2935 * The system also has a pair of internal speakers, and a headphone jack.
2936 * These are both connected to Line2 on the codec, hence to DAC 02.
2938 * There is a variable resistor to control the speaker or headphone
2939 * volume. This is a hardware-only device without a software API.
2941 * Plugging headphones in will disable the internal speakers. This is
2942 * implemented in hardware, not via the driver using jack sense. In
2943 * a similar fashion, plugging into the rear socket marked "front" will
2944 * disable both the speakers and headphones.
2946 * For input, there's a microphone jack, and an "audio in" jack.
2947 * These may not do anything useful with this driver yet, because I
2948 * haven't setup any initialization verbs for these yet...
2951 static const hda_nid_t alc880_w810_dac_nids[3] = {
2952 /* front, rear/surround, clfe */
2956 /* fixed 6 channels */
2957 static const struct hda_channel_mode alc880_w810_modes[1] = {
2961 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2962 static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2963 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2964 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2965 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2966 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2967 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2968 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2969 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2970 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2979 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2980 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2984 static const hda_nid_t alc880_z71v_dac_nids[1] = {
2987 #define ALC880_Z71V_HP_DAC 0x03
2989 /* fixed 2 channels */
2990 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2994 static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2996 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2997 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2998 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2999 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3000 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3008 * ALC880 F1734 model
3010 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3011 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3014 static const hda_nid_t alc880_f1734_dac_nids[1] = {
3017 #define ALC880_F1734_HP_DAC 0x02
3019 static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3020 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3021 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3022 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3023 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3024 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3025 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3026 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3031 static const struct hda_input_mux alc880_f1734_capture_source = {
3043 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3044 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3045 * Mic = 0x18, Line = 0x1a
3048 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3049 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3051 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3054 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3055 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3056 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3057 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3058 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3059 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3060 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3061 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3065 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3068 .name = "Channel Mode",
3069 .info = alc_ch_mode_info,
3070 .get = alc_ch_mode_get,
3071 .put = alc_ch_mode_put,
3077 * ALC880 ASUS W1V model
3079 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3080 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3081 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3084 /* additional mixers to alc880_asus_mixer */
3085 static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3086 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3087 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3092 static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3094 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3097 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3100 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3101 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3106 static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3107 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3108 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3109 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3110 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3111 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3112 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3113 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3114 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3121 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3122 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3125 .name = "Channel Mode",
3126 .info = alc_ch_mode_info,
3127 .get = alc_ch_mode_get,
3128 .put = alc_ch_mode_put,
3133 static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3134 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3135 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3136 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3137 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3140 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3141 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3142 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3143 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3147 static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3148 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3149 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3150 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3151 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3158 * virtual master controls
3162 * slave controls for virtual master
3164 static const char * const alc_slave_vols[] = {
3165 "Front Playback Volume",
3166 "Surround Playback Volume",
3167 "Center Playback Volume",
3168 "LFE Playback Volume",
3169 "Side Playback Volume",
3170 "Headphone Playback Volume",
3171 "Speaker Playback Volume",
3172 "Mono Playback Volume",
3173 "Line-Out Playback Volume",
3177 static const char * const alc_slave_sws[] = {
3178 "Front Playback Switch",
3179 "Surround Playback Switch",
3180 "Center Playback Switch",
3181 "LFE Playback Switch",
3182 "Side Playback Switch",
3183 "Headphone Playback Switch",
3184 "Speaker Playback Switch",
3185 "Mono Playback Switch",
3186 "IEC958 Playback Switch",
3187 "Line-Out Playback Switch",
3192 * build control elements
3195 #define NID_MAPPING (-1)
3197 #define SUBDEV_SPEAKER_ (0 << 6)
3198 #define SUBDEV_HP_ (1 << 6)
3199 #define SUBDEV_LINE_ (2 << 6)
3200 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3201 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3202 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3204 static void alc_free_kctls(struct hda_codec *codec);
3206 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3207 /* additional beep mixers; the actual parameters are overwritten at build */
3208 static const struct snd_kcontrol_new alc_beep_mixer[] = {
3209 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3210 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3215 static int alc_build_controls(struct hda_codec *codec)
3217 struct alc_spec *spec = codec->spec;
3218 struct snd_kcontrol *kctl = NULL;
3219 const struct snd_kcontrol_new *knew;
3224 for (i = 0; i < spec->num_mixers; i++) {
3225 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3229 if (spec->cap_mixer) {
3230 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3234 if (spec->multiout.dig_out_nid) {
3235 err = snd_hda_create_spdif_out_ctls(codec,
3236 spec->multiout.dig_out_nid,
3237 spec->multiout.dig_out_nid);
3240 if (!spec->no_analog) {
3241 err = snd_hda_create_spdif_share_sw(codec,
3245 spec->multiout.share_spdif = 1;
3248 if (spec->dig_in_nid) {
3249 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3254 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3255 /* create beep controls if needed */
3256 if (spec->beep_amp) {
3257 const struct snd_kcontrol_new *knew;
3258 for (knew = alc_beep_mixer; knew->name; knew++) {
3259 struct snd_kcontrol *kctl;
3260 kctl = snd_ctl_new1(knew, codec);
3263 kctl->private_value = spec->beep_amp;
3264 err = snd_hda_ctl_add(codec, 0, kctl);
3271 /* if we have no master control, let's create it */
3272 if (!spec->no_analog &&
3273 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3274 unsigned int vmaster_tlv[4];
3275 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3276 HDA_OUTPUT, vmaster_tlv);
3277 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3278 vmaster_tlv, alc_slave_vols);
3282 if (!spec->no_analog &&
3283 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3284 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3285 NULL, alc_slave_sws);
3290 /* assign Capture Source enums to NID */
3291 if (spec->capsrc_nids || spec->adc_nids) {
3292 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3294 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3295 for (i = 0; kctl && i < kctl->count; i++) {
3296 const hda_nid_t *nids = spec->capsrc_nids;
3298 nids = spec->adc_nids;
3299 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3304 if (spec->cap_mixer) {
3305 const char *kname = kctl ? kctl->id.name : NULL;
3306 for (knew = spec->cap_mixer; knew->name; knew++) {
3307 if (kname && strcmp(knew->name, kname) == 0)
3309 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3310 for (i = 0; kctl && i < kctl->count; i++) {
3311 err = snd_hda_add_nid(codec, kctl, i,
3319 /* other nid->control mapping */
3320 for (i = 0; i < spec->num_mixers; i++) {
3321 for (knew = spec->mixers[i]; knew->name; knew++) {
3322 if (knew->iface != NID_MAPPING)
3324 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3327 u = knew->subdevice;
3328 for (j = 0; j < 4; j++, u >>= 8) {
3333 case SUBDEV_SPEAKER_:
3334 nid = spec->autocfg.speaker_pins[nid];
3337 nid = spec->autocfg.line_out_pins[nid];
3340 nid = spec->autocfg.hp_pins[nid];
3345 err = snd_hda_add_nid(codec, kctl, 0, nid);
3349 u = knew->private_value;
3350 for (j = 0; j < 4; j++, u >>= 8) {
3354 err = snd_hda_add_nid(codec, kctl, 0, nid);
3361 alc_free_kctls(codec); /* no longer needed */
3368 * initialize the codec volumes, etc
3372 * generic initialization of ADC, input mixers and output mixers
3374 static const struct hda_verb alc880_volume_init_verbs[] = {
3376 * Unmute ADC0-2 and set the default input to mic-in
3378 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3379 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3380 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3382 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3383 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3385 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3387 * Note: PASD motherboards uses the Line In 2 as the input for front
3390 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3391 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3392 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3393 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3394 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3400 * Set up output mixers (0x0c - 0x0f)
3402 /* set vol=0 to output mixers */
3403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3404 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3405 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3407 /* set up input amps for analog loopback */
3408 /* Amp Indices: DAC = 0, mixer = 1 */
3409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3415 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3422 * 3-stack pin configuration:
3423 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3425 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3427 * preset connection lists of input pins
3428 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3430 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3431 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3432 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3435 * Set pin mode and muting
3437 /* set front pin widgets 0x14 for output */
3438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3440 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3441 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3442 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3443 /* Mic2 (as headphone out) for HP output */
3444 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3445 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3446 /* Line In pin widget for input */
3447 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3449 /* Line2 (as front mic) pin widget for input and vref at 80% */
3450 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3451 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3452 /* CD pin widget for input */
3453 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3459 * 5-stack pin configuration:
3460 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3461 * line-in/side = 0x1a, f-mic = 0x1b
3463 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3465 * preset connection lists of input pins
3466 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3468 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3469 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3472 * Set pin mode and muting
3474 /* set pin widgets 0x14-0x17 for output */
3475 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3477 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3478 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3479 /* unmute pins for output (no gain on this amp) */
3480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3482 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3483 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3485 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3486 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3487 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3488 /* Mic2 (as headphone out) for HP output */
3489 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3490 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3491 /* Line In pin widget for input */
3492 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3493 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3494 /* Line2 (as front mic) pin widget for input and vref at 80% */
3495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3496 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3497 /* CD pin widget for input */
3498 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3504 * W810 pin configuration:
3505 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3507 static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3508 /* hphone/speaker input selector: front DAC */
3509 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3512 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3514 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3515 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3516 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3525 * Z71V pin configuration:
3526 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3528 static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3529 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3530 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3531 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3532 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3534 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3535 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3537 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543 * 6-stack pin configuration:
3544 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3545 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3547 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3548 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3552 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3554 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3555 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3556 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3557 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3561 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3563 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3564 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3565 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3566 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3567 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3573 * Uniwill pin configuration:
3574 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3577 static const struct hda_verb alc880_uniwill_init_verbs[] = {
3578 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3581 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3584 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3585 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3586 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3587 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3592 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3595 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3601 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3602 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3603 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3605 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3606 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3613 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3615 static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3616 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3620 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3622 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3623 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3626 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3627 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3628 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3629 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3633 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3635 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3636 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3639 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3644 static const struct hda_verb alc880_beep_init_verbs[] = {
3645 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3649 /* auto-toggle front mic */
3650 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3652 unsigned int present;
3655 present = snd_hda_jack_detect(codec, 0x18);
3656 bits = present ? HDA_AMP_MUTE : 0;
3657 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3660 static void alc880_uniwill_setup(struct hda_codec *codec)
3662 struct alc_spec *spec = codec->spec;
3664 spec->autocfg.hp_pins[0] = 0x14;
3665 spec->autocfg.speaker_pins[0] = 0x15;
3666 spec->autocfg.speaker_pins[0] = 0x16;
3668 spec->automute_mode = ALC_AUTOMUTE_AMP;
3671 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3673 alc_hp_automute(codec);
3674 alc88x_simple_mic_automute(codec);
3677 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3680 /* Looks like the unsol event is incompatible with the standard
3681 * definition. 4bit tag is placed at 28 bit!
3683 switch (res >> 28) {
3684 case ALC880_MIC_EVENT:
3685 alc88x_simple_mic_automute(codec);
3688 alc_sku_unsol_event(codec, res);
3693 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3695 struct alc_spec *spec = codec->spec;
3697 spec->autocfg.hp_pins[0] = 0x14;
3698 spec->autocfg.speaker_pins[0] = 0x15;
3700 spec->automute_mode = ALC_AUTOMUTE_AMP;
3703 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3705 unsigned int present;
3707 present = snd_hda_codec_read(codec, 0x21, 0,
3708 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3709 present &= HDA_AMP_VOLMASK;
3710 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3711 HDA_AMP_VOLMASK, present);
3712 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3713 HDA_AMP_VOLMASK, present);
3716 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3719 /* Looks like the unsol event is incompatible with the standard
3720 * definition. 4bit tag is placed at 28 bit!
3722 if ((res >> 28) == ALC880_DCVOL_EVENT)
3723 alc880_uniwill_p53_dcvol_automute(codec);
3725 alc_sku_unsol_event(codec, res);
3729 * F1734 pin configuration:
3730 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3732 static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3733 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3734 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3735 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3736 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3737 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3744 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3745 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3746 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3747 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3748 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3750 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3751 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3752 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3754 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3755 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3761 * ASUS pin configuration:
3762 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3764 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3765 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3766 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3767 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3768 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3772 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3774 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3776 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3779 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3782 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3783 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3784 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3785 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3792 /* Enable GPIO mask and set output */
3793 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3794 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3795 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3797 /* Clevo m520g init */
3798 static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3799 /* headphone output */
3800 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3802 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3803 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3805 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3806 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3808 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3809 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810 /* Mic1 (rear panel) */
3811 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3813 /* Mic2 (front panel) */
3814 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3815 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3819 /* change to EAPD mode */
3820 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3821 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3826 static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3827 /* change to EAPD mode */
3828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3829 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3831 /* Headphone output */
3832 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3835 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3837 /* Line In pin widget for input */
3838 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3839 /* CD pin widget for input */
3840 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3841 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3842 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3844 /* change to EAPD mode */
3845 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3846 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3852 * LG m1 express dual
3855 * Rear Line-In/Out (blue): 0x14
3856 * Build-in Mic-In: 0x15
3858 * HP-Out (green): 0x1b
3859 * Mic-In/Out (red): 0x19
3863 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3864 static const hda_nid_t alc880_lg_dac_nids[3] = {
3868 /* seems analog CD is not working */
3869 static const struct hda_input_mux alc880_lg_capture_source = {
3874 { "Internal Mic", 0x6 },
3878 /* 2,4,6 channel modes */
3879 static const struct hda_verb alc880_lg_ch2_init[] = {
3880 /* set line-in and mic-in to input */
3881 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3882 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3886 static const struct hda_verb alc880_lg_ch4_init[] = {
3887 /* set line-in to out and mic-in to input */
3888 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3889 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3893 static const struct hda_verb alc880_lg_ch6_init[] = {
3894 /* set line-in and mic-in to output */
3895 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3896 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3900 static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3901 { 2, alc880_lg_ch2_init },
3902 { 4, alc880_lg_ch4_init },
3903 { 6, alc880_lg_ch6_init },
3906 static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3907 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3908 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3909 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3910 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3911 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3912 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3913 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3914 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3916 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3917 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3918 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3920 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3923 .name = "Channel Mode",
3924 .info = alc_ch_mode_info,
3925 .get = alc_ch_mode_get,
3926 .put = alc_ch_mode_put,
3931 static const struct hda_verb alc880_lg_init_verbs[] = {
3932 /* set capture source to mic-in */
3933 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3934 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3935 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3936 /* mute all amp mixer inputs */
3937 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3938 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3939 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3940 /* line-in to input */
3941 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3942 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3944 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3945 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3947 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3949 /* mic-in to input */
3950 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3951 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3952 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3954 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3955 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3958 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3962 /* toggle speaker-output according to the hp-jack state */
3963 static void alc880_lg_setup(struct hda_codec *codec)
3965 struct alc_spec *spec = codec->spec;
3967 spec->autocfg.hp_pins[0] = 0x1b;
3968 spec->autocfg.speaker_pins[0] = 0x17;
3970 spec->automute_mode = ALC_AUTOMUTE_AMP;
3979 * Built-in Mic-In: 0x19
3985 static const struct hda_input_mux alc880_lg_lw_capture_source = {
3989 { "Internal Mic", 0x1 },
3994 #define alc880_lg_lw_modes alc880_threestack_modes
3996 static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3997 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3998 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3999 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4000 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4001 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4002 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4003 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4004 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4009 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4010 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4013 .name = "Channel Mode",
4014 .info = alc_ch_mode_info,
4015 .get = alc_ch_mode_get,
4016 .put = alc_ch_mode_put,
4021 static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4022 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4023 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4024 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4026 /* set capture source to mic-in */
4027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4029 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4030 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4033 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4035 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4036 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4037 /* mic-in to input */
4038 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4039 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4041 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4042 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4044 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4048 /* toggle speaker-output according to the hp-jack state */
4049 static void alc880_lg_lw_setup(struct hda_codec *codec)
4051 struct alc_spec *spec = codec->spec;
4053 spec->autocfg.hp_pins[0] = 0x1b;
4054 spec->autocfg.speaker_pins[0] = 0x14;
4056 spec->automute_mode = ALC_AUTOMUTE_AMP;
4059 static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4060 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4061 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4064 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4065 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4069 static const struct hda_input_mux alc880_medion_rim_capture_source = {
4073 { "Internal Mic", 0x1 },
4077 static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4078 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4080 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4081 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4083 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4084 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4085 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4086 /* Mic2 (as headphone out) for HP output */
4087 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4088 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4089 /* Internal Speaker */
4090 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4093 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4094 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4096 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4100 /* toggle speaker-output according to the hp-jack state */
4101 static void alc880_medion_rim_automute(struct hda_codec *codec)
4103 struct alc_spec *spec = codec->spec;
4104 alc_hp_automute(codec);
4106 if (spec->jack_present)
4107 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4109 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4112 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4115 /* Looks like the unsol event is incompatible with the standard
4116 * definition. 4bit tag is placed at 28 bit!
4118 if ((res >> 28) == ALC880_HP_EVENT)
4119 alc880_medion_rim_automute(codec);
4122 static void alc880_medion_rim_setup(struct hda_codec *codec)
4124 struct alc_spec *spec = codec->spec;
4126 spec->autocfg.hp_pins[0] = 0x14;
4127 spec->autocfg.speaker_pins[0] = 0x1b;
4129 spec->automute_mode = ALC_AUTOMUTE_AMP;
4132 #ifdef CONFIG_SND_HDA_POWER_SAVE
4133 static const struct hda_amp_list alc880_loopbacks[] = {
4134 { 0x0b, HDA_INPUT, 0 },
4135 { 0x0b, HDA_INPUT, 1 },
4136 { 0x0b, HDA_INPUT, 2 },
4137 { 0x0b, HDA_INPUT, 3 },
4138 { 0x0b, HDA_INPUT, 4 },
4142 static const struct hda_amp_list alc880_lg_loopbacks[] = {
4143 { 0x0b, HDA_INPUT, 1 },
4144 { 0x0b, HDA_INPUT, 6 },
4145 { 0x0b, HDA_INPUT, 7 },
4154 static void alc_init_special_input_src(struct hda_codec *codec);
4156 static int alc_init(struct hda_codec *codec)
4158 struct alc_spec *spec = codec->spec;
4162 alc_auto_init_amp(codec, spec->init_amp);
4164 for (i = 0; i < spec->num_init_verbs; i++)
4165 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4166 alc_init_special_input_src(codec);
4168 if (spec->init_hook)
4169 spec->init_hook(codec);
4171 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4173 hda_call_check_power_status(codec, 0x01);
4177 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4179 struct alc_spec *spec = codec->spec;
4181 if (spec->unsol_event)
4182 spec->unsol_event(codec, res);
4185 #ifdef CONFIG_SND_HDA_POWER_SAVE
4186 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4188 struct alc_spec *spec = codec->spec;
4189 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4194 * Analog playback callbacks
4196 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4197 struct hda_codec *codec,
4198 struct snd_pcm_substream *substream)
4200 struct alc_spec *spec = codec->spec;
4201 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4205 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4206 struct hda_codec *codec,
4207 unsigned int stream_tag,
4208 unsigned int format,
4209 struct snd_pcm_substream *substream)
4211 struct alc_spec *spec = codec->spec;
4212 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4213 stream_tag, format, substream);
4216 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4217 struct hda_codec *codec,
4218 struct snd_pcm_substream *substream)
4220 struct alc_spec *spec = codec->spec;
4221 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4227 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4228 struct hda_codec *codec,
4229 struct snd_pcm_substream *substream)
4231 struct alc_spec *spec = codec->spec;
4232 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4235 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4236 struct hda_codec *codec,
4237 unsigned int stream_tag,
4238 unsigned int format,
4239 struct snd_pcm_substream *substream)
4241 struct alc_spec *spec = codec->spec;
4242 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4243 stream_tag, format, substream);
4246 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4247 struct hda_codec *codec,
4248 struct snd_pcm_substream *substream)
4250 struct alc_spec *spec = codec->spec;
4251 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4254 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4255 struct hda_codec *codec,
4256 struct snd_pcm_substream *substream)
4258 struct alc_spec *spec = codec->spec;
4259 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4265 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4266 struct hda_codec *codec,
4267 unsigned int stream_tag,
4268 unsigned int format,
4269 struct snd_pcm_substream *substream)
4271 struct alc_spec *spec = codec->spec;
4273 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4274 stream_tag, 0, format);
4278 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4279 struct hda_codec *codec,
4280 struct snd_pcm_substream *substream)
4282 struct alc_spec *spec = codec->spec;
4284 snd_hda_codec_cleanup_stream(codec,
4285 spec->adc_nids[substream->number + 1]);
4289 /* analog capture with dynamic dual-adc changes */
4290 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4291 struct hda_codec *codec,
4292 unsigned int stream_tag,
4293 unsigned int format,
4294 struct snd_pcm_substream *substream)
4296 struct alc_spec *spec = codec->spec;
4297 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4298 spec->cur_adc_stream_tag = stream_tag;
4299 spec->cur_adc_format = format;
4300 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4304 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4305 struct hda_codec *codec,
4306 struct snd_pcm_substream *substream)
4308 struct alc_spec *spec = codec->spec;
4309 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4314 static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4318 .nid = 0, /* fill later */
4320 .prepare = dualmic_capture_pcm_prepare,
4321 .cleanup = dualmic_capture_pcm_cleanup
4327 static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4331 /* NID is set in alc_build_pcms */
4333 .open = alc880_playback_pcm_open,
4334 .prepare = alc880_playback_pcm_prepare,
4335 .cleanup = alc880_playback_pcm_cleanup
4339 static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4343 /* NID is set in alc_build_pcms */
4346 static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4350 /* NID is set in alc_build_pcms */
4353 static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4354 .substreams = 2, /* can be overridden */
4357 /* NID is set in alc_build_pcms */
4359 .prepare = alc880_alt_capture_pcm_prepare,
4360 .cleanup = alc880_alt_capture_pcm_cleanup
4364 static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4368 /* NID is set in alc_build_pcms */
4370 .open = alc880_dig_playback_pcm_open,
4371 .close = alc880_dig_playback_pcm_close,
4372 .prepare = alc880_dig_playback_pcm_prepare,
4373 .cleanup = alc880_dig_playback_pcm_cleanup
4377 static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4381 /* NID is set in alc_build_pcms */
4384 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4385 static const struct hda_pcm_stream alc_pcm_null_stream = {
4391 static int alc_build_pcms(struct hda_codec *codec)
4393 struct alc_spec *spec = codec->spec;
4394 struct hda_pcm *info = spec->pcm_rec;
4397 codec->num_pcms = 1;
4398 codec->pcm_info = info;
4400 if (spec->no_analog)
4403 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4404 "%s Analog", codec->chip_name);
4405 info->name = spec->stream_name_analog;
4407 if (spec->stream_analog_playback) {
4408 if (snd_BUG_ON(!spec->multiout.dac_nids))
4410 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4413 if (spec->stream_analog_capture) {
4414 if (snd_BUG_ON(!spec->adc_nids))
4416 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4417 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4420 if (spec->channel_mode) {
4421 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4422 for (i = 0; i < spec->num_channel_mode; i++) {
4423 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4424 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4430 /* SPDIF for stream index #1 */
4431 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4432 snprintf(spec->stream_name_digital,
4433 sizeof(spec->stream_name_digital),
4434 "%s Digital", codec->chip_name);
4435 codec->num_pcms = 2;
4436 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4437 info = spec->pcm_rec + 1;
4438 info->name = spec->stream_name_digital;
4439 if (spec->dig_out_type)
4440 info->pcm_type = spec->dig_out_type;
4442 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4443 if (spec->multiout.dig_out_nid &&
4444 spec->stream_digital_playback) {
4445 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4446 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4448 if (spec->dig_in_nid &&
4449 spec->stream_digital_capture) {
4450 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4451 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4453 /* FIXME: do we need this for all Realtek codec models? */
4454 codec->spdif_status_reset = 1;
4457 if (spec->no_analog)
4460 /* If the use of more than one ADC is requested for the current
4461 * model, configure a second analog capture-only PCM.
4463 /* Additional Analaog capture for index #2 */
4464 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4465 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4466 codec->num_pcms = 3;
4467 info = spec->pcm_rec + 2;
4468 info->name = spec->stream_name_analog;
4469 if (spec->alt_dac_nid) {
4470 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4471 *spec->stream_analog_alt_playback;
4472 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4475 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4476 alc_pcm_null_stream;
4477 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4479 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4480 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4481 *spec->stream_analog_alt_capture;
4482 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4484 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4485 spec->num_adc_nids - 1;
4487 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4488 alc_pcm_null_stream;
4489 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4496 static inline void alc_shutup(struct hda_codec *codec)
4498 struct alc_spec *spec = codec->spec;
4500 if (spec && spec->shutup)
4501 spec->shutup(codec);
4502 snd_hda_shutup_pins(codec);
4505 static void alc_free_kctls(struct hda_codec *codec)
4507 struct alc_spec *spec = codec->spec;
4509 if (spec->kctls.list) {
4510 struct snd_kcontrol_new *kctl = spec->kctls.list;
4512 for (i = 0; i < spec->kctls.used; i++)
4513 kfree(kctl[i].name);
4515 snd_array_free(&spec->kctls);
4518 static void alc_free(struct hda_codec *codec)
4520 struct alc_spec *spec = codec->spec;
4526 snd_hda_input_jack_free(codec);
4527 alc_free_kctls(codec);
4529 snd_hda_detach_beep_device(codec);
4532 #ifdef CONFIG_SND_HDA_POWER_SAVE
4533 static void alc_power_eapd(struct hda_codec *codec)
4535 alc_auto_setup_eapd(codec, false);
4538 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4540 struct alc_spec *spec = codec->spec;
4542 if (spec && spec->power_hook)
4543 spec->power_hook(codec);
4548 #ifdef SND_HDA_NEEDS_RESUME
4549 static int alc_resume(struct hda_codec *codec)
4551 msleep(150); /* to avoid pop noise */
4552 codec->patch_ops.init(codec);
4553 snd_hda_codec_resume_amp(codec);
4554 snd_hda_codec_resume_cache(codec);
4555 hda_call_check_power_status(codec, 0x01);
4562 static const struct hda_codec_ops alc_patch_ops = {
4563 .build_controls = alc_build_controls,
4564 .build_pcms = alc_build_pcms,
4567 .unsol_event = alc_unsol_event,
4568 #ifdef SND_HDA_NEEDS_RESUME
4569 .resume = alc_resume,
4571 #ifdef CONFIG_SND_HDA_POWER_SAVE
4572 .suspend = alc_suspend,
4573 .check_power_status = alc_check_power_status,
4575 .reboot_notify = alc_shutup,
4578 /* replace the codec chip_name with the given string */
4579 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4581 kfree(codec->chip_name);
4582 codec->chip_name = kstrdup(name, GFP_KERNEL);
4583 if (!codec->chip_name) {
4591 * Test configuration for debugging
4593 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4596 #ifdef CONFIG_SND_DEBUG
4597 static const hda_nid_t alc880_test_dac_nids[4] = {
4598 0x02, 0x03, 0x04, 0x05
4601 static const struct hda_input_mux alc880_test_capture_source = {
4610 { "Surround", 0x6 },
4614 static const struct hda_channel_mode alc880_test_modes[4] = {
4621 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4622 struct snd_ctl_elem_info *uinfo)
4624 static const char * const texts[] = {
4625 "N/A", "Line Out", "HP Out",
4626 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4628 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4630 uinfo->value.enumerated.items = 8;
4631 if (uinfo->value.enumerated.item >= 8)
4632 uinfo->value.enumerated.item = 7;
4633 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4637 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4638 struct snd_ctl_elem_value *ucontrol)
4640 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4641 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4642 unsigned int pin_ctl, item = 0;
4644 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4645 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4646 if (pin_ctl & AC_PINCTL_OUT_EN) {
4647 if (pin_ctl & AC_PINCTL_HP_EN)
4651 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4652 switch (pin_ctl & AC_PINCTL_VREFEN) {
4653 case AC_PINCTL_VREF_HIZ: item = 3; break;
4654 case AC_PINCTL_VREF_50: item = 4; break;
4655 case AC_PINCTL_VREF_GRD: item = 5; break;
4656 case AC_PINCTL_VREF_80: item = 6; break;
4657 case AC_PINCTL_VREF_100: item = 7; break;
4660 ucontrol->value.enumerated.item[0] = item;
4664 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4665 struct snd_ctl_elem_value *ucontrol)
4667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4668 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4669 static const unsigned int ctls[] = {
4670 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4671 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4672 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4673 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4674 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4675 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4677 unsigned int old_ctl, new_ctl;
4679 old_ctl = snd_hda_codec_read(codec, nid, 0,
4680 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4681 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4682 if (old_ctl != new_ctl) {
4684 snd_hda_codec_write_cache(codec, nid, 0,
4685 AC_VERB_SET_PIN_WIDGET_CONTROL,
4687 val = ucontrol->value.enumerated.item[0] >= 3 ?
4689 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4696 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4697 struct snd_ctl_elem_info *uinfo)
4699 static const char * const texts[] = {
4700 "Front", "Surround", "CLFE", "Side"
4702 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4704 uinfo->value.enumerated.items = 4;
4705 if (uinfo->value.enumerated.item >= 4)
4706 uinfo->value.enumerated.item = 3;
4707 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4711 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4712 struct snd_ctl_elem_value *ucontrol)
4714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4715 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4718 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4719 ucontrol->value.enumerated.item[0] = sel & 3;
4723 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4724 struct snd_ctl_elem_value *ucontrol)
4726 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4727 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4730 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4731 if (ucontrol->value.enumerated.item[0] != sel) {
4732 sel = ucontrol->value.enumerated.item[0] & 3;
4733 snd_hda_codec_write_cache(codec, nid, 0,
4734 AC_VERB_SET_CONNECT_SEL, sel);
4740 #define PIN_CTL_TEST(xname,nid) { \
4741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4744 .info = alc_test_pin_ctl_info, \
4745 .get = alc_test_pin_ctl_get, \
4746 .put = alc_test_pin_ctl_put, \
4747 .private_value = nid \
4750 #define PIN_SRC_TEST(xname,nid) { \
4751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4753 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4754 .info = alc_test_pin_src_info, \
4755 .get = alc_test_pin_src_get, \
4756 .put = alc_test_pin_src_put, \
4757 .private_value = nid \
4760 static const struct snd_kcontrol_new alc880_test_mixer[] = {
4761 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4762 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4763 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4764 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4765 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4766 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4767 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4768 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4769 PIN_CTL_TEST("Front Pin Mode", 0x14),
4770 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4771 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4772 PIN_CTL_TEST("Side Pin Mode", 0x17),
4773 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4774 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4775 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4776 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4777 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4778 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4779 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4780 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4781 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4782 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4783 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4784 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4785 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4786 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4787 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4788 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4789 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4790 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4793 .name = "Channel Mode",
4794 .info = alc_ch_mode_info,
4795 .get = alc_ch_mode_get,
4796 .put = alc_ch_mode_put,
4801 static const struct hda_verb alc880_test_init_verbs[] = {
4802 /* Unmute inputs of 0x0c - 0x0f */
4803 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4805 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4809 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4811 /* Vol output for 0x0c-0x0f */
4812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4815 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4816 /* Set output pins 0x14-0x17 */
4817 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4818 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4820 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4821 /* Unmute output pins 0x14-0x17 */
4822 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4824 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4825 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4826 /* Set input pins 0x18-0x1c */
4827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4828 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4829 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4830 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4831 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4832 /* Mute input pins 0x18-0x1b */
4833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4834 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4835 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4836 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4839 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4840 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4841 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4842 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4843 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4844 /* Analog input/passthru */
4845 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4857 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4858 [ALC880_3ST] = "3stack",
4859 [ALC880_TCL_S700] = "tcl",
4860 [ALC880_3ST_DIG] = "3stack-digout",
4861 [ALC880_CLEVO] = "clevo",
4862 [ALC880_5ST] = "5stack",
4863 [ALC880_5ST_DIG] = "5stack-digout",
4864 [ALC880_W810] = "w810",
4865 [ALC880_Z71V] = "z71v",
4866 [ALC880_6ST] = "6stack",
4867 [ALC880_6ST_DIG] = "6stack-digout",
4868 [ALC880_ASUS] = "asus",
4869 [ALC880_ASUS_W1V] = "asus-w1v",
4870 [ALC880_ASUS_DIG] = "asus-dig",
4871 [ALC880_ASUS_DIG2] = "asus-dig2",
4872 [ALC880_UNIWILL_DIG] = "uniwill",
4873 [ALC880_UNIWILL_P53] = "uniwill-p53",
4874 [ALC880_FUJITSU] = "fujitsu",
4875 [ALC880_F1734] = "F1734",
4877 [ALC880_LG_LW] = "lg-lw",
4878 [ALC880_MEDION_RIM] = "medion",
4879 #ifdef CONFIG_SND_DEBUG
4880 [ALC880_TEST] = "test",
4882 [ALC880_AUTO] = "auto",
4885 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4886 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4887 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4888 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4889 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4890 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4891 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4892 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4893 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4894 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4895 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4896 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4897 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4898 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4899 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4900 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4901 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4902 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4903 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4904 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4905 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4906 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4907 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4908 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4909 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4910 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4911 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4912 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4913 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4914 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4915 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4916 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4917 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4918 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4919 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4920 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4921 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4922 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4923 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4924 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4925 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4926 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4927 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4928 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4929 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4930 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4931 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4932 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4933 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4934 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4935 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4936 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4937 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4938 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4939 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4940 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4941 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4942 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4943 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4944 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4945 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4946 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4947 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4948 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4949 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4950 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4951 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4952 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4953 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4955 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4956 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4957 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4962 * ALC880 codec presets
4964 static const struct alc_config_preset alc880_presets[] = {
4966 .mixers = { alc880_three_stack_mixer },
4967 .init_verbs = { alc880_volume_init_verbs,
4968 alc880_pin_3stack_init_verbs },
4969 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4970 .dac_nids = alc880_dac_nids,
4971 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4972 .channel_mode = alc880_threestack_modes,
4974 .input_mux = &alc880_capture_source,
4976 [ALC880_3ST_DIG] = {
4977 .mixers = { alc880_three_stack_mixer },
4978 .init_verbs = { alc880_volume_init_verbs,
4979 alc880_pin_3stack_init_verbs },
4980 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4981 .dac_nids = alc880_dac_nids,
4982 .dig_out_nid = ALC880_DIGOUT_NID,
4983 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4984 .channel_mode = alc880_threestack_modes,
4986 .input_mux = &alc880_capture_source,
4988 [ALC880_TCL_S700] = {
4989 .mixers = { alc880_tcl_s700_mixer },
4990 .init_verbs = { alc880_volume_init_verbs,
4991 alc880_pin_tcl_S700_init_verbs,
4992 alc880_gpio2_init_verbs },
4993 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4994 .dac_nids = alc880_dac_nids,
4995 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4996 .num_adc_nids = 1, /* single ADC */
4998 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4999 .channel_mode = alc880_2_jack_modes,
5000 .input_mux = &alc880_capture_source,
5003 .mixers = { alc880_three_stack_mixer,
5004 alc880_five_stack_mixer},
5005 .init_verbs = { alc880_volume_init_verbs,
5006 alc880_pin_5stack_init_verbs },
5007 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5008 .dac_nids = alc880_dac_nids,
5009 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5010 .channel_mode = alc880_fivestack_modes,
5011 .input_mux = &alc880_capture_source,
5013 [ALC880_5ST_DIG] = {
5014 .mixers = { alc880_three_stack_mixer,
5015 alc880_five_stack_mixer },
5016 .init_verbs = { alc880_volume_init_verbs,
5017 alc880_pin_5stack_init_verbs },
5018 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5019 .dac_nids = alc880_dac_nids,
5020 .dig_out_nid = ALC880_DIGOUT_NID,
5021 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5022 .channel_mode = alc880_fivestack_modes,
5023 .input_mux = &alc880_capture_source,
5026 .mixers = { alc880_six_stack_mixer },
5027 .init_verbs = { alc880_volume_init_verbs,
5028 alc880_pin_6stack_init_verbs },
5029 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5030 .dac_nids = alc880_6st_dac_nids,
5031 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5032 .channel_mode = alc880_sixstack_modes,
5033 .input_mux = &alc880_6stack_capture_source,
5035 [ALC880_6ST_DIG] = {
5036 .mixers = { alc880_six_stack_mixer },
5037 .init_verbs = { alc880_volume_init_verbs,
5038 alc880_pin_6stack_init_verbs },
5039 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5040 .dac_nids = alc880_6st_dac_nids,
5041 .dig_out_nid = ALC880_DIGOUT_NID,
5042 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5043 .channel_mode = alc880_sixstack_modes,
5044 .input_mux = &alc880_6stack_capture_source,
5047 .mixers = { alc880_w810_base_mixer },
5048 .init_verbs = { alc880_volume_init_verbs,
5049 alc880_pin_w810_init_verbs,
5050 alc880_gpio2_init_verbs },
5051 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5052 .dac_nids = alc880_w810_dac_nids,
5053 .dig_out_nid = ALC880_DIGOUT_NID,
5054 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5055 .channel_mode = alc880_w810_modes,
5056 .input_mux = &alc880_capture_source,
5059 .mixers = { alc880_z71v_mixer },
5060 .init_verbs = { alc880_volume_init_verbs,
5061 alc880_pin_z71v_init_verbs },
5062 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5063 .dac_nids = alc880_z71v_dac_nids,
5064 .dig_out_nid = ALC880_DIGOUT_NID,
5066 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5067 .channel_mode = alc880_2_jack_modes,
5068 .input_mux = &alc880_capture_source,
5071 .mixers = { alc880_f1734_mixer },
5072 .init_verbs = { alc880_volume_init_verbs,
5073 alc880_pin_f1734_init_verbs },
5074 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5075 .dac_nids = alc880_f1734_dac_nids,
5077 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5078 .channel_mode = alc880_2_jack_modes,
5079 .input_mux = &alc880_f1734_capture_source,
5080 .unsol_event = alc880_uniwill_p53_unsol_event,
5081 .setup = alc880_uniwill_p53_setup,
5082 .init_hook = alc_hp_automute,
5085 .mixers = { alc880_asus_mixer },
5086 .init_verbs = { alc880_volume_init_verbs,
5087 alc880_pin_asus_init_verbs,
5088 alc880_gpio1_init_verbs },
5089 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5090 .dac_nids = alc880_asus_dac_nids,
5091 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5092 .channel_mode = alc880_asus_modes,
5094 .input_mux = &alc880_capture_source,
5096 [ALC880_ASUS_DIG] = {
5097 .mixers = { alc880_asus_mixer },
5098 .init_verbs = { alc880_volume_init_verbs,
5099 alc880_pin_asus_init_verbs,
5100 alc880_gpio1_init_verbs },
5101 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5102 .dac_nids = alc880_asus_dac_nids,
5103 .dig_out_nid = ALC880_DIGOUT_NID,
5104 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5105 .channel_mode = alc880_asus_modes,
5107 .input_mux = &alc880_capture_source,
5109 [ALC880_ASUS_DIG2] = {
5110 .mixers = { alc880_asus_mixer },
5111 .init_verbs = { alc880_volume_init_verbs,
5112 alc880_pin_asus_init_verbs,
5113 alc880_gpio2_init_verbs }, /* use GPIO2 */
5114 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5115 .dac_nids = alc880_asus_dac_nids,
5116 .dig_out_nid = ALC880_DIGOUT_NID,
5117 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5118 .channel_mode = alc880_asus_modes,
5120 .input_mux = &alc880_capture_source,
5122 [ALC880_ASUS_W1V] = {
5123 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5124 .init_verbs = { alc880_volume_init_verbs,
5125 alc880_pin_asus_init_verbs,
5126 alc880_gpio1_init_verbs },
5127 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5128 .dac_nids = alc880_asus_dac_nids,
5129 .dig_out_nid = ALC880_DIGOUT_NID,
5130 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5131 .channel_mode = alc880_asus_modes,
5133 .input_mux = &alc880_capture_source,
5135 [ALC880_UNIWILL_DIG] = {
5136 .mixers = { alc880_asus_mixer },
5137 .init_verbs = { alc880_volume_init_verbs,
5138 alc880_pin_asus_init_verbs },
5139 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5140 .dac_nids = alc880_asus_dac_nids,
5141 .dig_out_nid = ALC880_DIGOUT_NID,
5142 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5143 .channel_mode = alc880_asus_modes,
5145 .input_mux = &alc880_capture_source,
5147 [ALC880_UNIWILL] = {
5148 .mixers = { alc880_uniwill_mixer },
5149 .init_verbs = { alc880_volume_init_verbs,
5150 alc880_uniwill_init_verbs },
5151 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5152 .dac_nids = alc880_asus_dac_nids,
5153 .dig_out_nid = ALC880_DIGOUT_NID,
5154 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5155 .channel_mode = alc880_threestack_modes,
5157 .input_mux = &alc880_capture_source,
5158 .unsol_event = alc880_uniwill_unsol_event,
5159 .setup = alc880_uniwill_setup,
5160 .init_hook = alc880_uniwill_init_hook,
5162 [ALC880_UNIWILL_P53] = {
5163 .mixers = { alc880_uniwill_p53_mixer },
5164 .init_verbs = { alc880_volume_init_verbs,
5165 alc880_uniwill_p53_init_verbs },
5166 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5167 .dac_nids = alc880_asus_dac_nids,
5168 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5169 .channel_mode = alc880_threestack_modes,
5170 .input_mux = &alc880_capture_source,
5171 .unsol_event = alc880_uniwill_p53_unsol_event,
5172 .setup = alc880_uniwill_p53_setup,
5173 .init_hook = alc_hp_automute,
5175 [ALC880_FUJITSU] = {
5176 .mixers = { alc880_fujitsu_mixer },
5177 .init_verbs = { alc880_volume_init_verbs,
5178 alc880_uniwill_p53_init_verbs,
5179 alc880_beep_init_verbs },
5180 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5181 .dac_nids = alc880_dac_nids,
5182 .dig_out_nid = ALC880_DIGOUT_NID,
5183 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5184 .channel_mode = alc880_2_jack_modes,
5185 .input_mux = &alc880_capture_source,
5186 .unsol_event = alc880_uniwill_p53_unsol_event,
5187 .setup = alc880_uniwill_p53_setup,
5188 .init_hook = alc_hp_automute,
5191 .mixers = { alc880_three_stack_mixer },
5192 .init_verbs = { alc880_volume_init_verbs,
5193 alc880_pin_clevo_init_verbs },
5194 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5195 .dac_nids = alc880_dac_nids,
5197 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5198 .channel_mode = alc880_threestack_modes,
5200 .input_mux = &alc880_capture_source,
5203 .mixers = { alc880_lg_mixer },
5204 .init_verbs = { alc880_volume_init_verbs,
5205 alc880_lg_init_verbs },
5206 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5207 .dac_nids = alc880_lg_dac_nids,
5208 .dig_out_nid = ALC880_DIGOUT_NID,
5209 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5210 .channel_mode = alc880_lg_ch_modes,
5212 .input_mux = &alc880_lg_capture_source,
5213 .unsol_event = alc_sku_unsol_event,
5214 .setup = alc880_lg_setup,
5215 .init_hook = alc_hp_automute,
5216 #ifdef CONFIG_SND_HDA_POWER_SAVE
5217 .loopbacks = alc880_lg_loopbacks,
5221 .mixers = { alc880_lg_lw_mixer },
5222 .init_verbs = { alc880_volume_init_verbs,
5223 alc880_lg_lw_init_verbs },
5224 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5225 .dac_nids = alc880_dac_nids,
5226 .dig_out_nid = ALC880_DIGOUT_NID,
5227 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5228 .channel_mode = alc880_lg_lw_modes,
5229 .input_mux = &alc880_lg_lw_capture_source,
5230 .unsol_event = alc_sku_unsol_event,
5231 .setup = alc880_lg_lw_setup,
5232 .init_hook = alc_hp_automute,
5234 [ALC880_MEDION_RIM] = {
5235 .mixers = { alc880_medion_rim_mixer },
5236 .init_verbs = { alc880_volume_init_verbs,
5237 alc880_medion_rim_init_verbs,
5238 alc_gpio2_init_verbs },
5239 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5240 .dac_nids = alc880_dac_nids,
5241 .dig_out_nid = ALC880_DIGOUT_NID,
5242 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5243 .channel_mode = alc880_2_jack_modes,
5244 .input_mux = &alc880_medion_rim_capture_source,
5245 .unsol_event = alc880_medion_rim_unsol_event,
5246 .setup = alc880_medion_rim_setup,
5247 .init_hook = alc880_medion_rim_automute,
5249 #ifdef CONFIG_SND_DEBUG
5251 .mixers = { alc880_test_mixer },
5252 .init_verbs = { alc880_test_init_verbs },
5253 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5254 .dac_nids = alc880_test_dac_nids,
5255 .dig_out_nid = ALC880_DIGOUT_NID,
5256 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5257 .channel_mode = alc880_test_modes,
5258 .input_mux = &alc880_test_capture_source,
5264 * Automatic parse of I/O pins from the BIOS configuration
5269 ALC_CTL_WIDGET_MUTE,
5272 static const struct snd_kcontrol_new alc880_control_templates[] = {
5273 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5274 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5275 HDA_BIND_MUTE(NULL, 0, 0, 0),
5278 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5280 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5281 return snd_array_new(&spec->kctls);
5284 /* add dynamic controls */
5285 static int add_control(struct alc_spec *spec, int type, const char *name,
5286 int cidx, unsigned long val)
5288 struct snd_kcontrol_new *knew;
5290 knew = alc_kcontrol_new(spec);
5293 *knew = alc880_control_templates[type];
5294 knew->name = kstrdup(name, GFP_KERNEL);
5298 if (get_amp_nid_(val))
5299 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5300 knew->private_value = val;
5304 static int add_control_with_pfx(struct alc_spec *spec, int type,
5305 const char *pfx, const char *dir,
5306 const char *sfx, int cidx, unsigned long val)
5309 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5310 return add_control(spec, type, name, cidx, val);
5313 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5314 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5315 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5316 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5317 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5318 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5319 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5320 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5322 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5323 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5324 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5325 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5326 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5327 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5328 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5329 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5330 #define ALC880_PIN_CD_NID 0x1c
5332 /* fill in the dac_nids table from the parsed pin configuration */
5333 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5334 const struct auto_pin_cfg *cfg)
5340 memset(assigned, 0, sizeof(assigned));
5341 spec->multiout.dac_nids = spec->private_dac_nids;
5343 /* check the pins hardwired to audio widget */
5344 for (i = 0; i < cfg->line_outs; i++) {
5345 nid = cfg->line_out_pins[i];
5346 if (alc880_is_fixed_pin(nid)) {
5347 int idx = alc880_fixed_pin_idx(nid);
5348 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5352 /* left pins can be connect to any audio widget */
5353 for (i = 0; i < cfg->line_outs; i++) {
5354 nid = cfg->line_out_pins[i];
5355 if (alc880_is_fixed_pin(nid))
5357 /* search for an empty channel */
5358 for (j = 0; j < cfg->line_outs; j++) {
5360 spec->private_dac_nids[i] =
5361 alc880_idx_to_dac(j);
5367 spec->multiout.num_dacs = cfg->line_outs;
5371 static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5372 bool can_be_master, int *index)
5374 struct auto_pin_cfg *cfg = &spec->autocfg;
5375 static const char * const chname[4] = {
5376 "Front", "Surround", NULL /*CLFE*/, "Side"
5380 if (cfg->line_outs == 1 && !spec->multi_ios &&
5381 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5384 switch (cfg->line_out_type) {
5385 case AUTO_PIN_SPEAKER_OUT:
5386 if (cfg->line_outs == 1)
5389 case AUTO_PIN_HP_OUT:
5390 /* for multi-io case, only the primary out */
5391 if (ch && spec->multi_ios)
5396 if (cfg->line_outs == 1 && !spec->multi_ios)
5403 /* add playback controls from the parsed DAC table */
5404 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5405 const struct auto_pin_cfg *cfg)
5408 int i, err, noutputs;
5410 noutputs = cfg->line_outs;
5411 if (spec->multi_ios > 0)
5412 noutputs += spec->multi_ios;
5414 for (i = 0; i < noutputs; i++) {
5417 if (!spec->multiout.dac_nids[i])
5419 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5420 name = alc_get_line_out_pfx(spec, i, false, &index);
5423 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5425 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5429 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5431 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5435 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5437 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5441 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5443 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5448 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5450 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5454 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5456 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5465 /* add playback controls for speaker and HP outputs */
5466 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5475 if (alc880_is_fixed_pin(pin)) {
5476 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5477 /* specify the DAC as the extra output */
5478 if (!spec->multiout.hp_nid)
5479 spec->multiout.hp_nid = nid;
5481 spec->multiout.extra_out_nid[0] = nid;
5482 /* control HP volume/switch on the output mixer amp */
5483 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5484 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5485 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5488 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5489 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5492 } else if (alc880_is_multi_pin(pin)) {
5493 /* set manual connection */
5494 /* we have only a switch on HP-out PIN */
5495 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5496 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5503 /* create input playback/capture controls for the given pin */
5504 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5505 const char *ctlname, int ctlidx,
5506 int idx, hda_nid_t mix_nid)
5510 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5511 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5514 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5515 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5521 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5523 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5524 return (pincap & AC_PINCAP_IN) != 0;
5527 /* create playback/capture controls for input pins */
5528 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5529 const struct auto_pin_cfg *cfg,
5531 hda_nid_t cap1, hda_nid_t cap2)
5533 struct alc_spec *spec = codec->spec;
5534 struct hda_input_mux *imux = &spec->private_imux[0];
5535 int i, err, idx, type_idx = 0;
5536 const char *prev_label = NULL;
5538 for (i = 0; i < cfg->num_inputs; i++) {
5542 pin = cfg->inputs[i].pin;
5543 if (!alc_is_input_pin(codec, pin))
5546 label = hda_get_autocfg_input_label(codec, cfg, i);
5547 if (prev_label && !strcmp(label, prev_label))
5554 idx = get_connection_index(codec, mixer, pin);
5556 err = new_analog_input(spec, pin,
5566 idx = get_connection_index(codec, cap1, pin);
5567 if (idx < 0 && cap2)
5568 idx = get_connection_index(codec, cap2, pin);
5570 snd_hda_add_imux_item(imux, label, idx, NULL);
5575 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5576 const struct auto_pin_cfg *cfg)
5578 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5581 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5582 unsigned int pin_type)
5584 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5587 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5591 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5592 hda_nid_t nid, int pin_type,
5595 alc_set_pin_output(codec, nid, pin_type);
5596 /* need the manual connection? */
5597 if (alc880_is_multi_pin(nid)) {
5598 struct alc_spec *spec = codec->spec;
5599 int idx = alc880_multi_pin_idx(nid);
5600 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5601 AC_VERB_SET_CONNECT_SEL,
5602 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5606 static int get_pin_type(int line_out_type)
5608 if (line_out_type == AUTO_PIN_HP_OUT)
5614 static void alc880_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
5618 nid = alc880_idx_to_mixer(alc880_dac_to_idx(nid));
5619 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5621 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5623 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5627 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5629 struct alc_spec *spec = codec->spec;
5632 for (i = 0; i < spec->autocfg.line_outs; i++) {
5633 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5634 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5635 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5638 for (i = 0; i < spec->multiout.num_dacs; i++)
5639 alc880_auto_init_dac(codec, spec->multiout.dac_nids[i]);
5642 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5644 struct alc_spec *spec = codec->spec;
5648 pin = spec->autocfg.speaker_pins[0];
5649 if (pin) /* connect to front */
5650 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5651 pin = spec->autocfg.hp_pins[0];
5652 if (pin) /* connect to front */
5653 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5655 alc880_auto_init_dac(codec, spec->multiout.hp_nid);
5656 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
5657 alc880_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
5660 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5662 struct alc_spec *spec = codec->spec;
5663 struct auto_pin_cfg *cfg = &spec->autocfg;
5666 for (i = 0; i < cfg->num_inputs; i++) {
5667 hda_nid_t nid = cfg->inputs[i].pin;
5668 if (alc_is_input_pin(codec, nid)) {
5669 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5670 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
5671 snd_hda_codec_write(codec, nid, 0,
5672 AC_VERB_SET_AMP_GAIN_MUTE,
5677 /* mute all loopback inputs */
5678 if (spec->mixer_nid) {
5679 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5680 for (i = 0; i < nums; i++)
5681 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5682 AC_VERB_SET_AMP_GAIN_MUTE,
5687 static void alc880_auto_init_input_src(struct hda_codec *codec)
5689 struct alc_spec *spec = codec->spec;
5692 for (c = 0; c < spec->num_adc_nids; c++) {
5693 unsigned int mux_idx;
5694 const struct hda_input_mux *imux;
5695 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5696 imux = &spec->input_mux[mux_idx];
5697 if (!imux->num_items && mux_idx > 0)
5698 imux = &spec->input_mux[0];
5700 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5701 AC_VERB_SET_CONNECT_SEL,
5702 imux->items[0].index);
5703 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5704 AC_VERB_SET_AMP_GAIN_MUTE,
5709 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5711 /* parse the BIOS configuration and set up the alc_spec */
5712 /* return 1 if successful, 0 if the proper config is not found,
5713 * or a negative error code
5715 static int alc880_parse_auto_config(struct hda_codec *codec)
5717 struct alc_spec *spec = codec->spec;
5719 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5721 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5725 if (!spec->autocfg.line_outs)
5726 return 0; /* can't find valid BIOS pin config */
5728 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5731 err = alc_auto_add_multi_channel_mode(codec);
5734 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5737 err = alc880_auto_create_extra_out(spec,
5738 spec->autocfg.speaker_pins[0],
5742 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5746 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5750 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5752 alc_auto_parse_digital(codec);
5754 if (spec->kctls.list)
5755 add_mixer(spec, spec->kctls.list);
5757 spec->num_mux_defs = 1;
5758 spec->input_mux = &spec->private_imux[0];
5760 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5765 /* additional initialization for auto-configuration model */
5766 static void alc880_auto_init(struct hda_codec *codec)
5768 struct alc_spec *spec = codec->spec;
5769 alc880_auto_init_multi_out(codec);
5770 alc880_auto_init_extra_out(codec);
5771 alc880_auto_init_analog_input(codec);
5772 alc880_auto_init_input_src(codec);
5773 alc_auto_init_digital(codec);
5774 if (spec->unsol_event)
5775 alc_inithook(codec);
5778 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5779 * one of two digital mic pins, e.g. on ALC272
5781 static void fixup_automic_adc(struct hda_codec *codec)
5783 struct alc_spec *spec = codec->spec;
5786 for (i = 0; i < spec->num_adc_nids; i++) {
5787 hda_nid_t cap = spec->capsrc_nids ?
5788 spec->capsrc_nids[i] : spec->adc_nids[i];
5791 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5794 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5797 spec->int_mic.mux_idx = iidx;
5798 spec->ext_mic.mux_idx = eidx;
5799 if (spec->capsrc_nids)
5800 spec->capsrc_nids += i;
5801 spec->adc_nids += i;
5802 spec->num_adc_nids = 1;
5803 /* optional dock-mic */
5804 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5806 spec->dock_mic.pin = 0;
5808 spec->dock_mic.mux_idx = eidx;
5811 snd_printd(KERN_INFO "hda_codec: %s: "
5812 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5813 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5814 spec->auto_mic = 0; /* disable auto-mic to be sure */
5817 /* select or unmute the given capsrc route */
5818 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5821 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5822 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5825 snd_hda_codec_write_cache(codec, cap, 0,
5826 AC_VERB_SET_CONNECT_SEL, idx);
5830 /* set the default connection to that pin */
5831 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5833 struct alc_spec *spec = codec->spec;
5838 for (i = 0; i < spec->num_adc_nids; i++) {
5839 hda_nid_t cap = spec->capsrc_nids ?
5840 spec->capsrc_nids[i] : spec->adc_nids[i];
5843 idx = get_connection_index(codec, cap, pin);
5846 select_or_unmute_capsrc(codec, cap, idx);
5847 return i; /* return the found index */
5849 return -1; /* not found */
5852 /* choose the ADC/MUX containing the input pin and initialize the setup */
5853 static void fixup_single_adc(struct hda_codec *codec)
5855 struct alc_spec *spec = codec->spec;
5856 struct auto_pin_cfg *cfg = &spec->autocfg;
5859 /* search for the input pin; there must be only one */
5860 if (cfg->num_inputs != 1)
5862 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5864 /* use only this ADC */
5865 if (spec->capsrc_nids)
5866 spec->capsrc_nids += i;
5867 spec->adc_nids += i;
5868 spec->num_adc_nids = 1;
5869 spec->single_input_src = 1;
5873 /* initialize dual adcs */
5874 static void fixup_dual_adc_switch(struct hda_codec *codec)
5876 struct alc_spec *spec = codec->spec;
5877 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5878 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5879 init_capsrc_for_pin(codec, spec->int_mic.pin);
5882 /* initialize some special cases for input sources */
5883 static void alc_init_special_input_src(struct hda_codec *codec)
5885 struct alc_spec *spec = codec->spec;
5886 if (spec->dual_adc_switch)
5887 fixup_dual_adc_switch(codec);
5888 else if (spec->single_input_src)
5889 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5892 static void set_capture_mixer(struct hda_codec *codec)
5894 struct alc_spec *spec = codec->spec;
5895 static const struct snd_kcontrol_new *caps[2][3] = {
5896 { alc_capture_mixer_nosrc1,
5897 alc_capture_mixer_nosrc2,
5898 alc_capture_mixer_nosrc3 },
5899 { alc_capture_mixer1,
5901 alc_capture_mixer3 },
5903 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5905 int num_adcs = spec->num_adc_nids;
5906 if (spec->dual_adc_switch)
5908 else if (spec->auto_mic)
5909 fixup_automic_adc(codec);
5910 else if (spec->input_mux) {
5911 if (spec->input_mux->num_items > 1)
5913 else if (spec->input_mux->num_items == 1)
5914 fixup_single_adc(codec);
5916 spec->cap_mixer = caps[mux][num_adcs - 1];
5920 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5921 static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5924 struct alc_spec *spec = codec->spec;
5925 struct auto_pin_cfg *cfg = &spec->autocfg;
5927 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5929 for (n = 0; n < num_nids; n++) {
5931 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5935 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5938 nconns = snd_hda_get_connections(codec, cap, conn,
5942 nconns = snd_hda_get_connections(codec, cap, conn,
5947 if (!fallback_adc) {
5951 for (i = 0; i < cfg->num_inputs; i++) {
5952 hda_nid_t nid = cfg->inputs[i].pin;
5953 for (j = 0; j < nconns; j++) {
5960 if (i >= cfg->num_inputs) {
5961 int num_adcs = spec->num_adc_nids;
5962 spec->private_adc_nids[num_adcs] = adc;
5963 spec->private_capsrc_nids[num_adcs] = cap;
5964 spec->num_adc_nids++;
5965 spec->adc_nids = spec->private_adc_nids;
5967 spec->capsrc_nids = spec->private_capsrc_nids;
5970 if (!spec->num_adc_nids) {
5971 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5972 " using fallback 0x%x\n",
5973 codec->chip_name, fallback_adc);
5974 spec->private_adc_nids[0] = fallback_adc;
5975 spec->adc_nids = spec->private_adc_nids;
5976 if (fallback_adc != fallback_cap) {
5977 spec->private_capsrc_nids[0] = fallback_cap;
5978 spec->capsrc_nids = spec->private_adc_nids;
5983 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5984 #define set_beep_amp(spec, nid, idx, dir) \
5985 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5987 static const struct snd_pci_quirk beep_white_list[] = {
5988 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5989 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5990 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5991 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5992 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5996 static inline int has_cdefine_beep(struct hda_codec *codec)
5998 struct alc_spec *spec = codec->spec;
5999 const struct snd_pci_quirk *q;
6000 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
6003 return spec->cdefine.enable_pcbeep;
6006 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
6007 #define has_cdefine_beep(codec) 0
6011 * OK, here we have finally the patch for ALC880
6014 static int patch_alc880(struct hda_codec *codec)
6016 struct alc_spec *spec;
6020 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6026 spec->mixer_nid = 0x0b;
6028 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
6031 if (board_config < 0) {
6032 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6034 board_config = ALC880_AUTO;
6037 if (board_config == ALC880_AUTO) {
6038 /* automatic parse from the BIOS config */
6039 err = alc880_parse_auto_config(codec);
6045 "hda_codec: Cannot set up configuration "
6046 "from BIOS. Using 3-stack mode...\n");
6047 board_config = ALC880_3ST;
6051 err = snd_hda_attach_beep_device(codec, 0x1);
6057 if (board_config != ALC880_AUTO)
6058 setup_preset(codec, &alc880_presets[board_config]);
6060 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6061 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6062 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6064 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6065 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6067 if (!spec->adc_nids && spec->input_mux) {
6068 /* check whether NID 0x07 is valid */
6069 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6071 wcap = get_wcaps_type(wcap);
6072 if (wcap != AC_WID_AUD_IN) {
6073 spec->adc_nids = alc880_adc_nids_alt;
6074 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6076 spec->adc_nids = alc880_adc_nids;
6077 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6080 set_capture_mixer(codec);
6081 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6083 spec->vmaster_nid = 0x0c;
6085 codec->patch_ops = alc_patch_ops;
6086 if (board_config == ALC880_AUTO)
6087 spec->init_hook = alc880_auto_init;
6088 #ifdef CONFIG_SND_HDA_POWER_SAVE
6089 if (!spec->loopback.amplist)
6090 spec->loopback.amplist = alc880_loopbacks;
6101 static const hda_nid_t alc260_dac_nids[1] = {
6106 static const hda_nid_t alc260_adc_nids[1] = {
6111 static const hda_nid_t alc260_adc_nids_alt[1] = {
6116 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
6117 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6119 static const hda_nid_t alc260_dual_adc_nids[2] = {
6124 #define ALC260_DIGOUT_NID 0x03
6125 #define ALC260_DIGIN_NID 0x06
6127 static const struct hda_input_mux alc260_capture_source = {
6131 { "Front Mic", 0x1 },
6137 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6138 * headphone jack and the internal CD lines since these are the only pins at
6139 * which audio can appear. For flexibility, also allow the option of
6140 * recording the mixer output on the second ADC (ADC0 doesn't have a
6141 * connection to the mixer output).
6143 static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6147 { "Mic/Line", 0x0 },
6149 { "Headphone", 0x2 },
6155 { "Mic/Line", 0x0 },
6157 { "Headphone", 0x2 },
6164 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6165 * the Fujitsu S702x, but jacks are marked differently.
6167 static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6174 { "Headphone", 0x5 },
6183 { "Headphone", 0x6 },
6189 /* Maxdata Favorit 100XS */
6190 static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6194 { "Line/Mic", 0x0 },
6201 { "Line/Mic", 0x0 },
6209 * This is just place-holder, so there's something for alc_build_pcms to look
6210 * at when it calculates the maximum number of channels. ALC260 has no mixer
6211 * element which allows changing the channel mode, so the verb list is
6214 static const struct hda_channel_mode alc260_modes[1] = {
6219 /* Mixer combinations
6221 * basic: base_output + input + pc_beep + capture
6222 * HP: base_output + input + capture_alt
6223 * HP_3013: hp_3013 + input + capture
6224 * fujitsu: fujitsu + capture
6225 * acer: acer + capture
6228 static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6229 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6230 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6231 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6232 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6233 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6234 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6238 static const struct snd_kcontrol_new alc260_input_mixer[] = {
6239 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6240 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6241 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6242 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6244 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6245 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6246 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6250 /* update HP, line and mono out pins according to the master switch */
6251 static void alc260_hp_master_update(struct hda_codec *codec)
6253 update_speakers(codec);
6256 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6257 struct snd_ctl_elem_value *ucontrol)
6259 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6260 struct alc_spec *spec = codec->spec;
6261 *ucontrol->value.integer.value = !spec->master_mute;
6265 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6266 struct snd_ctl_elem_value *ucontrol)
6268 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6269 struct alc_spec *spec = codec->spec;
6270 int val = !*ucontrol->value.integer.value;
6272 if (val == spec->master_mute)
6274 spec->master_mute = val;
6275 alc260_hp_master_update(codec);
6279 static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6281 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6282 .name = "Master Playback Switch",
6283 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6284 .info = snd_ctl_boolean_mono_info,
6285 .get = alc260_hp_master_sw_get,
6286 .put = alc260_hp_master_sw_put,
6288 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6289 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6291 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6292 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6294 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6298 static const struct hda_verb alc260_hp_unsol_verbs[] = {
6299 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6303 static void alc260_hp_setup(struct hda_codec *codec)
6305 struct alc_spec *spec = codec->spec;
6307 spec->autocfg.hp_pins[0] = 0x0f;
6308 spec->autocfg.speaker_pins[0] = 0x10;
6309 spec->autocfg.speaker_pins[1] = 0x11;
6311 spec->automute_mode = ALC_AUTOMUTE_PIN;
6314 static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6317 .name = "Master Playback Switch",
6318 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6319 .info = snd_ctl_boolean_mono_info,
6320 .get = alc260_hp_master_sw_get,
6321 .put = alc260_hp_master_sw_put,
6323 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6324 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6325 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6326 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6327 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6329 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6330 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6334 static void alc260_hp_3013_setup(struct hda_codec *codec)
6336 struct alc_spec *spec = codec->spec;
6338 spec->autocfg.hp_pins[0] = 0x15;
6339 spec->autocfg.speaker_pins[0] = 0x10;
6340 spec->autocfg.speaker_pins[1] = 0x11;
6342 spec->automute_mode = ALC_AUTOMUTE_PIN;
6345 static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6346 .ops = &snd_hda_bind_vol,
6348 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6349 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6350 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6355 static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6356 .ops = &snd_hda_bind_sw,
6358 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6359 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6364 static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6365 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6366 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6367 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6368 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6372 static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6373 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6377 static void alc260_hp_3012_setup(struct hda_codec *codec)
6379 struct alc_spec *spec = codec->spec;
6381 spec->autocfg.hp_pins[0] = 0x10;
6382 spec->autocfg.speaker_pins[0] = 0x0f;
6383 spec->autocfg.speaker_pins[1] = 0x11;
6384 spec->autocfg.speaker_pins[2] = 0x15;
6386 spec->automute_mode = ALC_AUTOMUTE_PIN;
6389 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6390 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6392 static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6393 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6394 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6395 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6396 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6397 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6398 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6399 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6400 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6401 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6402 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6406 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6407 * versions of the ALC260 don't act on requests to enable mic bias from NID
6408 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6409 * datasheet doesn't mention this restriction. At this stage it's not clear
6410 * whether this behaviour is intentional or is a hardware bug in chip
6411 * revisions available in early 2006. Therefore for now allow the
6412 * "Headphone Jack Mode" control to span all choices, but if it turns out
6413 * that the lack of mic bias for this NID is intentional we could change the
6414 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6416 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6417 * don't appear to make the mic bias available from the "line" jack, even
6418 * though the NID used for this jack (0x14) can supply it. The theory is
6419 * that perhaps Acer have included blocking capacitors between the ALC260
6420 * and the output jack. If this turns out to be the case for all such
6421 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6422 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6424 * The C20x Tablet series have a mono internal speaker which is controlled
6425 * via the chip's Mono sum widget and pin complex, so include the necessary
6426 * controls for such models. On models without a "mono speaker" the control
6427 * won't do anything.
6429 static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6430 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6431 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6432 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6433 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6435 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6437 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6438 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6440 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6441 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6442 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6443 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6444 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6448 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6450 static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6451 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6452 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6453 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6454 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6455 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6456 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6460 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6461 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6463 static const struct snd_kcontrol_new alc260_will_mixer[] = {
6464 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6465 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6467 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6468 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6469 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6470 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6471 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6472 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6473 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6477 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6478 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6480 static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6481 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6482 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6484 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6485 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6486 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6487 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6488 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6489 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6490 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6495 * initialization verbs
6497 static const struct hda_verb alc260_init_verbs[] = {
6498 /* Line In pin widget for input */
6499 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6500 /* CD pin widget for input */
6501 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6502 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6503 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6504 /* Mic2 (front panel) pin widget for input and vref at 80% */
6505 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6506 /* LINE-2 is used for line-out in rear */
6507 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6508 /* select line-out */
6509 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6511 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6513 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6515 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6516 /* mute capture amp left and right */
6517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6518 /* set connection select to line in (default select for this ADC) */
6519 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6520 /* mute capture amp left and right */
6521 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6522 /* set connection select to line in (default select for this ADC) */
6523 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6524 /* set vol=0 Line-Out mixer amp left and right */
6525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6526 /* unmute pin widget amp left and right (no gain on this amp) */
6527 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6528 /* set vol=0 HP mixer amp left and right */
6529 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6530 /* unmute pin widget amp left and right (no gain on this amp) */
6531 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6532 /* set vol=0 Mono mixer amp left and right */
6533 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6534 /* unmute pin widget amp left and right (no gain on this amp) */
6535 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6536 /* unmute LINE-2 out pin */
6537 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6538 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6541 /* mute analog inputs */
6542 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6543 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6544 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6545 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6547 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6548 /* mute Front out path */
6549 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6551 /* mute Headphone out path */
6552 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6553 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6554 /* mute Mono out path */
6555 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6556 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6560 #if 0 /* should be identical with alc260_init_verbs? */
6561 static const struct hda_verb alc260_hp_init_verbs[] = {
6562 /* Headphone and output */
6563 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6565 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6566 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6567 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6568 /* Mic2 (front panel) pin widget for input and vref at 80% */
6569 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6570 /* Line In pin widget for input */
6571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6572 /* Line-2 pin widget for output */
6573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6574 /* CD pin widget for input */
6575 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6576 /* unmute amp left and right */
6577 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6578 /* set connection select to line in (default select for this ADC) */
6579 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6580 /* unmute Line-Out mixer amp left and right (volume = 0) */
6581 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6582 /* mute pin widget amp left and right (no gain on this amp) */
6583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6584 /* unmute HP mixer amp left and right (volume = 0) */
6585 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6586 /* mute pin widget amp left and right (no gain on this amp) */
6587 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6588 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6591 /* mute analog inputs */
6592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6596 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6597 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6598 /* Unmute Front out path */
6599 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6600 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6601 /* Unmute Headphone out path */
6602 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6603 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6604 /* Unmute Mono out path */
6605 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6611 static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6612 /* Line out and output */
6613 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6615 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6616 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6617 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6618 /* Mic2 (front panel) pin widget for input and vref at 80% */
6619 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6620 /* Line In pin widget for input */
6621 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6622 /* Headphone pin widget for output */
6623 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6624 /* CD pin widget for input */
6625 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6626 /* unmute amp left and right */
6627 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6628 /* set connection select to line in (default select for this ADC) */
6629 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6630 /* unmute Line-Out mixer amp left and right (volume = 0) */
6631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6632 /* mute pin widget amp left and right (no gain on this amp) */
6633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6634 /* unmute HP mixer amp left and right (volume = 0) */
6635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6636 /* mute pin widget amp left and right (no gain on this amp) */
6637 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6638 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6641 /* mute analog inputs */
6642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6645 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6646 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6647 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6648 /* Unmute Front out path */
6649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6651 /* Unmute Headphone out path */
6652 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6654 /* Unmute Mono out path */
6655 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6656 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6660 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6661 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6662 * audio = 0x16, internal speaker = 0x10.
6664 static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6665 /* Disable all GPIOs */
6666 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6667 /* Internal speaker is connected to headphone pin */
6668 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6669 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6671 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6672 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6673 /* Ensure all other unused pins are disabled and muted. */
6674 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6675 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6676 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6677 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6678 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6679 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6683 /* Disable digital (SPDIF) pins */
6684 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6685 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6687 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6688 * when acting as an output.
6690 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6692 /* Start with output sum widgets muted and their output gains at min */
6693 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6694 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6695 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6696 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6697 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6698 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6699 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6700 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6701 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6703 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6704 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6705 /* Unmute Line1 pin widget output buffer since it starts as an output.
6706 * If the pin mode is changed by the user the pin mode control will
6707 * take care of enabling the pin's input/output buffers as needed.
6708 * Therefore there's no need to enable the input buffer at this
6711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6712 /* Unmute input buffer of pin widget used for Line-in (no equiv
6715 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6717 /* Mute capture amp left and right */
6718 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6719 /* Set ADC connection select to match default mixer setting - line
6722 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6724 /* Do the same for the second ADC: mute capture input amp and
6725 * set ADC connection to line in (on mic1 pin)
6727 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6728 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6730 /* Mute all inputs to mixer widget (even unconnected ones) */
6731 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6732 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6734 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6743 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6744 * similar laptops (adapted from Fujitsu init verbs).
6746 static const struct hda_verb alc260_acer_init_verbs[] = {
6747 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6748 * the headphone jack. Turn this on and rely on the standard mute
6749 * methods whenever the user wants to turn these outputs off.
6751 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6752 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6753 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6754 /* Internal speaker/Headphone jack is connected to Line-out pin */
6755 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6756 /* Internal microphone/Mic jack is connected to Mic1 pin */
6757 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6758 /* Line In jack is connected to Line1 pin */
6759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6760 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6761 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6762 /* Ensure all other unused pins are disabled and muted. */
6763 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6764 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6765 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6766 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6767 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6769 /* Disable digital (SPDIF) pins */
6770 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6771 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6773 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6774 * bus when acting as outputs.
6776 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6777 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6779 /* Start with output sum widgets muted and their output gains at min */
6780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6781 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6782 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6783 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6785 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6786 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6790 /* Unmute Line-out pin widget amp left and right
6791 * (no equiv mixer ctrl)
6793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6794 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6795 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6796 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6797 * inputs. If the pin mode is changed by the user the pin mode control
6798 * will take care of enabling the pin's input/output buffers as needed.
6799 * Therefore there's no need to enable the input buffer at this
6802 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6803 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6805 /* Mute capture amp left and right */
6806 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6807 /* Set ADC connection select to match default mixer setting - mic
6810 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6812 /* Do similar with the second ADC: mute capture input amp and
6813 * set ADC connection to mic to match ALSA's default state.
6815 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6816 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6818 /* Mute all inputs to mixer widget (even unconnected ones) */
6819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6831 /* Initialisation sequence for Maxdata Favorit 100XS
6832 * (adapted from Acer init verbs).
6834 static const struct hda_verb alc260_favorit100_init_verbs[] = {
6835 /* GPIO 0 enables the output jack.
6836 * Turn this on and rely on the standard mute
6837 * methods whenever the user wants to turn these outputs off.
6839 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6840 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6841 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6842 /* Line/Mic input jack is connected to Mic1 pin */
6843 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6844 /* Ensure all other unused pins are disabled and muted. */
6845 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6846 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6847 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6848 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6849 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6850 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 /* Disable digital (SPDIF) pins */
6856 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6857 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6859 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6860 * bus when acting as outputs.
6862 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6863 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6865 /* Start with output sum widgets muted and their output gains at min */
6866 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6867 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6869 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6870 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6873 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6874 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6876 /* Unmute Line-out pin widget amp left and right
6877 * (no equiv mixer ctrl)
6879 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6880 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6881 * inputs. If the pin mode is changed by the user the pin mode control
6882 * will take care of enabling the pin's input/output buffers as needed.
6883 * Therefore there's no need to enable the input buffer at this
6886 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6888 /* Mute capture amp left and right */
6889 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6890 /* Set ADC connection select to match default mixer setting - mic
6893 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6895 /* Do similar with the second ADC: mute capture input amp and
6896 * set ADC connection to mic to match ALSA's default state.
6898 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6899 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6901 /* Mute all inputs to mixer widget (even unconnected ones) */
6902 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6903 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6904 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6906 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6914 static const struct hda_verb alc260_will_verbs[] = {
6915 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6916 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6917 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6918 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6919 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6920 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6924 static const struct hda_verb alc260_replacer_672v_verbs[] = {
6925 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6926 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6927 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6929 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6930 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6931 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6933 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6937 /* toggle speaker-output according to the hp-jack state */
6938 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6940 unsigned int present;
6942 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6943 present = snd_hda_jack_detect(codec, 0x0f);
6945 snd_hda_codec_write_cache(codec, 0x01, 0,
6946 AC_VERB_SET_GPIO_DATA, 1);
6947 snd_hda_codec_write_cache(codec, 0x0f, 0,
6948 AC_VERB_SET_PIN_WIDGET_CONTROL,
6951 snd_hda_codec_write_cache(codec, 0x01, 0,
6952 AC_VERB_SET_GPIO_DATA, 0);
6953 snd_hda_codec_write_cache(codec, 0x0f, 0,
6954 AC_VERB_SET_PIN_WIDGET_CONTROL,
6959 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6962 if ((res >> 26) == ALC880_HP_EVENT)
6963 alc260_replacer_672v_automute(codec);
6966 static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6967 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6969 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6970 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6971 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6973 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6974 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6975 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6976 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6980 /* Test configuration for debugging, modelled after the ALC880 test
6983 #ifdef CONFIG_SND_DEBUG
6984 static const hda_nid_t alc260_test_dac_nids[1] = {
6987 static const hda_nid_t alc260_test_adc_nids[2] = {
6990 /* For testing the ALC260, each input MUX needs its own definition since
6991 * the signal assignments are different. This assumes that the first ADC
6994 static const struct hda_input_mux alc260_test_capture_sources[2] = {
6998 { "MIC1 pin", 0x0 },
6999 { "MIC2 pin", 0x1 },
7000 { "LINE1 pin", 0x2 },
7001 { "LINE2 pin", 0x3 },
7003 { "LINE-OUT pin", 0x5 },
7004 { "HP-OUT pin", 0x6 },
7010 { "MIC1 pin", 0x0 },
7011 { "MIC2 pin", 0x1 },
7012 { "LINE1 pin", 0x2 },
7013 { "LINE2 pin", 0x3 },
7016 { "LINE-OUT pin", 0x6 },
7017 { "HP-OUT pin", 0x7 },
7021 static const struct snd_kcontrol_new alc260_test_mixer[] = {
7022 /* Output driver widgets */
7023 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
7024 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
7025 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
7026 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
7027 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
7028 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
7030 /* Modes for retasking pin widgets
7031 * Note: the ALC260 doesn't seem to act on requests to enable mic
7032 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
7033 * mention this restriction. At this stage it's not clear whether
7034 * this behaviour is intentional or is a hardware bug in chip
7035 * revisions available at least up until early 2006. Therefore for
7036 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7037 * choices, but if it turns out that the lack of mic bias for these
7038 * NIDs is intentional we could change their modes from
7039 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7041 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7042 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7043 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7044 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7045 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7046 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7048 /* Loopback mixer controls */
7049 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7050 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7051 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7052 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7053 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7054 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7055 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7056 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7057 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7058 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7059 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7060 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7061 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7062 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7064 /* Controls for GPIO pins, assuming they are configured as outputs */
7065 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7066 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7067 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7068 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7070 /* Switches to allow the digital IO pins to be enabled. The datasheet
7071 * is ambigious as to which NID is which; testing on laptops which
7072 * make this output available should provide clarification.
7074 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7075 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7077 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7078 * this output to turn on an external amplifier.
7080 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7081 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7085 static const struct hda_verb alc260_test_init_verbs[] = {
7086 /* Enable all GPIOs as outputs with an initial value of 0 */
7087 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7088 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7089 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7091 /* Enable retasking pins as output, initially without power amp */
7092 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7093 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7094 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7095 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7096 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7097 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7099 /* Disable digital (SPDIF) pins initially, but users can enable
7100 * them via a mixer switch. In the case of SPDIF-out, this initverb
7101 * payload also sets the generation to 0, output to be in "consumer"
7102 * PCM format, copyright asserted, no pre-emphasis and no validity
7105 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7106 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7108 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7109 * OUT1 sum bus when acting as an output.
7111 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7112 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7113 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7114 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7116 /* Start with output sum widgets muted and their output gains at min */
7117 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7118 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7119 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7120 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7122 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7123 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7124 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7125 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7127 /* Unmute retasking pin widget output buffers since the default
7128 * state appears to be output. As the pin mode is changed by the
7129 * user the pin mode control will take care of enabling the pin's
7130 * input/output buffers as needed.
7132 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7133 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7135 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7136 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7137 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7138 /* Also unmute the mono-out pin widget */
7139 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7141 /* Mute capture amp left and right */
7142 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7143 /* Set ADC connection select to match default mixer setting (mic1
7146 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7148 /* Do the same for the second ADC: mute capture input amp and
7149 * set ADC connection to mic1 pin
7151 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7152 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7154 /* Mute all inputs to mixer widget (even unconnected ones) */
7155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7158 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7159 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7168 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7169 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
7171 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
7172 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
7175 * for BIOS auto-configuration
7178 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7179 const char *pfx, int *vol_bits)
7182 unsigned long vol_val, sw_val;
7185 if (nid >= 0x0f && nid < 0x11) {
7186 nid_vol = nid - 0x7;
7187 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7188 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7189 } else if (nid == 0x11) {
7190 nid_vol = nid - 0x7;
7191 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7192 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7193 } else if (nid >= 0x12 && nid <= 0x15) {
7195 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7196 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7200 if (!(*vol_bits & (1 << nid_vol))) {
7201 /* first control for the volume widget */
7202 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7205 *vol_bits |= (1 << nid_vol);
7207 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7213 /* add playback controls from the parsed DAC table */
7214 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7215 const struct auto_pin_cfg *cfg)
7221 spec->multiout.num_dacs = 1;
7222 spec->multiout.dac_nids = spec->private_dac_nids;
7223 spec->private_dac_nids[0] = 0x02;
7225 nid = cfg->line_out_pins[0];
7229 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
7230 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7235 nid = cfg->speaker_pins[0];
7237 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7242 nid = cfg->hp_pins[0];
7244 err = alc260_add_playback_controls(spec, nid, "Headphone",
7252 /* create playback/capture controls for input pins */
7253 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
7254 const struct auto_pin_cfg *cfg)
7256 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7259 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7260 hda_nid_t nid, int pin_type,
7263 alc_set_pin_output(codec, nid, pin_type);
7264 /* need the manual connection? */
7266 int idx = nid - 0x12;
7267 snd_hda_codec_write(codec, idx + 0x0b, 0,
7268 AC_VERB_SET_CONNECT_SEL, sel_idx);
7272 static void alc260_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
7276 nid += 0x06; /* DAC -> MIX */
7277 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7279 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7281 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7285 static void alc260_auto_init_multi_out(struct hda_codec *codec)
7287 struct alc_spec *spec = codec->spec;
7291 nid = spec->autocfg.line_out_pins[0];
7293 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7294 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7297 nid = spec->autocfg.speaker_pins[0];
7299 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7301 nid = spec->autocfg.hp_pins[0];
7303 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7306 for (i = 0; i < spec->multiout.num_dacs; i++)
7307 alc260_auto_init_dac(codec, spec->multiout.dac_nids[i]);
7308 alc260_auto_init_dac(codec, spec->multiout.extra_out_nid[0]);
7309 alc260_auto_init_dac(codec, spec->multiout.hp_nid);
7312 #define alc260_auto_init_analog_input alc880_auto_init_analog_input
7313 #define alc260_auto_init_input_src alc880_auto_init_input_src
7315 static int alc260_parse_auto_config(struct hda_codec *codec)
7317 struct alc_spec *spec = codec->spec;
7319 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7321 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7325 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7328 if (!spec->kctls.list)
7329 return 0; /* can't find valid BIOS pin config */
7330 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7334 spec->multiout.max_channels = 2;
7336 if (spec->autocfg.dig_outs)
7337 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7338 if (spec->kctls.list)
7339 add_mixer(spec, spec->kctls.list);
7341 spec->num_mux_defs = 1;
7342 spec->input_mux = &spec->private_imux[0];
7344 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7349 /* additional initialization for auto-configuration model */
7350 static void alc260_auto_init(struct hda_codec *codec)
7352 struct alc_spec *spec = codec->spec;
7353 alc260_auto_init_multi_out(codec);
7354 alc260_auto_init_analog_input(codec);
7355 alc260_auto_init_input_src(codec);
7356 alc_auto_init_digital(codec);
7357 if (spec->unsol_event)
7358 alc_inithook(codec);
7361 #ifdef CONFIG_SND_HDA_POWER_SAVE
7362 static const struct hda_amp_list alc260_loopbacks[] = {
7363 { 0x07, HDA_INPUT, 0 },
7364 { 0x07, HDA_INPUT, 1 },
7365 { 0x07, HDA_INPUT, 2 },
7366 { 0x07, HDA_INPUT, 3 },
7367 { 0x07, HDA_INPUT, 4 },
7379 static const struct alc_fixup alc260_fixups[] = {
7380 [PINFIX_HP_DC5750] = {
7381 .type = ALC_FIXUP_PINS,
7382 .v.pins = (const struct alc_pincfg[]) {
7383 { 0x11, 0x90130110 }, /* speaker */
7389 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7390 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7395 * ALC260 configurations
7397 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7398 [ALC260_BASIC] = "basic",
7400 [ALC260_HP_3013] = "hp-3013",
7401 [ALC260_HP_DC7600] = "hp-dc7600",
7402 [ALC260_FUJITSU_S702X] = "fujitsu",
7403 [ALC260_ACER] = "acer",
7404 [ALC260_WILL] = "will",
7405 [ALC260_REPLACER_672V] = "replacer",
7406 [ALC260_FAVORIT100] = "favorit100",
7407 #ifdef CONFIG_SND_DEBUG
7408 [ALC260_TEST] = "test",
7410 [ALC260_AUTO] = "auto",
7413 static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7414 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7415 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7416 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7417 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7418 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7419 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7420 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7421 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7422 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7423 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7424 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7425 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7426 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7427 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7428 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7429 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7430 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7431 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7432 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7433 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7437 static const struct alc_config_preset alc260_presets[] = {
7439 .mixers = { alc260_base_output_mixer,
7440 alc260_input_mixer },
7441 .init_verbs = { alc260_init_verbs },
7442 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7443 .dac_nids = alc260_dac_nids,
7444 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7445 .adc_nids = alc260_dual_adc_nids,
7446 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7447 .channel_mode = alc260_modes,
7448 .input_mux = &alc260_capture_source,
7451 .mixers = { alc260_hp_output_mixer,
7452 alc260_input_mixer },
7453 .init_verbs = { alc260_init_verbs,
7454 alc260_hp_unsol_verbs },
7455 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7456 .dac_nids = alc260_dac_nids,
7457 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7458 .adc_nids = alc260_adc_nids_alt,
7459 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7460 .channel_mode = alc260_modes,
7461 .input_mux = &alc260_capture_source,
7462 .unsol_event = alc_sku_unsol_event,
7463 .setup = alc260_hp_setup,
7464 .init_hook = alc_inithook,
7466 [ALC260_HP_DC7600] = {
7467 .mixers = { alc260_hp_dc7600_mixer,
7468 alc260_input_mixer },
7469 .init_verbs = { alc260_init_verbs,
7470 alc260_hp_dc7600_verbs },
7471 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7472 .dac_nids = alc260_dac_nids,
7473 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7474 .adc_nids = alc260_adc_nids_alt,
7475 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7476 .channel_mode = alc260_modes,
7477 .input_mux = &alc260_capture_source,
7478 .unsol_event = alc_sku_unsol_event,
7479 .setup = alc260_hp_3012_setup,
7480 .init_hook = alc_inithook,
7482 [ALC260_HP_3013] = {
7483 .mixers = { alc260_hp_3013_mixer,
7484 alc260_input_mixer },
7485 .init_verbs = { alc260_hp_3013_init_verbs,
7486 alc260_hp_3013_unsol_verbs },
7487 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7488 .dac_nids = alc260_dac_nids,
7489 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7490 .adc_nids = alc260_adc_nids_alt,
7491 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7492 .channel_mode = alc260_modes,
7493 .input_mux = &alc260_capture_source,
7494 .unsol_event = alc_sku_unsol_event,
7495 .setup = alc260_hp_3013_setup,
7496 .init_hook = alc_inithook,
7498 [ALC260_FUJITSU_S702X] = {
7499 .mixers = { alc260_fujitsu_mixer },
7500 .init_verbs = { alc260_fujitsu_init_verbs },
7501 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7502 .dac_nids = alc260_dac_nids,
7503 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7504 .adc_nids = alc260_dual_adc_nids,
7505 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7506 .channel_mode = alc260_modes,
7507 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7508 .input_mux = alc260_fujitsu_capture_sources,
7511 .mixers = { alc260_acer_mixer },
7512 .init_verbs = { alc260_acer_init_verbs },
7513 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7514 .dac_nids = alc260_dac_nids,
7515 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7516 .adc_nids = alc260_dual_adc_nids,
7517 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7518 .channel_mode = alc260_modes,
7519 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7520 .input_mux = alc260_acer_capture_sources,
7522 [ALC260_FAVORIT100] = {
7523 .mixers = { alc260_favorit100_mixer },
7524 .init_verbs = { alc260_favorit100_init_verbs },
7525 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7526 .dac_nids = alc260_dac_nids,
7527 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7528 .adc_nids = alc260_dual_adc_nids,
7529 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7530 .channel_mode = alc260_modes,
7531 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7532 .input_mux = alc260_favorit100_capture_sources,
7535 .mixers = { alc260_will_mixer },
7536 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7537 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7538 .dac_nids = alc260_dac_nids,
7539 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7540 .adc_nids = alc260_adc_nids,
7541 .dig_out_nid = ALC260_DIGOUT_NID,
7542 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7543 .channel_mode = alc260_modes,
7544 .input_mux = &alc260_capture_source,
7546 [ALC260_REPLACER_672V] = {
7547 .mixers = { alc260_replacer_672v_mixer },
7548 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7549 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7550 .dac_nids = alc260_dac_nids,
7551 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7552 .adc_nids = alc260_adc_nids,
7553 .dig_out_nid = ALC260_DIGOUT_NID,
7554 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7555 .channel_mode = alc260_modes,
7556 .input_mux = &alc260_capture_source,
7557 .unsol_event = alc260_replacer_672v_unsol_event,
7558 .init_hook = alc260_replacer_672v_automute,
7560 #ifdef CONFIG_SND_DEBUG
7562 .mixers = { alc260_test_mixer },
7563 .init_verbs = { alc260_test_init_verbs },
7564 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7565 .dac_nids = alc260_test_dac_nids,
7566 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7567 .adc_nids = alc260_test_adc_nids,
7568 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7569 .channel_mode = alc260_modes,
7570 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7571 .input_mux = alc260_test_capture_sources,
7576 static int patch_alc260(struct hda_codec *codec)
7578 struct alc_spec *spec;
7579 int err, board_config;
7581 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7587 spec->mixer_nid = 0x07;
7589 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7592 if (board_config < 0) {
7593 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7595 board_config = ALC260_AUTO;
7598 if (board_config == ALC260_AUTO) {
7599 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7600 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7603 if (board_config == ALC260_AUTO) {
7604 /* automatic parse from the BIOS config */
7605 err = alc260_parse_auto_config(codec);
7611 "hda_codec: Cannot set up configuration "
7612 "from BIOS. Using base mode...\n");
7613 board_config = ALC260_BASIC;
7617 err = snd_hda_attach_beep_device(codec, 0x1);
7623 if (board_config != ALC260_AUTO)
7624 setup_preset(codec, &alc260_presets[board_config]);
7626 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7627 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7628 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7630 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7631 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7633 if (!spec->adc_nids && spec->input_mux) {
7634 /* check whether NID 0x04 is valid */
7635 unsigned int wcap = get_wcaps(codec, 0x04);
7636 wcap = get_wcaps_type(wcap);
7638 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7639 spec->adc_nids = alc260_adc_nids_alt;
7640 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7642 spec->adc_nids = alc260_adc_nids;
7643 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7646 set_capture_mixer(codec);
7647 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7649 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7651 spec->vmaster_nid = 0x08;
7653 codec->patch_ops = alc_patch_ops;
7654 if (board_config == ALC260_AUTO)
7655 spec->init_hook = alc260_auto_init;
7656 spec->shutup = alc_eapd_shutup;
7657 #ifdef CONFIG_SND_HDA_POWER_SAVE
7658 if (!spec->loopback.amplist)
7659 spec->loopback.amplist = alc260_loopbacks;
7667 * ALC882/883/885/888/889 support
7669 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7670 * configuration. Each pin widget can choose any input DACs and a mixer.
7671 * Each ADC is connected from a mixer of all inputs. This makes possible
7672 * 6-channel independent captures.
7674 * In addition, an independent DAC for the multi-playback (not used in this
7677 #define ALC882_DIGOUT_NID 0x06
7678 #define ALC882_DIGIN_NID 0x0a
7679 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7680 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7681 #define ALC1200_DIGOUT_NID 0x10
7684 static const struct hda_channel_mode alc882_ch_modes[1] = {
7689 static const hda_nid_t alc882_dac_nids[4] = {
7690 /* front, rear, clfe, rear_surr */
7691 0x02, 0x03, 0x04, 0x05
7693 #define alc883_dac_nids alc882_dac_nids
7696 #define alc882_adc_nids alc880_adc_nids
7697 #define alc882_adc_nids_alt alc880_adc_nids_alt
7698 #define alc883_adc_nids alc882_adc_nids_alt
7699 static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7700 static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7701 #define alc889_adc_nids alc880_adc_nids
7703 static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7704 static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7705 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7706 static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7707 #define alc889_capsrc_nids alc882_capsrc_nids
7710 /* FIXME: should be a matrix-type input source selection */
7712 static const struct hda_input_mux alc882_capture_source = {
7716 { "Front Mic", 0x1 },
7722 #define alc883_capture_source alc882_capture_source
7724 static const struct hda_input_mux alc889_capture_source = {
7727 { "Front Mic", 0x0 },
7733 static const struct hda_input_mux mb5_capture_source = {
7742 static const struct hda_input_mux macmini3_capture_source = {
7750 static const struct hda_input_mux alc883_3stack_6ch_intel = {
7754 { "Front Mic", 0x0 },
7760 static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7768 static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7772 { "Internal Mic", 0x1 },
7778 static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7782 { "Internal Mic", 0x1 },
7786 static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7790 { "Front Mic", 0x1 },
7795 static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7803 static const struct hda_input_mux alc889A_mb31_capture_source = {
7807 /* Front Mic (0x01) unused */
7809 /* Line 2 (0x03) unused */
7810 /* CD (0x04) unused? */
7814 static const struct hda_input_mux alc889A_imac91_capture_source = {
7818 { "Line", 0x2 }, /* Not sure! */
7825 static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7832 static const struct hda_verb alc882_3ST_ch2_init[] = {
7833 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7834 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7835 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7836 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7843 static const struct hda_verb alc882_3ST_ch4_init[] = {
7844 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7845 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7846 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7847 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7848 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7855 static const struct hda_verb alc882_3ST_ch6_init[] = {
7856 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7857 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7858 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7859 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7860 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7861 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7865 static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7866 { 2, alc882_3ST_ch2_init },
7867 { 4, alc882_3ST_ch4_init },
7868 { 6, alc882_3ST_ch6_init },
7871 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7876 static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7877 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7878 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7879 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7888 static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7889 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7890 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7891 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7892 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7893 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7894 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7901 static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7902 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7903 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7905 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7906 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7908 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7912 static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7913 { 2, alc883_3ST_ch2_clevo_init },
7914 { 4, alc883_3ST_ch4_clevo_init },
7915 { 6, alc883_3ST_ch6_clevo_init },
7922 static const struct hda_verb alc882_sixstack_ch6_init[] = {
7923 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7924 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7925 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7926 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7933 static const struct hda_verb alc882_sixstack_ch8_init[] = {
7934 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7935 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7936 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7937 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7942 { 6, alc882_sixstack_ch6_init },
7943 { 8, alc882_sixstack_ch8_init },
7947 /* Macbook Air 2,1 */
7949 static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7954 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7960 static const struct hda_verb alc885_mbp_ch2_init[] = {
7961 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7962 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7963 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7970 static const struct hda_verb alc885_mbp_ch4_init[] = {
7971 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7972 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7973 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7974 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7975 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7979 static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7980 { 2, alc885_mbp_ch2_init },
7981 { 4, alc885_mbp_ch4_init },
7986 * Speakers/Woofer/HP = Front
7989 static const struct hda_verb alc885_mb5_ch2_init[] = {
7990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7991 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7997 * Speakers/HP = Front
8001 static const struct hda_verb alc885_mb5_ch6_init[] = {
8002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8004 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8008 static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8009 { 2, alc885_mb5_ch2_init },
8010 { 6, alc885_mb5_ch6_init },
8013 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
8018 static const struct hda_verb alc883_4ST_ch2_init[] = {
8019 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8020 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8021 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8022 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8023 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8024 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8031 static const struct hda_verb alc883_4ST_ch4_init[] = {
8032 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8033 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8034 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8035 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8036 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8045 static const struct hda_verb alc883_4ST_ch6_init[] = {
8046 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8047 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8048 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8049 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8050 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8051 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8052 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8053 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8060 static const struct hda_verb alc883_4ST_ch8_init[] = {
8061 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8062 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8063 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8064 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8065 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8066 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8067 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8068 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8069 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8073 static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8074 { 2, alc883_4ST_ch2_init },
8075 { 4, alc883_4ST_ch4_init },
8076 { 6, alc883_4ST_ch6_init },
8077 { 8, alc883_4ST_ch8_init },
8084 static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8085 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8086 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8087 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8088 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8095 static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8096 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8097 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8098 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8099 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8100 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8107 static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8108 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8109 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8110 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8111 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8112 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8113 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8117 static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8118 { 2, alc883_3ST_ch2_intel_init },
8119 { 4, alc883_3ST_ch4_intel_init },
8120 { 6, alc883_3ST_ch6_intel_init },
8126 static const struct hda_verb alc889_ch2_intel_init[] = {
8127 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8128 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8129 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8130 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8139 static const struct hda_verb alc889_ch6_intel_init[] = {
8140 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8141 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8142 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8143 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8144 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8145 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8152 static const struct hda_verb alc889_ch8_intel_init[] = {
8153 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8154 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8155 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8156 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8157 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8158 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8159 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8163 static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8164 { 2, alc889_ch2_intel_init },
8165 { 6, alc889_ch6_intel_init },
8166 { 8, alc889_ch8_intel_init },
8172 static const struct hda_verb alc883_sixstack_ch6_init[] = {
8173 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8174 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8175 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8176 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8183 static const struct hda_verb alc883_sixstack_ch8_init[] = {
8184 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8185 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8186 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8187 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8192 { 6, alc883_sixstack_ch6_init },
8193 { 8, alc883_sixstack_ch8_init },
8197 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8198 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8200 static const struct snd_kcontrol_new alc882_base_mixer[] = {
8201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8204 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8205 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8209 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8210 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8212 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8213 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8225 /* Macbook Air 2,1 same control for HP and internal Speaker */
8227 static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8228 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8229 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8234 static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8235 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8236 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8237 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8238 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8239 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8240 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8241 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8243 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8244 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8245 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8249 static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8250 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8251 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8252 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8253 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8254 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8257 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8258 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8259 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8261 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8262 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8263 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8267 static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8269 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8270 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8271 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8272 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8273 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8274 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8275 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8276 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8277 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8278 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8282 static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8283 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8284 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8289 static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8290 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8291 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8292 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8293 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8298 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8302 static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8303 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8304 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8306 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8307 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8308 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8309 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8311 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8312 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8313 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8314 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8315 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8319 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8320 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8322 static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8323 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8324 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8326 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8327 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8328 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8329 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8330 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8331 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8332 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8339 static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8340 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8341 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8342 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8343 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8344 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8345 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8346 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8348 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8349 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8353 static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8356 .name = "Channel Mode",
8357 .info = alc_ch_mode_info,
8358 .get = alc_ch_mode_get,
8359 .put = alc_ch_mode_put,
8364 static const struct hda_verb alc882_base_init_verbs[] = {
8365 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8375 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8378 /* Front Pin: output 0 (0x0c) */
8379 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8380 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8382 /* Rear Pin: output 1 (0x0d) */
8383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8386 /* CLFE Pin: output 2 (0x0e) */
8387 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8390 /* Side Pin: output 3 (0x0f) */
8391 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8394 /* Mic (rear) pin: input vref at 80% */
8395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8397 /* Front Mic pin: input vref at 80% */
8398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400 /* Line In pin: input */
8401 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8402 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8407 /* CD pin widget for input */
8408 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8410 /* FIXME: use matrix-type input source selection */
8411 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8416 /* ADC2: mute amp left and right */
8417 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8418 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8419 /* ADC3: mute amp left and right */
8420 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8421 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8426 static const struct hda_verb alc882_adc1_init_verbs[] = {
8427 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8429 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8430 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8432 /* ADC1: mute amp left and right */
8433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8434 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8438 static const struct hda_verb alc882_eapd_verbs[] = {
8439 /* change to EAPD mode */
8440 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8441 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8445 static const struct hda_verb alc889_eapd_verbs[] = {
8446 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8447 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 static const struct hda_verb alc_hp15_unsol_verbs[] = {
8452 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8457 static const struct hda_verb alc885_init_verbs[] = {
8458 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8462 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8468 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8471 /* Front HP Pin: output 0 (0x0c) */
8472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8473 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8474 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8475 /* Front Pin: output 0 (0x0c) */
8476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* Rear Pin: output 1 (0x0d) */
8480 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8483 /* CLFE Pin: output 2 (0x0e) */
8484 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8487 /* Side Pin: output 3 (0x0f) */
8488 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8491 /* Mic (rear) pin: input vref at 80% */
8492 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8493 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8494 /* Front Mic pin: input vref at 80% */
8495 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8497 /* Line In pin: input */
8498 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8499 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8501 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8503 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8505 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8507 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8508 /* ADC2: mute amp left and right */
8509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8510 /* ADC3: mute amp left and right */
8511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8516 static const struct hda_verb alc885_init_input_verbs[] = {
8517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8524 /* Unmute Selector 24h and set the default input to front mic */
8525 static const struct hda_verb alc889_init_input_verbs[] = {
8526 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8532 #define alc883_init_verbs alc882_base_init_verbs
8535 static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8536 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8537 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8539 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8540 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8541 /* FIXME: this looks suspicious...
8542 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8543 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8548 static const struct hda_verb alc882_macpro_init_verbs[] = {
8549 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8553 /* Front Pin: output 0 (0x0c) */
8554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8556 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 /* Front Mic pin: input vref at 80% */
8558 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8559 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8560 /* Speaker: output */
8561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8562 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8563 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8564 /* Headphone output (output 0 - 0x0c) */
8565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8569 /* FIXME: use matrix-type input source selection */
8570 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8571 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8578 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8583 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8586 /* ADC1: mute amp left and right */
8587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8588 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8589 /* ADC2: mute amp left and right */
8590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8591 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 /* ADC3: mute amp left and right */
8593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8594 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8600 static const struct hda_verb alc885_mb5_init_verbs[] = {
8602 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8603 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8604 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8605 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8610 /* Surround mixer */
8611 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8615 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8616 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8619 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8620 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8622 /* Front Pin (0x0c) */
8623 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8625 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8626 /* LFE Pin (0x0e) */
8627 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8629 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8631 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8634 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8635 /* Front Mic pin: input vref at 80% */
8636 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8637 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8639 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8643 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8644 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8649 static const struct hda_verb alc885_macmini3_init_verbs[] = {
8651 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8652 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8653 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8654 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8659 /* Surround mixer */
8660 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8662 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8664 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8665 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8666 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8668 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8669 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8670 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8671 /* Front Pin (0x0c) */
8672 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8673 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8674 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8675 /* LFE Pin (0x0e) */
8676 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8677 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8678 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8681 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8683 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8685 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8696 static const struct hda_verb alc885_mba21_init_verbs[] = {
8697 /*Internal and HP Speaker Mixer*/
8698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8701 /*Internal Speaker Pin (0x0c)*/
8702 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8704 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8705 /* HP Pin: output 0 (0x0e) */
8706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8710 /* Line in (is hp when jack connected)*/
8711 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8712 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8718 /* Macbook Pro rev3 */
8719 static const struct hda_verb alc885_mbp3_init_verbs[] = {
8720 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8731 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8732 /* Front Pin: output 0 (0x0c) */
8733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8735 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8736 /* HP Pin: output 0 (0x0e) */
8737 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8739 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8740 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8741 /* Mic (rear) pin: input vref at 80% */
8742 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8744 /* Front Mic pin: input vref at 80% */
8745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8746 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8747 /* Line In pin: use output 1 when in LineOut mode */
8748 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8750 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8752 /* FIXME: use matrix-type input source selection */
8753 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8754 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8760 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8761 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8769 /* ADC1: mute amp left and right */
8770 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8771 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8772 /* ADC2: mute amp left and right */
8773 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8774 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8775 /* ADC3: mute amp left and right */
8776 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8777 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8783 static const struct hda_verb alc885_imac91_init_verbs[] = {
8784 /* Internal Speaker Pin (0x0c) */
8785 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8786 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8787 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8790 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8794 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8799 /* Front Mic pin: input vref at 80% */
8800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8804 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8805 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8806 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8810 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8812 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8813 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8815 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8816 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8817 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8818 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8819 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8820 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8821 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8825 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8827 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8828 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8829 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8830 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8831 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8833 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8837 /* iMac 24 mixer. */
8838 static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8839 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8840 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8844 /* iMac 24 init verbs. */
8845 static const struct hda_verb alc885_imac24_init_verbs[] = {
8846 /* Internal speakers: output 0 (0x0c) */
8847 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8848 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8849 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8850 /* Internal speakers: output 0 (0x0c) */
8851 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8852 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8853 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 /* Headphone: output 0 (0x0c) */
8855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8859 /* Front Mic: input vref at 80% */
8860 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8865 /* Toggle speaker-output according to the hp-jack state */
8866 static void alc885_imac24_setup(struct hda_codec *codec)
8868 struct alc_spec *spec = codec->spec;
8870 spec->autocfg.hp_pins[0] = 0x14;
8871 spec->autocfg.speaker_pins[0] = 0x18;
8872 spec->autocfg.speaker_pins[1] = 0x1a;
8874 spec->automute_mode = ALC_AUTOMUTE_AMP;
8877 #define alc885_mb5_setup alc885_imac24_setup
8878 #define alc885_macmini3_setup alc885_imac24_setup
8880 /* Macbook Air 2,1 */
8881 static void alc885_mba21_setup(struct hda_codec *codec)
8883 struct alc_spec *spec = codec->spec;
8885 spec->autocfg.hp_pins[0] = 0x14;
8886 spec->autocfg.speaker_pins[0] = 0x18;
8888 spec->automute_mode = ALC_AUTOMUTE_AMP;
8893 static void alc885_mbp3_setup(struct hda_codec *codec)
8895 struct alc_spec *spec = codec->spec;
8897 spec->autocfg.hp_pins[0] = 0x15;
8898 spec->autocfg.speaker_pins[0] = 0x14;
8900 spec->automute_mode = ALC_AUTOMUTE_AMP;
8903 static void alc885_imac91_setup(struct hda_codec *codec)
8905 struct alc_spec *spec = codec->spec;
8907 spec->autocfg.hp_pins[0] = 0x14;
8908 spec->autocfg.speaker_pins[0] = 0x18;
8909 spec->autocfg.speaker_pins[1] = 0x1a;
8911 spec->automute_mode = ALC_AUTOMUTE_AMP;
8914 static const struct hda_verb alc882_targa_verbs[] = {
8915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8916 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8918 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8921 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8922 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8923 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8925 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8929 /* toggle speaker-output according to the hp-jack state */
8930 static void alc882_targa_automute(struct hda_codec *codec)
8932 struct alc_spec *spec = codec->spec;
8933 alc_hp_automute(codec);
8934 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8935 spec->jack_present ? 1 : 3);
8938 static void alc882_targa_setup(struct hda_codec *codec)
8940 struct alc_spec *spec = codec->spec;
8942 spec->autocfg.hp_pins[0] = 0x14;
8943 spec->autocfg.speaker_pins[0] = 0x1b;
8945 spec->automute_mode = ALC_AUTOMUTE_AMP;
8948 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8950 if ((res >> 26) == ALC880_HP_EVENT)
8951 alc882_targa_automute(codec);
8954 static const struct hda_verb alc882_asus_a7j_verbs[] = {
8955 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8956 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8958 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8960 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8962 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8963 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8964 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8966 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8967 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8968 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8972 static const struct hda_verb alc882_asus_a7m_verbs[] = {
8973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8977 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8978 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8980 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8982 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8984 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8985 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8986 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8990 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8992 unsigned int gpiostate, gpiomask, gpiodir;
8994 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8995 AC_VERB_GET_GPIO_DATA, 0);
8998 gpiostate |= (1 << pin);
9000 gpiostate &= ~(1 << pin);
9002 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9003 AC_VERB_GET_GPIO_MASK, 0);
9004 gpiomask |= (1 << pin);
9006 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9007 AC_VERB_GET_GPIO_DIRECTION, 0);
9008 gpiodir |= (1 << pin);
9011 snd_hda_codec_write(codec, codec->afg, 0,
9012 AC_VERB_SET_GPIO_MASK, gpiomask);
9013 snd_hda_codec_write(codec, codec->afg, 0,
9014 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9018 snd_hda_codec_write(codec, codec->afg, 0,
9019 AC_VERB_SET_GPIO_DATA, gpiostate);
9022 /* set up GPIO at initialization */
9023 static void alc885_macpro_init_hook(struct hda_codec *codec)
9025 alc882_gpio_mute(codec, 0, 0);
9026 alc882_gpio_mute(codec, 1, 0);
9029 /* set up GPIO and update auto-muting at initialization */
9030 static void alc885_imac24_init_hook(struct hda_codec *codec)
9032 alc885_macpro_init_hook(codec);
9033 alc_hp_automute(codec);
9036 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9037 static const struct hda_verb alc889A_mb31_ch2_init[] = {
9038 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9039 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9040 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9045 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9046 static const struct hda_verb alc889A_mb31_ch4_init[] = {
9047 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9048 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9049 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9050 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9054 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9055 static const struct hda_verb alc889A_mb31_ch5_init[] = {
9056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9057 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9058 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9063 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9064 static const struct hda_verb alc889A_mb31_ch6_init[] = {
9065 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9066 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9067 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9068 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9072 static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9073 { 2, alc889A_mb31_ch2_init },
9074 { 4, alc889A_mb31_ch4_init },
9075 { 5, alc889A_mb31_ch5_init },
9076 { 6, alc889A_mb31_ch6_init },
9079 static const struct hda_verb alc883_medion_eapd_verbs[] = {
9080 /* eanable EAPD on medion laptop */
9081 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9082 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9086 #define alc883_base_mixer alc882_base_mixer
9088 static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9089 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9090 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9091 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9092 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9093 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9094 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9097 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9098 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9099 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9101 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9105 static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9106 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9107 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9108 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9109 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9111 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9113 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9114 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9115 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9119 static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9120 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9121 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9123 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9129 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9133 static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9138 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9139 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9140 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9150 static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9151 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9154 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9155 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9156 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9157 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9158 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9161 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9163 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9173 static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9175 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9176 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9177 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9178 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9180 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9182 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9191 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9192 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9193 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9197 static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9201 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9204 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9205 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9206 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9208 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9210 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9211 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9213 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9214 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9215 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9216 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9217 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9221 static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9223 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9225 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9226 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9227 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9228 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9229 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9230 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9238 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9239 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9244 static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9245 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9246 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9247 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9249 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9250 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9251 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9252 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9253 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9254 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9255 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9256 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9258 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9260 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9261 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9265 static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9266 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9267 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9269 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9270 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9271 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9274 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9275 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9277 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9281 static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9282 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9283 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9284 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9285 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9286 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9290 static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9294 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9298 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9302 static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9303 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9304 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9306 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9307 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9309 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9310 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9311 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9315 static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9316 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9317 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9318 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9320 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9321 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9325 static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9326 /* Unmute front mixer */
9327 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9330 /* Set speaker pin to front mixer */
9331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9333 /* Init headphone pin */
9334 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9335 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9336 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9337 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9342 /* toggle speaker-output according to the hp-jack state */
9343 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9345 struct alc_spec *spec = codec->spec;
9347 spec->autocfg.hp_pins[0] = 0x1a;
9348 spec->autocfg.speaker_pins[0] = 0x15;
9350 spec->automute_mode = ALC_AUTOMUTE_AMP;
9353 static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9354 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9355 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9360 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9365 static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9366 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9367 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9373 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9378 static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9379 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9380 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9381 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9382 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9383 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9384 0x0d, 1, 0x0, HDA_OUTPUT),
9385 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9386 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9387 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9388 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9389 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9390 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9391 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9392 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9393 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9395 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9396 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9397 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9398 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9399 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9403 static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9405 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9406 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9407 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9408 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9409 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9411 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9412 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9413 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9414 /* Output switches */
9415 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9416 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9417 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9419 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9420 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9423 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9425 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9429 static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9432 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9434 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9439 static const struct hda_bind_ctls alc883_bind_cap_vol = {
9440 .ops = &snd_hda_bind_vol,
9442 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9443 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9448 static const struct hda_bind_ctls alc883_bind_cap_switch = {
9449 .ops = &snd_hda_bind_sw,
9451 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9452 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9457 static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9458 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9459 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9469 static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9470 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9471 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9474 /* .name = "Capture Source", */
9475 .name = "Input Source",
9477 .info = alc_mux_enum_info,
9478 .get = alc_mux_enum_get,
9479 .put = alc_mux_enum_put,
9484 static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9486 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9487 .name = "Channel Mode",
9488 .info = alc_ch_mode_info,
9489 .get = alc_ch_mode_get,
9490 .put = alc_ch_mode_put,
9495 /* toggle speaker-output according to the hp-jack state */
9496 static void alc883_mitac_setup(struct hda_codec *codec)
9498 struct alc_spec *spec = codec->spec;
9500 spec->autocfg.hp_pins[0] = 0x15;
9501 spec->autocfg.speaker_pins[0] = 0x14;
9502 spec->autocfg.speaker_pins[1] = 0x17;
9504 spec->automute_mode = ALC_AUTOMUTE_AMP;
9507 static const struct hda_verb alc883_mitac_verbs[] = {
9509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9512 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9513 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9515 /* enable unsolicited event */
9516 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9517 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9522 static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9524 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9525 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9527 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9529 /* enable unsolicited event */
9531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9532 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9538 static const struct hda_verb alc883_clevo_m720_verbs[] = {
9540 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9543 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9546 /* enable unsolicited event */
9547 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9548 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9553 static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9555 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9558 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9559 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9561 /* enable unsolicited event */
9562 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9567 static const struct hda_verb alc883_targa_verbs[] = {
9568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9574 /* Connect Line-Out side jack (SPDIF) to Side */
9575 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9576 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9577 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9578 /* Connect Mic jack to CLFE */
9579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9581 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9582 /* Connect Line-in jack to Surround */
9583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9585 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9586 /* Connect HP out jack to Front */
9587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9588 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9589 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9591 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9596 static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9598 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9599 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9603 static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9604 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9606 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9611 static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9614 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9616 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9620 static const struct hda_verb alc883_haier_w66_verbs[] = {
9621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9626 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9628 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9629 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9633 static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9637 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9640 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9641 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9645 static const struct hda_verb alc888_6st_dell_verbs[] = {
9646 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9650 static const struct hda_verb alc883_vaiott_verbs[] = {
9652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9655 /* enable unsolicited event */
9656 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9661 static void alc888_3st_hp_setup(struct hda_codec *codec)
9663 struct alc_spec *spec = codec->spec;
9665 spec->autocfg.hp_pins[0] = 0x1b;
9666 spec->autocfg.speaker_pins[0] = 0x14;
9667 spec->autocfg.speaker_pins[1] = 0x16;
9668 spec->autocfg.speaker_pins[2] = 0x18;
9670 spec->automute_mode = ALC_AUTOMUTE_AMP;
9673 static const struct hda_verb alc888_3st_hp_verbs[] = {
9674 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9675 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9676 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9677 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9684 static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9687 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9688 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9695 static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9696 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9697 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9698 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9699 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9700 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9707 static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9708 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9709 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9710 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9711 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9712 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9713 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9717 static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9718 { 2, alc888_3st_hp_2ch_init },
9719 { 4, alc888_3st_hp_4ch_init },
9720 { 6, alc888_3st_hp_6ch_init },
9723 static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9725 struct alc_spec *spec = codec->spec;
9727 spec->autocfg.hp_pins[0] = 0x1b;
9728 spec->autocfg.line_out_pins[0] = 0x14;
9729 spec->autocfg.speaker_pins[0] = 0x15;
9731 spec->automute_mode = ALC_AUTOMUTE_AMP;
9734 /* toggle speaker-output according to the hp-jack state */
9735 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9737 struct alc_spec *spec = codec->spec;
9739 spec->autocfg.hp_pins[0] = 0x14;
9740 spec->autocfg.speaker_pins[0] = 0x15;
9742 spec->automute_mode = ALC_AUTOMUTE_AMP;
9745 /* toggle speaker-output according to the hp-jack state */
9746 #define alc883_targa_init_hook alc882_targa_init_hook
9747 #define alc883_targa_unsol_event alc882_targa_unsol_event
9749 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9751 struct alc_spec *spec = codec->spec;
9753 spec->autocfg.hp_pins[0] = 0x15;
9754 spec->autocfg.speaker_pins[0] = 0x14;
9756 spec->automute_mode = ALC_AUTOMUTE_AMP;
9759 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9761 alc_hp_automute(codec);
9762 alc88x_simple_mic_automute(codec);
9765 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9768 switch (res >> 26) {
9769 case ALC880_MIC_EVENT:
9770 alc88x_simple_mic_automute(codec);
9773 alc_sku_unsol_event(codec, res);
9778 /* toggle speaker-output according to the hp-jack state */
9779 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9781 struct alc_spec *spec = codec->spec;
9783 spec->autocfg.hp_pins[0] = 0x14;
9784 spec->autocfg.speaker_pins[0] = 0x15;
9786 spec->automute_mode = ALC_AUTOMUTE_AMP;
9789 static void alc883_haier_w66_setup(struct hda_codec *codec)
9791 struct alc_spec *spec = codec->spec;
9793 spec->autocfg.hp_pins[0] = 0x1b;
9794 spec->autocfg.speaker_pins[0] = 0x14;
9796 spec->automute_mode = ALC_AUTOMUTE_AMP;
9799 static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9801 struct alc_spec *spec = codec->spec;
9803 spec->autocfg.hp_pins[0] = 0x1b;
9804 spec->autocfg.line_out_pins[0] = 0x14;
9805 spec->autocfg.speaker_pins[0] = 0x15;
9807 spec->detect_line = 1;
9808 spec->automute_lines = 1;
9809 spec->automute_mode = ALC_AUTOMUTE_AMP;
9812 /* toggle speaker-output according to the hp-jack state */
9813 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9815 struct alc_spec *spec = codec->spec;
9817 spec->autocfg.hp_pins[0] = 0x14;
9818 spec->autocfg.speaker_pins[0] = 0x15;
9819 spec->autocfg.speaker_pins[1] = 0x16;
9821 spec->automute_mode = ALC_AUTOMUTE_AMP;
9824 static const struct hda_verb alc883_acer_eapd_verbs[] = {
9825 /* HP Pin: output 0 (0x0c) */
9826 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9827 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9828 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9829 /* Front Pin: output 0 (0x0c) */
9830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9831 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9832 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9833 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9834 /* eanable EAPD on medion laptop */
9835 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9836 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9837 /* enable unsolicited event */
9838 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9842 static void alc888_6st_dell_setup(struct hda_codec *codec)
9844 struct alc_spec *spec = codec->spec;
9846 spec->autocfg.hp_pins[0] = 0x1b;
9847 spec->autocfg.speaker_pins[0] = 0x14;
9848 spec->autocfg.speaker_pins[1] = 0x15;
9849 spec->autocfg.speaker_pins[2] = 0x16;
9850 spec->autocfg.speaker_pins[3] = 0x17;
9852 spec->automute_mode = ALC_AUTOMUTE_AMP;
9855 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9857 struct alc_spec *spec = codec->spec;
9859 spec->autocfg.hp_pins[0] = 0x1b;
9860 spec->autocfg.speaker_pins[0] = 0x14;
9861 spec->autocfg.speaker_pins[1] = 0x15;
9862 spec->autocfg.speaker_pins[2] = 0x16;
9863 spec->autocfg.speaker_pins[3] = 0x17;
9864 spec->autocfg.speaker_pins[4] = 0x1a;
9866 spec->automute_mode = ALC_AUTOMUTE_AMP;
9869 static void alc883_vaiott_setup(struct hda_codec *codec)
9871 struct alc_spec *spec = codec->spec;
9873 spec->autocfg.hp_pins[0] = 0x15;
9874 spec->autocfg.speaker_pins[0] = 0x14;
9875 spec->autocfg.speaker_pins[1] = 0x17;
9877 spec->automute_mode = ALC_AUTOMUTE_AMP;
9880 static const struct hda_verb alc888_asus_m90v_verbs[] = {
9881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9883 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9884 /* enable unsolicited event */
9885 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9886 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9890 static void alc883_mode2_setup(struct hda_codec *codec)
9892 struct alc_spec *spec = codec->spec;
9894 spec->autocfg.hp_pins[0] = 0x1b;
9895 spec->autocfg.speaker_pins[0] = 0x14;
9896 spec->autocfg.speaker_pins[1] = 0x15;
9897 spec->autocfg.speaker_pins[2] = 0x16;
9898 spec->ext_mic.pin = 0x18;
9899 spec->int_mic.pin = 0x19;
9900 spec->ext_mic.mux_idx = 0;
9901 spec->int_mic.mux_idx = 1;
9904 spec->automute_mode = ALC_AUTOMUTE_AMP;
9907 static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9908 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9911 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9912 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9913 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9914 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9915 /* enable unsolicited event */
9916 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9920 static void alc883_eee1601_inithook(struct hda_codec *codec)
9922 struct alc_spec *spec = codec->spec;
9924 spec->autocfg.hp_pins[0] = 0x14;
9925 spec->autocfg.speaker_pins[0] = 0x1b;
9926 alc_hp_automute(codec);
9929 static const struct hda_verb alc889A_mb31_verbs[] = {
9930 /* Init rear pin (used as headphone output) */
9931 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9933 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9934 /* Init line pin (used as output in 4ch and 6ch mode) */
9935 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9936 /* Init line 2 pin (used as headphone out by default) */
9937 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9938 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9942 /* Mute speakers according to the headphone jack state */
9943 static void alc889A_mb31_automute(struct hda_codec *codec)
9945 unsigned int present;
9947 /* Mute only in 2ch or 4ch mode */
9948 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9950 present = snd_hda_jack_detect(codec, 0x15);
9951 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9952 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9953 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9954 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9958 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9960 if ((res >> 26) == ALC880_HP_EVENT)
9961 alc889A_mb31_automute(codec);
9965 #ifdef CONFIG_SND_HDA_POWER_SAVE
9966 #define alc882_loopbacks alc880_loopbacks
9969 /* pcm configuration: identical with ALC880 */
9970 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9971 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9972 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9973 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9975 static const hda_nid_t alc883_slave_dig_outs[] = {
9976 ALC1200_DIGOUT_NID, 0,
9979 static const hda_nid_t alc1200_slave_dig_outs[] = {
9980 ALC883_DIGOUT_NID, 0,
9984 * configuration and preset
9986 static const char * const alc882_models[ALC882_MODEL_LAST] = {
9987 [ALC882_3ST_DIG] = "3stack-dig",
9988 [ALC882_6ST_DIG] = "6stack-dig",
9989 [ALC882_ARIMA] = "arima",
9990 [ALC882_W2JC] = "w2jc",
9991 [ALC882_TARGA] = "targa",
9992 [ALC882_ASUS_A7J] = "asus-a7j",
9993 [ALC882_ASUS_A7M] = "asus-a7m",
9994 [ALC885_MACPRO] = "macpro",
9995 [ALC885_MB5] = "mb5",
9996 [ALC885_MACMINI3] = "macmini3",
9997 [ALC885_MBA21] = "mba21",
9998 [ALC885_MBP3] = "mbp3",
9999 [ALC885_IMAC24] = "imac24",
10000 [ALC885_IMAC91] = "imac91",
10001 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
10002 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10003 [ALC883_3ST_6ch] = "3stack-6ch",
10004 [ALC883_6ST_DIG] = "alc883-6stack-dig",
10005 [ALC883_TARGA_DIG] = "targa-dig",
10006 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
10007 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
10008 [ALC883_ACER] = "acer",
10009 [ALC883_ACER_ASPIRE] = "acer-aspire",
10010 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
10011 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
10012 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
10013 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
10014 [ALC883_MEDION] = "medion",
10015 [ALC883_MEDION_WIM2160] = "medion-wim2160",
10016 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
10017 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10018 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10019 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10020 [ALC888_LENOVO_SKY] = "lenovo-sky",
10021 [ALC883_HAIER_W66] = "haier-w66",
10022 [ALC888_3ST_HP] = "3stack-hp",
10023 [ALC888_6ST_DELL] = "6stack-dell",
10024 [ALC883_MITAC] = "mitac",
10025 [ALC883_CLEVO_M540R] = "clevo-m540r",
10026 [ALC883_CLEVO_M720] = "clevo-m720",
10027 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10028 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10029 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
10030 [ALC889A_INTEL] = "intel-alc889a",
10031 [ALC889_INTEL] = "intel-x58",
10032 [ALC1200_ASUS_P5Q] = "asus-p5q",
10033 [ALC889A_MB31] = "mb31",
10034 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
10035 [ALC882_AUTO] = "auto",
10038 static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10039 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10041 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10042 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10043 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10044 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10045 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10046 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10047 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10048 ALC888_ACER_ASPIRE_4930G),
10049 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10050 ALC888_ACER_ASPIRE_4930G),
10051 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10052 ALC888_ACER_ASPIRE_8930G),
10053 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10054 ALC888_ACER_ASPIRE_8930G),
10055 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10056 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10057 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10058 ALC888_ACER_ASPIRE_6530G),
10059 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10060 ALC888_ACER_ASPIRE_6530G),
10061 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10062 ALC888_ACER_ASPIRE_7730G),
10063 /* default Acer -- disabled as it causes more problems.
10064 * model=auto should work fine now
10066 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10068 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10070 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10071 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10072 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10073 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10074 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10075 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10077 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10078 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10079 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10080 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10081 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10082 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10083 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10084 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10085 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10086 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10087 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10089 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10090 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10091 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10092 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10093 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10094 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10095 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10096 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10097 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10099 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10100 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10101 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10102 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
10103 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10104 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10105 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10106 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10107 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10108 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10109 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10110 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10111 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10112 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10113 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10114 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10115 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10116 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10117 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10118 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10119 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10120 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10121 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10122 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10123 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10124 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10125 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10126 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10127 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10128 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10129 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10131 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10132 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10133 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10134 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10135 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10136 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10137 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10138 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10139 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10140 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10141 ALC883_FUJITSU_PI2515),
10142 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10143 ALC888_FUJITSU_XA3530),
10144 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10145 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10146 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10147 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10148 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10149 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10150 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10151 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10153 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10154 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10155 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10156 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10157 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10158 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10159 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10164 /* codec SSID table for Intel Mac */
10165 static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10166 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10167 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10168 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10169 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10170 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10171 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10172 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10173 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10174 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10175 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10176 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10177 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10178 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10179 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10180 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10181 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10182 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10183 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10184 * so apparently no perfect solution yet
10186 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10187 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10188 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10189 {} /* terminator */
10192 static const struct alc_config_preset alc882_presets[] = {
10193 [ALC882_3ST_DIG] = {
10194 .mixers = { alc882_base_mixer },
10195 .init_verbs = { alc882_base_init_verbs,
10196 alc882_adc1_init_verbs },
10197 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10198 .dac_nids = alc882_dac_nids,
10199 .dig_out_nid = ALC882_DIGOUT_NID,
10200 .dig_in_nid = ALC882_DIGIN_NID,
10201 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10202 .channel_mode = alc882_ch_modes,
10204 .input_mux = &alc882_capture_source,
10206 [ALC882_6ST_DIG] = {
10207 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10208 .init_verbs = { alc882_base_init_verbs,
10209 alc882_adc1_init_verbs },
10210 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10211 .dac_nids = alc882_dac_nids,
10212 .dig_out_nid = ALC882_DIGOUT_NID,
10213 .dig_in_nid = ALC882_DIGIN_NID,
10214 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10215 .channel_mode = alc882_sixstack_modes,
10216 .input_mux = &alc882_capture_source,
10219 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10220 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10221 alc882_eapd_verbs },
10222 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10223 .dac_nids = alc882_dac_nids,
10224 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10225 .channel_mode = alc882_sixstack_modes,
10226 .input_mux = &alc882_capture_source,
10229 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10230 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10231 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10232 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10233 .dac_nids = alc882_dac_nids,
10234 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10235 .channel_mode = alc880_threestack_modes,
10237 .input_mux = &alc882_capture_source,
10238 .dig_out_nid = ALC882_DIGOUT_NID,
10241 .mixers = { alc885_mba21_mixer },
10242 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10244 .dac_nids = alc882_dac_nids,
10245 .channel_mode = alc885_mba21_ch_modes,
10246 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10247 .input_mux = &alc882_capture_source,
10248 .unsol_event = alc_sku_unsol_event,
10249 .setup = alc885_mba21_setup,
10250 .init_hook = alc_hp_automute,
10253 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10254 .init_verbs = { alc885_mbp3_init_verbs,
10255 alc880_gpio1_init_verbs },
10257 .dac_nids = alc882_dac_nids,
10259 .channel_mode = alc885_mbp_4ch_modes,
10260 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10261 .input_mux = &alc882_capture_source,
10262 .dig_out_nid = ALC882_DIGOUT_NID,
10263 .dig_in_nid = ALC882_DIGIN_NID,
10264 .unsol_event = alc_sku_unsol_event,
10265 .setup = alc885_mbp3_setup,
10266 .init_hook = alc_hp_automute,
10269 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10270 .init_verbs = { alc885_mb5_init_verbs,
10271 alc880_gpio1_init_verbs },
10272 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10273 .dac_nids = alc882_dac_nids,
10274 .channel_mode = alc885_mb5_6ch_modes,
10275 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10276 .input_mux = &mb5_capture_source,
10277 .dig_out_nid = ALC882_DIGOUT_NID,
10278 .dig_in_nid = ALC882_DIGIN_NID,
10279 .unsol_event = alc_sku_unsol_event,
10280 .setup = alc885_mb5_setup,
10281 .init_hook = alc_hp_automute,
10283 [ALC885_MACMINI3] = {
10284 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10285 .init_verbs = { alc885_macmini3_init_verbs,
10286 alc880_gpio1_init_verbs },
10287 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10288 .dac_nids = alc882_dac_nids,
10289 .channel_mode = alc885_macmini3_6ch_modes,
10290 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10291 .input_mux = &macmini3_capture_source,
10292 .dig_out_nid = ALC882_DIGOUT_NID,
10293 .dig_in_nid = ALC882_DIGIN_NID,
10294 .unsol_event = alc_sku_unsol_event,
10295 .setup = alc885_macmini3_setup,
10296 .init_hook = alc_hp_automute,
10298 [ALC885_MACPRO] = {
10299 .mixers = { alc882_macpro_mixer },
10300 .init_verbs = { alc882_macpro_init_verbs },
10301 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10302 .dac_nids = alc882_dac_nids,
10303 .dig_out_nid = ALC882_DIGOUT_NID,
10304 .dig_in_nid = ALC882_DIGIN_NID,
10305 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10306 .channel_mode = alc882_ch_modes,
10307 .input_mux = &alc882_capture_source,
10308 .init_hook = alc885_macpro_init_hook,
10310 [ALC885_IMAC24] = {
10311 .mixers = { alc885_imac24_mixer },
10312 .init_verbs = { alc885_imac24_init_verbs },
10313 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10314 .dac_nids = alc882_dac_nids,
10315 .dig_out_nid = ALC882_DIGOUT_NID,
10316 .dig_in_nid = ALC882_DIGIN_NID,
10317 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10318 .channel_mode = alc882_ch_modes,
10319 .input_mux = &alc882_capture_source,
10320 .unsol_event = alc_sku_unsol_event,
10321 .setup = alc885_imac24_setup,
10322 .init_hook = alc885_imac24_init_hook,
10324 [ALC885_IMAC91] = {
10325 .mixers = {alc885_imac91_mixer},
10326 .init_verbs = { alc885_imac91_init_verbs,
10327 alc880_gpio1_init_verbs },
10328 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10329 .dac_nids = alc882_dac_nids,
10330 .channel_mode = alc885_mba21_ch_modes,
10331 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10332 .input_mux = &alc889A_imac91_capture_source,
10333 .dig_out_nid = ALC882_DIGOUT_NID,
10334 .dig_in_nid = ALC882_DIGIN_NID,
10335 .unsol_event = alc_sku_unsol_event,
10336 .setup = alc885_imac91_setup,
10337 .init_hook = alc_hp_automute,
10340 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10341 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10342 alc880_gpio3_init_verbs, alc882_targa_verbs},
10343 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10344 .dac_nids = alc882_dac_nids,
10345 .dig_out_nid = ALC882_DIGOUT_NID,
10346 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10347 .adc_nids = alc882_adc_nids,
10348 .capsrc_nids = alc882_capsrc_nids,
10349 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10350 .channel_mode = alc882_3ST_6ch_modes,
10352 .input_mux = &alc882_capture_source,
10353 .unsol_event = alc_sku_unsol_event,
10354 .setup = alc882_targa_setup,
10355 .init_hook = alc882_targa_automute,
10357 [ALC882_ASUS_A7J] = {
10358 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10359 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10360 alc882_asus_a7j_verbs},
10361 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10362 .dac_nids = alc882_dac_nids,
10363 .dig_out_nid = ALC882_DIGOUT_NID,
10364 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10365 .adc_nids = alc882_adc_nids,
10366 .capsrc_nids = alc882_capsrc_nids,
10367 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10368 .channel_mode = alc882_3ST_6ch_modes,
10370 .input_mux = &alc882_capture_source,
10372 [ALC882_ASUS_A7M] = {
10373 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10374 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10375 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10376 alc882_asus_a7m_verbs },
10377 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10378 .dac_nids = alc882_dac_nids,
10379 .dig_out_nid = ALC882_DIGOUT_NID,
10380 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10381 .channel_mode = alc880_threestack_modes,
10383 .input_mux = &alc882_capture_source,
10385 [ALC883_3ST_2ch_DIG] = {
10386 .mixers = { alc883_3ST_2ch_mixer },
10387 .init_verbs = { alc883_init_verbs },
10388 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10389 .dac_nids = alc883_dac_nids,
10390 .dig_out_nid = ALC883_DIGOUT_NID,
10391 .dig_in_nid = ALC883_DIGIN_NID,
10392 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10393 .channel_mode = alc883_3ST_2ch_modes,
10394 .input_mux = &alc883_capture_source,
10396 [ALC883_3ST_6ch_DIG] = {
10397 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10398 .init_verbs = { alc883_init_verbs },
10399 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10400 .dac_nids = alc883_dac_nids,
10401 .dig_out_nid = ALC883_DIGOUT_NID,
10402 .dig_in_nid = ALC883_DIGIN_NID,
10403 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10404 .channel_mode = alc883_3ST_6ch_modes,
10406 .input_mux = &alc883_capture_source,
10408 [ALC883_3ST_6ch] = {
10409 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10410 .init_verbs = { alc883_init_verbs },
10411 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10412 .dac_nids = alc883_dac_nids,
10413 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10414 .channel_mode = alc883_3ST_6ch_modes,
10416 .input_mux = &alc883_capture_source,
10418 [ALC883_3ST_6ch_INTEL] = {
10419 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10420 .init_verbs = { alc883_init_verbs },
10421 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10422 .dac_nids = alc883_dac_nids,
10423 .dig_out_nid = ALC883_DIGOUT_NID,
10424 .dig_in_nid = ALC883_DIGIN_NID,
10425 .slave_dig_outs = alc883_slave_dig_outs,
10426 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10427 .channel_mode = alc883_3ST_6ch_intel_modes,
10429 .input_mux = &alc883_3stack_6ch_intel,
10431 [ALC889A_INTEL] = {
10432 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10433 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10434 alc_hp15_unsol_verbs },
10435 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10436 .dac_nids = alc883_dac_nids,
10437 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10438 .adc_nids = alc889_adc_nids,
10439 .dig_out_nid = ALC883_DIGOUT_NID,
10440 .dig_in_nid = ALC883_DIGIN_NID,
10441 .slave_dig_outs = alc883_slave_dig_outs,
10442 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10443 .channel_mode = alc889_8ch_intel_modes,
10444 .capsrc_nids = alc889_capsrc_nids,
10445 .input_mux = &alc889_capture_source,
10446 .setup = alc889_automute_setup,
10447 .init_hook = alc_hp_automute,
10448 .unsol_event = alc_sku_unsol_event,
10452 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10453 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10454 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10455 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10456 .dac_nids = alc883_dac_nids,
10457 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10458 .adc_nids = alc889_adc_nids,
10459 .dig_out_nid = ALC883_DIGOUT_NID,
10460 .dig_in_nid = ALC883_DIGIN_NID,
10461 .slave_dig_outs = alc883_slave_dig_outs,
10462 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10463 .channel_mode = alc889_8ch_intel_modes,
10464 .capsrc_nids = alc889_capsrc_nids,
10465 .input_mux = &alc889_capture_source,
10466 .setup = alc889_automute_setup,
10467 .init_hook = alc889_intel_init_hook,
10468 .unsol_event = alc_sku_unsol_event,
10471 [ALC883_6ST_DIG] = {
10472 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10473 .init_verbs = { alc883_init_verbs },
10474 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10475 .dac_nids = alc883_dac_nids,
10476 .dig_out_nid = ALC883_DIGOUT_NID,
10477 .dig_in_nid = ALC883_DIGIN_NID,
10478 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10479 .channel_mode = alc883_sixstack_modes,
10480 .input_mux = &alc883_capture_source,
10482 [ALC883_TARGA_DIG] = {
10483 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10484 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10485 alc883_targa_verbs},
10486 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10487 .dac_nids = alc883_dac_nids,
10488 .dig_out_nid = ALC883_DIGOUT_NID,
10489 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10490 .channel_mode = alc883_3ST_6ch_modes,
10492 .input_mux = &alc883_capture_source,
10493 .unsol_event = alc883_targa_unsol_event,
10494 .setup = alc882_targa_setup,
10495 .init_hook = alc882_targa_automute,
10497 [ALC883_TARGA_2ch_DIG] = {
10498 .mixers = { alc883_targa_2ch_mixer},
10499 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10500 alc883_targa_verbs},
10501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10502 .dac_nids = alc883_dac_nids,
10503 .adc_nids = alc883_adc_nids_alt,
10504 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10505 .capsrc_nids = alc883_capsrc_nids,
10506 .dig_out_nid = ALC883_DIGOUT_NID,
10507 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10508 .channel_mode = alc883_3ST_2ch_modes,
10509 .input_mux = &alc883_capture_source,
10510 .unsol_event = alc883_targa_unsol_event,
10511 .setup = alc882_targa_setup,
10512 .init_hook = alc882_targa_automute,
10514 [ALC883_TARGA_8ch_DIG] = {
10515 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10516 alc883_chmode_mixer },
10517 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10518 alc883_targa_verbs },
10519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10520 .dac_nids = alc883_dac_nids,
10521 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10522 .adc_nids = alc883_adc_nids_rev,
10523 .capsrc_nids = alc883_capsrc_nids_rev,
10524 .dig_out_nid = ALC883_DIGOUT_NID,
10525 .dig_in_nid = ALC883_DIGIN_NID,
10526 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10527 .channel_mode = alc883_4ST_8ch_modes,
10529 .input_mux = &alc883_capture_source,
10530 .unsol_event = alc883_targa_unsol_event,
10531 .setup = alc882_targa_setup,
10532 .init_hook = alc882_targa_automute,
10535 .mixers = { alc883_base_mixer },
10536 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10537 * and the headphone jack. Turn this on and rely on the
10538 * standard mute methods whenever the user wants to turn
10539 * these outputs off.
10541 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10542 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10543 .dac_nids = alc883_dac_nids,
10544 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10545 .channel_mode = alc883_3ST_2ch_modes,
10546 .input_mux = &alc883_capture_source,
10548 [ALC883_ACER_ASPIRE] = {
10549 .mixers = { alc883_acer_aspire_mixer },
10550 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552 .dac_nids = alc883_dac_nids,
10553 .dig_out_nid = ALC883_DIGOUT_NID,
10554 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10555 .channel_mode = alc883_3ST_2ch_modes,
10556 .input_mux = &alc883_capture_source,
10557 .unsol_event = alc_sku_unsol_event,
10558 .setup = alc883_acer_aspire_setup,
10559 .init_hook = alc_hp_automute,
10561 [ALC888_ACER_ASPIRE_4930G] = {
10562 .mixers = { alc888_acer_aspire_4930g_mixer,
10563 alc883_chmode_mixer },
10564 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10565 alc888_acer_aspire_4930g_verbs },
10566 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10567 .dac_nids = alc883_dac_nids,
10568 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10569 .adc_nids = alc883_adc_nids_rev,
10570 .capsrc_nids = alc883_capsrc_nids_rev,
10571 .dig_out_nid = ALC883_DIGOUT_NID,
10572 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10573 .channel_mode = alc883_3ST_6ch_modes,
10575 .const_channel_count = 6,
10577 ARRAY_SIZE(alc888_2_capture_sources),
10578 .input_mux = alc888_2_capture_sources,
10579 .unsol_event = alc_sku_unsol_event,
10580 .setup = alc888_acer_aspire_4930g_setup,
10581 .init_hook = alc_hp_automute,
10583 [ALC888_ACER_ASPIRE_6530G] = {
10584 .mixers = { alc888_acer_aspire_6530_mixer },
10585 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10586 alc888_acer_aspire_6530g_verbs },
10587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10588 .dac_nids = alc883_dac_nids,
10589 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10590 .adc_nids = alc883_adc_nids_rev,
10591 .capsrc_nids = alc883_capsrc_nids_rev,
10592 .dig_out_nid = ALC883_DIGOUT_NID,
10593 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10594 .channel_mode = alc883_3ST_2ch_modes,
10596 ARRAY_SIZE(alc888_2_capture_sources),
10597 .input_mux = alc888_acer_aspire_6530_sources,
10598 .unsol_event = alc_sku_unsol_event,
10599 .setup = alc888_acer_aspire_6530g_setup,
10600 .init_hook = alc_hp_automute,
10602 [ALC888_ACER_ASPIRE_8930G] = {
10603 .mixers = { alc889_acer_aspire_8930g_mixer,
10604 alc883_chmode_mixer },
10605 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10606 alc889_acer_aspire_8930g_verbs,
10607 alc889_eapd_verbs},
10608 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10609 .dac_nids = alc883_dac_nids,
10610 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10611 .adc_nids = alc889_adc_nids,
10612 .capsrc_nids = alc889_capsrc_nids,
10613 .dig_out_nid = ALC883_DIGOUT_NID,
10614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10615 .channel_mode = alc883_3ST_6ch_modes,
10617 .const_channel_count = 6,
10619 ARRAY_SIZE(alc889_capture_sources),
10620 .input_mux = alc889_capture_sources,
10621 .unsol_event = alc_sku_unsol_event,
10622 .setup = alc889_acer_aspire_8930g_setup,
10623 .init_hook = alc_hp_automute,
10624 #ifdef CONFIG_SND_HDA_POWER_SAVE
10625 .power_hook = alc_power_eapd,
10628 [ALC888_ACER_ASPIRE_7730G] = {
10629 .mixers = { alc883_3ST_6ch_mixer,
10630 alc883_chmode_mixer },
10631 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10632 alc888_acer_aspire_7730G_verbs },
10633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10634 .dac_nids = alc883_dac_nids,
10635 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10636 .adc_nids = alc883_adc_nids_rev,
10637 .capsrc_nids = alc883_capsrc_nids_rev,
10638 .dig_out_nid = ALC883_DIGOUT_NID,
10639 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10640 .channel_mode = alc883_3ST_6ch_modes,
10642 .const_channel_count = 6,
10643 .input_mux = &alc883_capture_source,
10644 .unsol_event = alc_sku_unsol_event,
10645 .setup = alc888_acer_aspire_7730g_setup,
10646 .init_hook = alc_hp_automute,
10648 [ALC883_MEDION] = {
10649 .mixers = { alc883_fivestack_mixer,
10650 alc883_chmode_mixer },
10651 .init_verbs = { alc883_init_verbs,
10652 alc883_medion_eapd_verbs },
10653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10654 .dac_nids = alc883_dac_nids,
10655 .adc_nids = alc883_adc_nids_alt,
10656 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10657 .capsrc_nids = alc883_capsrc_nids,
10658 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10659 .channel_mode = alc883_sixstack_modes,
10660 .input_mux = &alc883_capture_source,
10662 [ALC883_MEDION_WIM2160] = {
10663 .mixers = { alc883_medion_wim2160_mixer },
10664 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10665 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10666 .dac_nids = alc883_dac_nids,
10667 .dig_out_nid = ALC883_DIGOUT_NID,
10668 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10669 .adc_nids = alc883_adc_nids,
10670 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10671 .channel_mode = alc883_3ST_2ch_modes,
10672 .input_mux = &alc883_capture_source,
10673 .unsol_event = alc_sku_unsol_event,
10674 .setup = alc883_medion_wim2160_setup,
10675 .init_hook = alc_hp_automute,
10677 [ALC883_LAPTOP_EAPD] = {
10678 .mixers = { alc883_base_mixer },
10679 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10680 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10681 .dac_nids = alc883_dac_nids,
10682 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10683 .channel_mode = alc883_3ST_2ch_modes,
10684 .input_mux = &alc883_capture_source,
10686 [ALC883_CLEVO_M540R] = {
10687 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10688 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10689 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10690 .dac_nids = alc883_dac_nids,
10691 .dig_out_nid = ALC883_DIGOUT_NID,
10692 .dig_in_nid = ALC883_DIGIN_NID,
10693 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10694 .channel_mode = alc883_3ST_6ch_clevo_modes,
10696 .input_mux = &alc883_capture_source,
10697 /* This machine has the hardware HP auto-muting, thus
10698 * we need no software mute via unsol event
10701 [ALC883_CLEVO_M720] = {
10702 .mixers = { alc883_clevo_m720_mixer },
10703 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10704 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10705 .dac_nids = alc883_dac_nids,
10706 .dig_out_nid = ALC883_DIGOUT_NID,
10707 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10708 .channel_mode = alc883_3ST_2ch_modes,
10709 .input_mux = &alc883_capture_source,
10710 .unsol_event = alc883_clevo_m720_unsol_event,
10711 .setup = alc883_clevo_m720_setup,
10712 .init_hook = alc883_clevo_m720_init_hook,
10714 [ALC883_LENOVO_101E_2ch] = {
10715 .mixers = { alc883_lenovo_101e_2ch_mixer},
10716 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10717 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10718 .dac_nids = alc883_dac_nids,
10719 .adc_nids = alc883_adc_nids_alt,
10720 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10721 .capsrc_nids = alc883_capsrc_nids,
10722 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10723 .channel_mode = alc883_3ST_2ch_modes,
10724 .input_mux = &alc883_lenovo_101e_capture_source,
10725 .setup = alc883_lenovo_101e_setup,
10726 .unsol_event = alc_sku_unsol_event,
10727 .init_hook = alc_inithook,
10729 [ALC883_LENOVO_NB0763] = {
10730 .mixers = { alc883_lenovo_nb0763_mixer },
10731 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10732 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10733 .dac_nids = alc883_dac_nids,
10734 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10735 .channel_mode = alc883_3ST_2ch_modes,
10737 .input_mux = &alc883_lenovo_nb0763_capture_source,
10738 .unsol_event = alc_sku_unsol_event,
10739 .setup = alc883_lenovo_nb0763_setup,
10740 .init_hook = alc_hp_automute,
10742 [ALC888_LENOVO_MS7195_DIG] = {
10743 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10744 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10745 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10746 .dac_nids = alc883_dac_nids,
10747 .dig_out_nid = ALC883_DIGOUT_NID,
10748 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10749 .channel_mode = alc883_3ST_6ch_modes,
10751 .input_mux = &alc883_capture_source,
10752 .unsol_event = alc_sku_unsol_event,
10753 .setup = alc888_lenovo_ms7195_setup,
10754 .init_hook = alc_inithook,
10756 [ALC883_HAIER_W66] = {
10757 .mixers = { alc883_targa_2ch_mixer},
10758 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10760 .dac_nids = alc883_dac_nids,
10761 .dig_out_nid = ALC883_DIGOUT_NID,
10762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10763 .channel_mode = alc883_3ST_2ch_modes,
10764 .input_mux = &alc883_capture_source,
10765 .unsol_event = alc_sku_unsol_event,
10766 .setup = alc883_haier_w66_setup,
10767 .init_hook = alc_hp_automute,
10769 [ALC888_3ST_HP] = {
10770 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10771 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10772 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10773 .dac_nids = alc883_dac_nids,
10774 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10775 .channel_mode = alc888_3st_hp_modes,
10777 .input_mux = &alc883_capture_source,
10778 .unsol_event = alc_sku_unsol_event,
10779 .setup = alc888_3st_hp_setup,
10780 .init_hook = alc_hp_automute,
10782 [ALC888_6ST_DELL] = {
10783 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10784 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10786 .dac_nids = alc883_dac_nids,
10787 .dig_out_nid = ALC883_DIGOUT_NID,
10788 .dig_in_nid = ALC883_DIGIN_NID,
10789 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10790 .channel_mode = alc883_sixstack_modes,
10791 .input_mux = &alc883_capture_source,
10792 .unsol_event = alc_sku_unsol_event,
10793 .setup = alc888_6st_dell_setup,
10794 .init_hook = alc_hp_automute,
10797 .mixers = { alc883_mitac_mixer },
10798 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10799 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10800 .dac_nids = alc883_dac_nids,
10801 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10802 .channel_mode = alc883_3ST_2ch_modes,
10803 .input_mux = &alc883_capture_source,
10804 .unsol_event = alc_sku_unsol_event,
10805 .setup = alc883_mitac_setup,
10806 .init_hook = alc_hp_automute,
10808 [ALC883_FUJITSU_PI2515] = {
10809 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10810 .init_verbs = { alc883_init_verbs,
10811 alc883_2ch_fujitsu_pi2515_verbs},
10812 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10813 .dac_nids = alc883_dac_nids,
10814 .dig_out_nid = ALC883_DIGOUT_NID,
10815 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10816 .channel_mode = alc883_3ST_2ch_modes,
10817 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10818 .unsol_event = alc_sku_unsol_event,
10819 .setup = alc883_2ch_fujitsu_pi2515_setup,
10820 .init_hook = alc_hp_automute,
10822 [ALC888_FUJITSU_XA3530] = {
10823 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10824 .init_verbs = { alc883_init_verbs,
10825 alc888_fujitsu_xa3530_verbs },
10826 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10827 .dac_nids = alc883_dac_nids,
10828 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10829 .adc_nids = alc883_adc_nids_rev,
10830 .capsrc_nids = alc883_capsrc_nids_rev,
10831 .dig_out_nid = ALC883_DIGOUT_NID,
10832 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10833 .channel_mode = alc888_4ST_8ch_intel_modes,
10835 ARRAY_SIZE(alc888_2_capture_sources),
10836 .input_mux = alc888_2_capture_sources,
10837 .unsol_event = alc_sku_unsol_event,
10838 .setup = alc888_fujitsu_xa3530_setup,
10839 .init_hook = alc_hp_automute,
10841 [ALC888_LENOVO_SKY] = {
10842 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10843 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845 .dac_nids = alc883_dac_nids,
10846 .dig_out_nid = ALC883_DIGOUT_NID,
10847 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10848 .channel_mode = alc883_sixstack_modes,
10850 .input_mux = &alc883_lenovo_sky_capture_source,
10851 .unsol_event = alc_sku_unsol_event,
10852 .setup = alc888_lenovo_sky_setup,
10853 .init_hook = alc_hp_automute,
10855 [ALC888_ASUS_M90V] = {
10856 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10857 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10859 .dac_nids = alc883_dac_nids,
10860 .dig_out_nid = ALC883_DIGOUT_NID,
10861 .dig_in_nid = ALC883_DIGIN_NID,
10862 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10863 .channel_mode = alc883_3ST_6ch_modes,
10865 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10866 .unsol_event = alc_sku_unsol_event,
10867 .setup = alc883_mode2_setup,
10868 .init_hook = alc_inithook,
10870 [ALC888_ASUS_EEE1601] = {
10871 .mixers = { alc883_asus_eee1601_mixer },
10872 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10873 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10874 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10875 .dac_nids = alc883_dac_nids,
10876 .dig_out_nid = ALC883_DIGOUT_NID,
10877 .dig_in_nid = ALC883_DIGIN_NID,
10878 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10879 .channel_mode = alc883_3ST_2ch_modes,
10881 .input_mux = &alc883_asus_eee1601_capture_source,
10882 .unsol_event = alc_sku_unsol_event,
10883 .init_hook = alc883_eee1601_inithook,
10885 [ALC1200_ASUS_P5Q] = {
10886 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10887 .init_verbs = { alc883_init_verbs },
10888 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10889 .dac_nids = alc883_dac_nids,
10890 .dig_out_nid = ALC1200_DIGOUT_NID,
10891 .dig_in_nid = ALC883_DIGIN_NID,
10892 .slave_dig_outs = alc1200_slave_dig_outs,
10893 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10894 .channel_mode = alc883_sixstack_modes,
10895 .input_mux = &alc883_capture_source,
10898 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10899 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10900 alc880_gpio1_init_verbs },
10901 .adc_nids = alc883_adc_nids,
10902 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10903 .capsrc_nids = alc883_capsrc_nids,
10904 .dac_nids = alc883_dac_nids,
10905 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10906 .channel_mode = alc889A_mb31_6ch_modes,
10907 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10908 .input_mux = &alc889A_mb31_capture_source,
10909 .dig_out_nid = ALC883_DIGOUT_NID,
10910 .unsol_event = alc889A_mb31_unsol_event,
10911 .init_hook = alc889A_mb31_automute,
10913 [ALC883_SONY_VAIO_TT] = {
10914 .mixers = { alc883_vaiott_mixer },
10915 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10916 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10917 .dac_nids = alc883_dac_nids,
10918 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10919 .channel_mode = alc883_3ST_2ch_modes,
10920 .input_mux = &alc883_capture_source,
10921 .unsol_event = alc_sku_unsol_event,
10922 .setup = alc883_vaiott_setup,
10923 .init_hook = alc_hp_automute,
10932 PINFIX_ABIT_AW9D_MAX,
10933 PINFIX_LENOVO_Y530,
10935 PINFIX_ACER_ASPIRE_7736,
10938 static const struct alc_fixup alc882_fixups[] = {
10939 [PINFIX_ABIT_AW9D_MAX] = {
10940 .type = ALC_FIXUP_PINS,
10941 .v.pins = (const struct alc_pincfg[]) {
10942 { 0x15, 0x01080104 }, /* side */
10943 { 0x16, 0x01011012 }, /* rear */
10944 { 0x17, 0x01016011 }, /* clfe */
10948 [PINFIX_LENOVO_Y530] = {
10949 .type = ALC_FIXUP_PINS,
10950 .v.pins = (const struct alc_pincfg[]) {
10951 { 0x15, 0x99130112 }, /* rear int speakers */
10952 { 0x16, 0x99130111 }, /* subwoofer */
10956 [PINFIX_PB_M5210] = {
10957 .type = ALC_FIXUP_VERBS,
10958 .v.verbs = (const struct hda_verb[]) {
10959 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10963 [PINFIX_ACER_ASPIRE_7736] = {
10964 .type = ALC_FIXUP_SKU,
10965 .v.sku = ALC_FIXUP_SKU_IGNORE,
10969 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10970 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10971 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10972 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10973 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10978 * BIOS auto configuration
10980 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10981 const struct auto_pin_cfg *cfg)
10983 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10986 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10987 hda_nid_t nid, int pin_type,
10992 /* set as output */
10993 alc_set_pin_output(codec, nid, pin_type);
10995 if (snd_hda_get_conn_list(codec, nid, NULL) < 2)
11000 else if (dac >= 0x02 && dac <= 0x05)
11004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11007 #define alc882_auto_init_dac alc880_auto_init_dac
11009 static void alc882_auto_init_multi_out(struct hda_codec *codec)
11011 struct alc_spec *spec = codec->spec;
11014 for (i = 0; i <= HDA_SIDE; i++) {
11015 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11016 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11018 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11019 spec->multiout.dac_nids[i]);
11022 for (i = 0; i < spec->multiout.num_dacs; i++)
11023 alc882_auto_init_dac(codec, spec->multiout.dac_nids[i]);
11026 static void alc882_auto_init_hp_out(struct hda_codec *codec)
11028 struct alc_spec *spec = codec->spec;
11029 hda_nid_t pin, dac;
11032 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11033 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11034 pin = spec->autocfg.hp_pins[i];
11037 dac = spec->multiout.hp_nid;
11039 dac = spec->multiout.dac_nids[0]; /* to front */
11040 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11044 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11045 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11046 pin = spec->autocfg.speaker_pins[i];
11049 dac = spec->multiout.extra_out_nid[0];
11051 dac = spec->multiout.dac_nids[0]; /* to front */
11052 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11057 alc882_auto_init_dac(codec, spec->multiout.hp_nid);
11058 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
11059 alc882_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
11062 #define alc882_auto_init_analog_input alc880_auto_init_analog_input
11064 static void alc882_auto_init_input_src(struct hda_codec *codec)
11066 struct alc_spec *spec = codec->spec;
11069 for (c = 0; c < spec->num_adc_nids; c++) {
11070 hda_nid_t nid = spec->capsrc_nids[c];
11071 unsigned int mux_idx;
11072 const struct hda_input_mux *imux;
11073 int conns, mute, idx, item;
11076 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11077 AC_VERB_SET_AMP_GAIN_MUTE,
11080 conns = snd_hda_get_conn_list(codec, nid, NULL);
11083 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11084 imux = &spec->input_mux[mux_idx];
11085 if (!imux->num_items && mux_idx > 0)
11086 imux = &spec->input_mux[0];
11087 for (idx = 0; idx < conns; idx++) {
11088 /* if the current connection is the selected one,
11089 * unmute it as default - otherwise mute it
11091 mute = AMP_IN_MUTE(idx);
11092 for (item = 0; item < imux->num_items; item++) {
11093 if (imux->items[item].index == idx) {
11094 if (spec->cur_mux[c] == item)
11095 mute = AMP_IN_UNMUTE(idx);
11099 /* check if we have a selector or mixer
11100 * we could check for the widget type instead, but
11101 * just check for Amp-In presence (in case of mixer
11102 * without amp-in there is something wrong, this
11103 * function shouldn't be used or capsrc nid is wrong)
11105 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11106 snd_hda_codec_write(codec, nid, 0,
11107 AC_VERB_SET_AMP_GAIN_MUTE,
11109 else if (mute != AMP_IN_MUTE(idx))
11110 snd_hda_codec_write(codec, nid, 0,
11111 AC_VERB_SET_CONNECT_SEL,
11117 /* add mic boosts if needed */
11118 static int alc_auto_add_mic_boost(struct hda_codec *codec)
11120 struct alc_spec *spec = codec->spec;
11121 struct auto_pin_cfg *cfg = &spec->autocfg;
11125 const char *prev_label = NULL;
11127 for (i = 0; i < cfg->num_inputs; i++) {
11128 if (cfg->inputs[i].type > AUTO_PIN_MIC)
11130 nid = cfg->inputs[i].pin;
11131 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11133 char boost_label[32];
11135 label = hda_get_autocfg_input_label(codec, cfg, i);
11136 if (prev_label && !strcmp(label, prev_label))
11140 prev_label = label;
11142 snprintf(boost_label, sizeof(boost_label),
11143 "%s Boost Volume", label);
11144 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11145 boost_label, type_idx,
11146 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11154 /* almost identical with ALC880 parser... */
11155 static int alc882_parse_auto_config(struct hda_codec *codec)
11157 struct alc_spec *spec = codec->spec;
11158 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11161 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11165 if (!spec->autocfg.line_outs)
11166 return 0; /* can't find valid BIOS pin config */
11168 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11171 err = alc_auto_add_multi_channel_mode(codec);
11174 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11177 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11181 err = alc880_auto_create_extra_out(spec,
11182 spec->autocfg.speaker_pins[0],
11186 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11190 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11192 alc_auto_parse_digital(codec);
11194 if (spec->kctls.list)
11195 add_mixer(spec, spec->kctls.list);
11197 /* if ADC 0x07 is available, initialize it, too */
11198 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11199 add_verb(spec, alc882_adc1_init_verbs);
11201 spec->num_mux_defs = 1;
11202 spec->input_mux = &spec->private_imux[0];
11204 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11206 err = alc_auto_add_mic_boost(codec);
11210 return 1; /* config found */
11213 /* additional initialization for auto-configuration model */
11214 static void alc882_auto_init(struct hda_codec *codec)
11216 struct alc_spec *spec = codec->spec;
11217 alc882_auto_init_multi_out(codec);
11218 alc882_auto_init_hp_out(codec);
11219 alc882_auto_init_analog_input(codec);
11220 alc882_auto_init_input_src(codec);
11221 alc_auto_init_digital(codec);
11222 if (spec->unsol_event)
11223 alc_inithook(codec);
11226 static int patch_alc882(struct hda_codec *codec)
11228 struct alc_spec *spec;
11229 int err, board_config;
11231 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11235 codec->spec = spec;
11237 spec->mixer_nid = 0x0b;
11239 switch (codec->vendor_id) {
11244 /* ALC883 and variants */
11245 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11249 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11253 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11254 board_config = snd_hda_check_board_codec_sid_config(codec,
11255 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11257 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11258 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11260 board_config = ALC882_AUTO;
11263 if (board_config == ALC882_AUTO) {
11264 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11265 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11268 alc_auto_parse_customize_define(codec);
11270 if (board_config == ALC882_AUTO) {
11271 /* automatic parse from the BIOS config */
11272 err = alc882_parse_auto_config(codec);
11278 "hda_codec: Cannot set up configuration "
11279 "from BIOS. Using base mode...\n");
11280 board_config = ALC882_3ST_DIG;
11284 if (has_cdefine_beep(codec)) {
11285 err = snd_hda_attach_beep_device(codec, 0x1);
11292 if (board_config != ALC882_AUTO)
11293 setup_preset(codec, &alc882_presets[board_config]);
11295 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11296 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11297 /* FIXME: setup DAC5 */
11298 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11299 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11301 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11302 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11304 if (!spec->adc_nids && spec->input_mux) {
11306 spec->num_adc_nids = 0;
11307 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11308 const struct hda_input_mux *imux = spec->input_mux;
11310 hda_nid_t nid = alc882_adc_nids[i];
11311 unsigned int wcap = get_wcaps(codec, nid);
11313 wcap = get_wcaps_type(wcap);
11314 if (wcap != AC_WID_AUD_IN)
11316 spec->private_adc_nids[spec->num_adc_nids] = nid;
11317 err = snd_hda_get_connections(codec, nid, &cap, 1);
11320 err = snd_hda_get_conn_list(codec, cap, NULL);
11323 for (j = 0; j < imux->num_items; j++)
11324 if (imux->items[j].index >= err)
11326 if (j < imux->num_items)
11328 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11329 spec->num_adc_nids++;
11331 spec->adc_nids = spec->private_adc_nids;
11332 spec->capsrc_nids = spec->private_capsrc_nids;
11335 set_capture_mixer(codec);
11337 if (has_cdefine_beep(codec))
11338 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11340 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11342 spec->vmaster_nid = 0x0c;
11344 codec->patch_ops = alc_patch_ops;
11345 if (board_config == ALC882_AUTO)
11346 spec->init_hook = alc882_auto_init;
11348 alc_init_jacks(codec);
11349 #ifdef CONFIG_SND_HDA_POWER_SAVE
11350 if (!spec->loopback.amplist)
11351 spec->loopback.amplist = alc882_loopbacks;
11362 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11363 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11365 #define alc262_dac_nids alc260_dac_nids
11366 #define alc262_adc_nids alc882_adc_nids
11367 #define alc262_adc_nids_alt alc882_adc_nids_alt
11368 #define alc262_capsrc_nids alc882_capsrc_nids
11369 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11371 #define alc262_modes alc260_modes
11372 #define alc262_capture_source alc882_capture_source
11374 static const hda_nid_t alc262_dmic_adc_nids[1] = {
11379 static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11381 static const struct snd_kcontrol_new alc262_base_mixer[] = {
11382 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11383 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11384 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11385 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11386 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11387 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11390 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11393 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11394 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11396 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11397 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11401 /* update HP, line and mono-out pins according to the master switch */
11402 #define alc262_hp_master_update alc260_hp_master_update
11404 static void alc262_hp_bpc_setup(struct hda_codec *codec)
11406 struct alc_spec *spec = codec->spec;
11408 spec->autocfg.hp_pins[0] = 0x1b;
11409 spec->autocfg.speaker_pins[0] = 0x16;
11410 spec->automute = 1;
11411 spec->automute_mode = ALC_AUTOMUTE_PIN;
11414 static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11416 struct alc_spec *spec = codec->spec;
11418 spec->autocfg.hp_pins[0] = 0x15;
11419 spec->autocfg.speaker_pins[0] = 0x16;
11420 spec->automute = 1;
11421 spec->automute_mode = ALC_AUTOMUTE_PIN;
11424 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11425 #define alc262_hp_master_sw_put alc260_hp_master_sw_put
11427 #define ALC262_HP_MASTER_SWITCH \
11429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11430 .name = "Master Playback Switch", \
11431 .info = snd_ctl_boolean_mono_info, \
11432 .get = alc262_hp_master_sw_get, \
11433 .put = alc262_hp_master_sw_put, \
11436 .iface = NID_MAPPING, \
11437 .name = "Master Playback Switch", \
11438 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11442 static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11443 ALC262_HP_MASTER_SWITCH,
11444 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11449 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11458 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11461 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11462 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11466 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11467 ALC262_HP_MASTER_SWITCH,
11468 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11469 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11470 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11471 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11472 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11474 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11476 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11477 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11478 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11479 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11480 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11481 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11482 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11486 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11487 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11488 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11489 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11493 /* mute/unmute internal speaker according to the hp jack and mute state */
11494 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11496 struct alc_spec *spec = codec->spec;
11498 spec->autocfg.hp_pins[0] = 0x15;
11499 spec->autocfg.speaker_pins[0] = 0x14;
11500 spec->automute = 1;
11501 spec->automute_mode = ALC_AUTOMUTE_PIN;
11504 static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11505 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11506 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11507 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11511 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11515 static const struct hda_verb alc262_hp_t5735_verbs[] = {
11516 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11519 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11523 static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11524 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11525 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11526 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11527 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11528 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11529 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11533 static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11534 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11535 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11536 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11537 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11538 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11539 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11540 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11542 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11547 static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11554 /* bind hp and internal speaker mute (with plug check) as master switch */
11555 #define alc262_hippo_master_update alc262_hp_master_update
11556 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11557 #define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11559 #define ALC262_HIPPO_MASTER_SWITCH \
11561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11562 .name = "Master Playback Switch", \
11563 .info = snd_ctl_boolean_mono_info, \
11564 .get = alc262_hippo_master_sw_get, \
11565 .put = alc262_hippo_master_sw_put, \
11568 .iface = NID_MAPPING, \
11569 .name = "Master Playback Switch", \
11570 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11571 (SUBDEV_SPEAKER(0) << 16), \
11574 static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11575 ALC262_HIPPO_MASTER_SWITCH,
11576 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11579 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11580 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11581 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11584 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11585 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11586 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11591 static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11592 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11593 ALC262_HIPPO_MASTER_SWITCH,
11594 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11595 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11596 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11597 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11600 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11601 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11602 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11603 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11607 /* mute/unmute internal speaker according to the hp jack and mute state */
11608 static void alc262_hippo_setup(struct hda_codec *codec)
11610 struct alc_spec *spec = codec->spec;
11612 spec->autocfg.hp_pins[0] = 0x15;
11613 spec->autocfg.speaker_pins[0] = 0x14;
11614 spec->automute = 1;
11615 spec->automute_mode = ALC_AUTOMUTE_AMP;
11618 static void alc262_hippo1_setup(struct hda_codec *codec)
11620 struct alc_spec *spec = codec->spec;
11622 spec->autocfg.hp_pins[0] = 0x1b;
11623 spec->autocfg.speaker_pins[0] = 0x14;
11624 spec->automute = 1;
11625 spec->automute_mode = ALC_AUTOMUTE_AMP;
11629 static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11630 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11631 ALC262_HIPPO_MASTER_SWITCH,
11632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11634 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11635 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11639 static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11640 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11641 ALC262_HIPPO_MASTER_SWITCH,
11642 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11643 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11645 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11646 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11650 static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11651 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11652 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11653 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11654 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11656 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11660 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11661 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11662 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11666 static const struct hda_verb alc262_tyan_verbs[] = {
11667 /* Headphone automute */
11668 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11670 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11672 /* P11 AUX_IN, white 4-pin connector */
11673 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11674 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11675 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11676 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11681 /* unsolicited event for HP jack sensing */
11682 static void alc262_tyan_setup(struct hda_codec *codec)
11684 struct alc_spec *spec = codec->spec;
11686 spec->autocfg.hp_pins[0] = 0x1b;
11687 spec->autocfg.speaker_pins[0] = 0x15;
11688 spec->automute = 1;
11689 spec->automute_mode = ALC_AUTOMUTE_AMP;
11693 #define alc262_capture_mixer alc882_capture_mixer
11694 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11697 * generic initialization of ADC, input mixers and output mixers
11699 static const struct hda_verb alc262_init_verbs[] = {
11701 * Unmute ADC0-2 and set the default input to mic-in
11703 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11705 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11706 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11707 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11708 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11710 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11712 * Note: PASD motherboards uses the Line In 2 as the input for
11713 * front panel mic (mic 2)
11715 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11723 * Set up output mixers (0x0c - 0x0e)
11725 /* set vol=0 to output mixers */
11726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11729 /* set up input amps for analog loopback */
11730 /* Amp Indices: DAC = 0, mixer = 1 */
11731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11733 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11734 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11736 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11739 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11740 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11741 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11742 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11743 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11747 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11751 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11752 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11754 /* FIXME: use matrix-type input source selection */
11755 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11756 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11775 static const struct hda_verb alc262_eapd_verbs[] = {
11776 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11777 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11781 static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11782 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11783 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11786 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11791 static const struct hda_verb alc262_sony_unsol_verbs[] = {
11792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11794 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11796 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11801 static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11802 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11803 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11810 static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11811 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11813 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11814 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11815 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11816 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11817 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11818 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11822 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11824 struct alc_spec *spec = codec->spec;
11826 spec->autocfg.hp_pins[0] = 0x15;
11827 spec->autocfg.speaker_pins[0] = 0x14;
11828 spec->ext_mic.pin = 0x18;
11829 spec->ext_mic.mux_idx = 0;
11830 spec->int_mic.pin = 0x12;
11831 spec->int_mic.mux_idx = 9;
11832 spec->auto_mic = 1;
11833 spec->automute = 1;
11834 spec->automute_mode = ALC_AUTOMUTE_PIN;
11840 * 0x16 = internal speaker
11841 * 0x18 = external mic
11844 static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11845 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11846 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11850 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11857 static const struct hda_verb alc262_nec_verbs[] = {
11858 /* Unmute Speaker */
11859 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11865 /* External mic to headphone */
11866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11867 /* External mic to speaker */
11868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11874 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11875 * 0x1b = port replicator headphone out
11878 #define ALC_HP_EVENT ALC880_HP_EVENT
11880 static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11881 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11882 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11883 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11884 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11888 static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11889 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11890 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11894 static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11895 /* Front Mic pin: input vref at 50% */
11896 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11897 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11901 static const struct hda_input_mux alc262_fujitsu_capture_source = {
11905 { "Internal Mic", 0x1 },
11910 static const struct hda_input_mux alc262_HP_capture_source = {
11914 { "Front Mic", 0x1 },
11921 static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11925 { "Front Mic", 0x2 },
11931 static void alc262_fujitsu_setup(struct hda_codec *codec)
11933 struct alc_spec *spec = codec->spec;
11935 spec->autocfg.hp_pins[0] = 0x14;
11936 spec->autocfg.hp_pins[1] = 0x1b;
11937 spec->autocfg.speaker_pins[0] = 0x15;
11938 spec->automute = 1;
11939 spec->automute_mode = ALC_AUTOMUTE_AMP;
11942 /* bind volumes of both NID 0x0c and 0x0d */
11943 static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11944 .ops = &snd_hda_bind_vol,
11946 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11947 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11952 static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11953 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11956 .name = "Master Playback Switch",
11957 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11958 .info = snd_ctl_boolean_mono_info,
11959 .get = alc262_hp_master_sw_get,
11960 .put = alc262_hp_master_sw_put,
11963 .iface = NID_MAPPING,
11964 .name = "Master Playback Switch",
11965 .private_value = 0x1b,
11967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11969 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11971 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11972 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11973 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11974 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11978 static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11980 struct alc_spec *spec = codec->spec;
11982 spec->autocfg.hp_pins[0] = 0x1b;
11983 spec->autocfg.speaker_pins[0] = 0x14;
11984 spec->autocfg.speaker_pins[1] = 0x16;
11985 spec->automute = 1;
11986 spec->automute_mode = ALC_AUTOMUTE_AMP;
11989 static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11990 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11993 .name = "Master Playback Switch",
11994 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11995 .info = snd_ctl_boolean_mono_info,
11996 .get = alc262_hp_master_sw_get,
11997 .put = alc262_hp_master_sw_put,
11999 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12000 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12001 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12002 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12003 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12004 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12005 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12006 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12010 static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12011 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12012 ALC262_HIPPO_MASTER_SWITCH,
12013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12014 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12015 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12016 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12017 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12018 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12022 /* additional init verbs for Benq laptops */
12023 static const struct hda_verb alc262_EAPD_verbs[] = {
12024 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12025 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12029 static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12030 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12031 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12033 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12034 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12038 /* Samsung Q1 Ultra Vista model setup */
12039 static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12040 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12041 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12043 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12044 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12045 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12049 static const struct hda_verb alc262_ultra_verbs[] = {
12051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12053 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12057 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12058 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12061 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12063 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12064 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12066 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12068 /* ADC, choose mic */
12069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12071 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12082 /* mute/unmute internal speaker according to the hp jack and mute state */
12083 static void alc262_ultra_automute(struct hda_codec *codec)
12085 struct alc_spec *spec = codec->spec;
12089 /* auto-mute only when HP is used as HP */
12090 if (!spec->cur_mux[0]) {
12091 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12092 if (spec->jack_present)
12093 mute = HDA_AMP_MUTE;
12095 /* mute/unmute internal speaker */
12096 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12097 HDA_AMP_MUTE, mute);
12098 /* mute/unmute HP */
12099 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12100 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12103 /* unsolicited event for HP jack sensing */
12104 static void alc262_ultra_unsol_event(struct hda_codec *codec,
12107 if ((res >> 26) != ALC880_HP_EVENT)
12109 alc262_ultra_automute(codec);
12112 static const struct hda_input_mux alc262_ultra_capture_source = {
12116 { "Headphone", 0x7 },
12120 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12121 struct snd_ctl_elem_value *ucontrol)
12123 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12124 struct alc_spec *spec = codec->spec;
12127 ret = alc_mux_enum_put(kcontrol, ucontrol);
12130 /* reprogram the HP pin as mic or HP according to the input source */
12131 snd_hda_codec_write_cache(codec, 0x15, 0,
12132 AC_VERB_SET_PIN_WIDGET_CONTROL,
12133 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12134 alc262_ultra_automute(codec); /* mute/unmute HP */
12138 static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12139 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12140 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12143 .name = "Capture Source",
12144 .info = alc_mux_enum_info,
12145 .get = alc_mux_enum_get,
12146 .put = alc262_ultra_mux_enum_put,
12149 .iface = NID_MAPPING,
12150 .name = "Capture Source",
12151 .private_value = 0x15,
12156 /* We use two mixers depending on the output pin; 0x16 is a mono output
12157 * and thus it's bound with a different mixer.
12158 * This function returns which mixer amp should be used.
12160 static int alc262_check_volbit(hda_nid_t nid)
12164 else if (nid == 0x16)
12170 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12171 const char *pfx, int *vbits, int idx)
12176 vbit = alc262_check_volbit(nid);
12179 if (*vbits & vbit) /* a volume control for this mixer already there */
12183 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12185 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12186 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12189 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12190 const char *pfx, int idx)
12197 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12199 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12200 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12203 /* add playback controls from the parsed DAC table */
12204 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12205 const struct auto_pin_cfg *cfg)
12211 spec->multiout.num_dacs = 1; /* only use one dac */
12212 spec->multiout.dac_nids = spec->private_dac_nids;
12213 spec->private_dac_nids[0] = 2;
12215 for (i = 0; i < 2; i++) {
12216 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12219 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
12223 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12224 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12229 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12230 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12237 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12238 alc262_check_volbit(cfg->speaker_pins[0]) |
12239 alc262_check_volbit(cfg->hp_pins[0]);
12241 for (i = 0; i < 2; i++) {
12242 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12245 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12249 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12250 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12251 "Speaker", &vbits, i);
12255 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12256 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12257 "Headphone", &vbits, i);
12265 #define alc262_auto_create_input_ctls \
12266 alc882_auto_create_input_ctls
12268 static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12270 * Unmute ADC0-2 and set the default input to mic-in
12272 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12274 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12275 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12276 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12277 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12279 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12281 * Note: PASD motherboards uses the Line In 2 as the input for
12282 * front panel mic (mic 2)
12284 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12294 * Set up output mixers (0x0c - 0x0e)
12296 /* set vol=0 to output mixers */
12297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12301 /* set up input amps for analog loopback */
12302 /* Amp Indices: DAC = 0, mixer = 1 */
12303 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12305 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12306 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12310 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12312 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12314 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12317 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12320 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12321 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12322 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12323 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12324 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12327 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12328 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12329 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12330 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12331 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12334 /* FIXME: use matrix-type input source selection */
12335 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12336 /* Input mixer1: only unmute Mic */
12337 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12338 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12339 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12340 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12341 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12342 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12343 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12347 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12349 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12351 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12354 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12357 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12358 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12360 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12363 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12364 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12367 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12372 static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12374 * Unmute ADC0-2 and set the default input to mic-in
12376 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12377 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12378 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12380 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12383 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12385 * Note: PASD motherboards uses the Line In 2 as the input for front
12386 * panel mic (mic 2)
12388 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12389 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12390 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12391 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12392 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12393 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12394 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12398 * Set up output mixers (0x0c - 0x0e)
12400 /* set vol=0 to output mixers */
12401 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12405 /* set up input amps for analog loopback */
12406 /* Amp Indices: DAC = 0, mixer = 1 */
12407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12415 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12416 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12417 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12419 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12420 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12421 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12423 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12426 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12427 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12429 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12431 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12432 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12433 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12434 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12436 /* FIXME: use matrix-type input source selection */
12437 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12438 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12439 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12440 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12441 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12444 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12452 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12460 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12463 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12468 static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12470 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12471 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12472 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12475 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12476 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12477 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12479 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12480 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12481 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12493 static const struct alc_fixup alc262_fixups[] = {
12494 [PINFIX_FSC_H270] = {
12495 .type = ALC_FIXUP_PINS,
12496 .v.pins = (const struct alc_pincfg[]) {
12497 { 0x14, 0x99130110 }, /* speaker */
12498 { 0x15, 0x0221142f }, /* front HP */
12499 { 0x1b, 0x0121141f }, /* rear HP */
12503 [PINFIX_HP_Z200] = {
12504 .type = ALC_FIXUP_PINS,
12505 .v.pins = (const struct alc_pincfg[]) {
12506 { 0x16, 0x99130120 }, /* internal speaker */
12512 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12513 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12514 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12519 #ifdef CONFIG_SND_HDA_POWER_SAVE
12520 #define alc262_loopbacks alc880_loopbacks
12523 /* pcm configuration: identical with ALC880 */
12524 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12525 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12526 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12527 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12530 * BIOS auto configuration
12532 static int alc262_parse_auto_config(struct hda_codec *codec)
12534 struct alc_spec *spec = codec->spec;
12536 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12538 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12542 if (!spec->autocfg.line_outs) {
12543 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12544 spec->multiout.max_channels = 2;
12545 spec->no_analog = 1;
12548 return 0; /* can't find valid BIOS pin config */
12550 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12553 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12557 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12560 alc_auto_parse_digital(codec);
12562 if (spec->kctls.list)
12563 add_mixer(spec, spec->kctls.list);
12565 spec->num_mux_defs = 1;
12566 spec->input_mux = &spec->private_imux[0];
12568 err = alc_auto_add_mic_boost(codec);
12572 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12577 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12578 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12579 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12580 #define alc262_auto_init_input_src alc882_auto_init_input_src
12583 /* init callback for auto-configuration model -- overriding the default init */
12584 static void alc262_auto_init(struct hda_codec *codec)
12586 struct alc_spec *spec = codec->spec;
12587 alc262_auto_init_multi_out(codec);
12588 alc262_auto_init_hp_out(codec);
12589 alc262_auto_init_analog_input(codec);
12590 alc262_auto_init_input_src(codec);
12591 alc_auto_init_digital(codec);
12592 if (spec->unsol_event)
12593 alc_inithook(codec);
12597 * configuration and preset
12599 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12600 [ALC262_BASIC] = "basic",
12601 [ALC262_HIPPO] = "hippo",
12602 [ALC262_HIPPO_1] = "hippo_1",
12603 [ALC262_FUJITSU] = "fujitsu",
12604 [ALC262_HP_BPC] = "hp-bpc",
12605 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12606 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12607 [ALC262_HP_RP5700] = "hp-rp5700",
12608 [ALC262_BENQ_ED8] = "benq",
12609 [ALC262_BENQ_T31] = "benq-t31",
12610 [ALC262_SONY_ASSAMD] = "sony-assamd",
12611 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12612 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12613 [ALC262_ULTRA] = "ultra",
12614 [ALC262_LENOVO_3000] = "lenovo-3000",
12615 [ALC262_NEC] = "nec",
12616 [ALC262_TYAN] = "tyan",
12617 [ALC262_AUTO] = "auto",
12620 static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12621 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12622 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12623 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12625 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12627 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12629 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12631 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12633 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12634 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12635 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12636 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12637 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12638 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12639 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12640 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12641 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12642 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12643 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12644 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12645 ALC262_HP_TC_T5735),
12646 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12647 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12648 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12649 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12650 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12651 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12652 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12653 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12654 #if 0 /* disable the quirk since model=auto works better in recent versions */
12655 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12656 ALC262_SONY_ASSAMD),
12658 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12659 ALC262_TOSHIBA_RX1),
12660 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12661 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12662 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12663 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12664 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12666 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12667 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12668 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12669 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12670 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12674 static const struct alc_config_preset alc262_presets[] = {
12676 .mixers = { alc262_base_mixer },
12677 .init_verbs = { alc262_init_verbs },
12678 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12679 .dac_nids = alc262_dac_nids,
12681 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12682 .channel_mode = alc262_modes,
12683 .input_mux = &alc262_capture_source,
12686 .mixers = { alc262_hippo_mixer },
12687 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12688 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12689 .dac_nids = alc262_dac_nids,
12691 .dig_out_nid = ALC262_DIGOUT_NID,
12692 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12693 .channel_mode = alc262_modes,
12694 .input_mux = &alc262_capture_source,
12695 .unsol_event = alc_sku_unsol_event,
12696 .setup = alc262_hippo_setup,
12697 .init_hook = alc_inithook,
12699 [ALC262_HIPPO_1] = {
12700 .mixers = { alc262_hippo1_mixer },
12701 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12702 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12703 .dac_nids = alc262_dac_nids,
12705 .dig_out_nid = ALC262_DIGOUT_NID,
12706 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12707 .channel_mode = alc262_modes,
12708 .input_mux = &alc262_capture_source,
12709 .unsol_event = alc_sku_unsol_event,
12710 .setup = alc262_hippo1_setup,
12711 .init_hook = alc_inithook,
12713 [ALC262_FUJITSU] = {
12714 .mixers = { alc262_fujitsu_mixer },
12715 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12716 alc262_fujitsu_unsol_verbs },
12717 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12718 .dac_nids = alc262_dac_nids,
12720 .dig_out_nid = ALC262_DIGOUT_NID,
12721 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12722 .channel_mode = alc262_modes,
12723 .input_mux = &alc262_fujitsu_capture_source,
12724 .unsol_event = alc_sku_unsol_event,
12725 .setup = alc262_fujitsu_setup,
12726 .init_hook = alc_inithook,
12728 [ALC262_HP_BPC] = {
12729 .mixers = { alc262_HP_BPC_mixer },
12730 .init_verbs = { alc262_HP_BPC_init_verbs },
12731 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12732 .dac_nids = alc262_dac_nids,
12734 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12735 .channel_mode = alc262_modes,
12736 .input_mux = &alc262_HP_capture_source,
12737 .unsol_event = alc_sku_unsol_event,
12738 .setup = alc262_hp_bpc_setup,
12739 .init_hook = alc_inithook,
12741 [ALC262_HP_BPC_D7000_WF] = {
12742 .mixers = { alc262_HP_BPC_WildWest_mixer },
12743 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12744 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12745 .dac_nids = alc262_dac_nids,
12747 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12748 .channel_mode = alc262_modes,
12749 .input_mux = &alc262_HP_D7000_capture_source,
12750 .unsol_event = alc_sku_unsol_event,
12751 .setup = alc262_hp_wildwest_setup,
12752 .init_hook = alc_inithook,
12754 [ALC262_HP_BPC_D7000_WL] = {
12755 .mixers = { alc262_HP_BPC_WildWest_mixer,
12756 alc262_HP_BPC_WildWest_option_mixer },
12757 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12758 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12759 .dac_nids = alc262_dac_nids,
12761 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12762 .channel_mode = alc262_modes,
12763 .input_mux = &alc262_HP_D7000_capture_source,
12764 .unsol_event = alc_sku_unsol_event,
12765 .setup = alc262_hp_wildwest_setup,
12766 .init_hook = alc_inithook,
12768 [ALC262_HP_TC_T5735] = {
12769 .mixers = { alc262_hp_t5735_mixer },
12770 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12771 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12772 .dac_nids = alc262_dac_nids,
12774 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12775 .channel_mode = alc262_modes,
12776 .input_mux = &alc262_capture_source,
12777 .unsol_event = alc_sku_unsol_event,
12778 .setup = alc262_hp_t5735_setup,
12779 .init_hook = alc_inithook,
12781 [ALC262_HP_RP5700] = {
12782 .mixers = { alc262_hp_rp5700_mixer },
12783 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12784 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12785 .dac_nids = alc262_dac_nids,
12786 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12787 .channel_mode = alc262_modes,
12788 .input_mux = &alc262_hp_rp5700_capture_source,
12790 [ALC262_BENQ_ED8] = {
12791 .mixers = { alc262_base_mixer },
12792 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12793 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12794 .dac_nids = alc262_dac_nids,
12796 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12797 .channel_mode = alc262_modes,
12798 .input_mux = &alc262_capture_source,
12800 [ALC262_SONY_ASSAMD] = {
12801 .mixers = { alc262_sony_mixer },
12802 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12804 .dac_nids = alc262_dac_nids,
12806 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12807 .channel_mode = alc262_modes,
12808 .input_mux = &alc262_capture_source,
12809 .unsol_event = alc_sku_unsol_event,
12810 .setup = alc262_hippo_setup,
12811 .init_hook = alc_inithook,
12813 [ALC262_BENQ_T31] = {
12814 .mixers = { alc262_benq_t31_mixer },
12815 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12816 alc_hp15_unsol_verbs },
12817 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12818 .dac_nids = alc262_dac_nids,
12820 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12821 .channel_mode = alc262_modes,
12822 .input_mux = &alc262_capture_source,
12823 .unsol_event = alc_sku_unsol_event,
12824 .setup = alc262_hippo_setup,
12825 .init_hook = alc_inithook,
12828 .mixers = { alc262_ultra_mixer },
12829 .cap_mixer = alc262_ultra_capture_mixer,
12830 .init_verbs = { alc262_ultra_verbs },
12831 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12832 .dac_nids = alc262_dac_nids,
12833 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12834 .channel_mode = alc262_modes,
12835 .input_mux = &alc262_ultra_capture_source,
12836 .adc_nids = alc262_adc_nids, /* ADC0 */
12837 .capsrc_nids = alc262_capsrc_nids,
12838 .num_adc_nids = 1, /* single ADC */
12839 .unsol_event = alc262_ultra_unsol_event,
12840 .init_hook = alc262_ultra_automute,
12842 [ALC262_LENOVO_3000] = {
12843 .mixers = { alc262_lenovo_3000_mixer },
12844 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12845 alc262_lenovo_3000_unsol_verbs,
12846 alc262_lenovo_3000_init_verbs },
12847 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12848 .dac_nids = alc262_dac_nids,
12850 .dig_out_nid = ALC262_DIGOUT_NID,
12851 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12852 .channel_mode = alc262_modes,
12853 .input_mux = &alc262_fujitsu_capture_source,
12854 .unsol_event = alc_sku_unsol_event,
12855 .setup = alc262_lenovo_3000_setup,
12856 .init_hook = alc_inithook,
12859 .mixers = { alc262_nec_mixer },
12860 .init_verbs = { alc262_nec_verbs },
12861 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12862 .dac_nids = alc262_dac_nids,
12864 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12865 .channel_mode = alc262_modes,
12866 .input_mux = &alc262_capture_source,
12868 [ALC262_TOSHIBA_S06] = {
12869 .mixers = { alc262_toshiba_s06_mixer },
12870 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12871 alc262_eapd_verbs },
12872 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12873 .capsrc_nids = alc262_dmic_capsrc_nids,
12874 .dac_nids = alc262_dac_nids,
12875 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12876 .num_adc_nids = 1, /* single ADC */
12877 .dig_out_nid = ALC262_DIGOUT_NID,
12878 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12879 .channel_mode = alc262_modes,
12880 .unsol_event = alc_sku_unsol_event,
12881 .setup = alc262_toshiba_s06_setup,
12882 .init_hook = alc_inithook,
12884 [ALC262_TOSHIBA_RX1] = {
12885 .mixers = { alc262_toshiba_rx1_mixer },
12886 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12887 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12888 .dac_nids = alc262_dac_nids,
12890 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12891 .channel_mode = alc262_modes,
12892 .input_mux = &alc262_capture_source,
12893 .unsol_event = alc_sku_unsol_event,
12894 .setup = alc262_hippo_setup,
12895 .init_hook = alc_inithook,
12898 .mixers = { alc262_tyan_mixer },
12899 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12900 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12901 .dac_nids = alc262_dac_nids,
12903 .dig_out_nid = ALC262_DIGOUT_NID,
12904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12905 .channel_mode = alc262_modes,
12906 .input_mux = &alc262_capture_source,
12907 .unsol_event = alc_sku_unsol_event,
12908 .setup = alc262_tyan_setup,
12909 .init_hook = alc_hp_automute,
12913 static int patch_alc262(struct hda_codec *codec)
12915 struct alc_spec *spec;
12919 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12923 codec->spec = spec;
12925 spec->mixer_nid = 0x0b;
12928 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12933 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12934 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12935 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12936 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12939 alc_auto_parse_customize_define(codec);
12941 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12943 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12947 if (board_config < 0) {
12948 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12950 board_config = ALC262_AUTO;
12953 if (board_config == ALC262_AUTO) {
12954 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12955 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12958 if (board_config == ALC262_AUTO) {
12959 /* automatic parse from the BIOS config */
12960 err = alc262_parse_auto_config(codec);
12966 "hda_codec: Cannot set up configuration "
12967 "from BIOS. Using base mode...\n");
12968 board_config = ALC262_BASIC;
12972 if (!spec->no_analog && has_cdefine_beep(codec)) {
12973 err = snd_hda_attach_beep_device(codec, 0x1);
12980 if (board_config != ALC262_AUTO)
12981 setup_preset(codec, &alc262_presets[board_config]);
12983 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12984 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12986 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12987 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12989 if (!spec->adc_nids && spec->input_mux) {
12991 /* check whether the digital-mic has to be supported */
12992 for (i = 0; i < spec->input_mux->num_items; i++) {
12993 if (spec->input_mux->items[i].index >= 9)
12996 if (i < spec->input_mux->num_items) {
12997 /* use only ADC0 */
12998 spec->adc_nids = alc262_dmic_adc_nids;
12999 spec->num_adc_nids = 1;
13000 spec->capsrc_nids = alc262_dmic_capsrc_nids;
13002 /* all analog inputs */
13003 /* check whether NID 0x07 is valid */
13004 unsigned int wcap = get_wcaps(codec, 0x07);
13007 wcap = get_wcaps_type(wcap);
13008 if (wcap != AC_WID_AUD_IN) {
13009 spec->adc_nids = alc262_adc_nids_alt;
13010 spec->num_adc_nids =
13011 ARRAY_SIZE(alc262_adc_nids_alt);
13012 spec->capsrc_nids = alc262_capsrc_nids_alt;
13014 spec->adc_nids = alc262_adc_nids;
13015 spec->num_adc_nids =
13016 ARRAY_SIZE(alc262_adc_nids);
13017 spec->capsrc_nids = alc262_capsrc_nids;
13021 if (!spec->cap_mixer && !spec->no_analog)
13022 set_capture_mixer(codec);
13023 if (!spec->no_analog && has_cdefine_beep(codec))
13024 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13026 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13028 spec->vmaster_nid = 0x0c;
13030 codec->patch_ops = alc_patch_ops;
13031 if (board_config == ALC262_AUTO)
13032 spec->init_hook = alc262_auto_init;
13033 spec->shutup = alc_eapd_shutup;
13035 alc_init_jacks(codec);
13036 #ifdef CONFIG_SND_HDA_POWER_SAVE
13037 if (!spec->loopback.amplist)
13038 spec->loopback.amplist = alc262_loopbacks;
13045 * ALC268 channel source setting (2 channel)
13047 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13048 #define alc268_modes alc260_modes
13050 static const hda_nid_t alc268_dac_nids[2] = {
13055 static const hda_nid_t alc268_adc_nids[2] = {
13060 static const hda_nid_t alc268_adc_nids_alt[1] = {
13065 static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13067 static const struct snd_kcontrol_new alc268_base_mixer[] = {
13068 /* output mixer control */
13069 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13070 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13071 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13072 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13073 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13074 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13075 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13079 static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13080 /* output mixer control */
13081 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13082 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13083 ALC262_HIPPO_MASTER_SWITCH,
13084 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13085 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13086 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13090 /* bind Beep switches of both NID 0x0f and 0x10 */
13091 static const struct hda_bind_ctls alc268_bind_beep_sw = {
13092 .ops = &snd_hda_bind_sw,
13094 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13095 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13100 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13101 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13102 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13106 static const struct hda_verb alc268_eapd_verbs[] = {
13107 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13108 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13112 /* Toshiba specific */
13113 static const struct hda_verb alc268_toshiba_verbs[] = {
13114 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13118 /* Acer specific */
13119 /* bind volumes of both NID 0x02 and 0x03 */
13120 static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13121 .ops = &snd_hda_bind_vol,
13123 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13124 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13129 static void alc268_acer_setup(struct hda_codec *codec)
13131 struct alc_spec *spec = codec->spec;
13133 spec->autocfg.hp_pins[0] = 0x14;
13134 spec->autocfg.speaker_pins[0] = 0x15;
13135 spec->automute = 1;
13136 spec->automute_mode = ALC_AUTOMUTE_AMP;
13139 #define alc268_acer_master_sw_get alc262_hp_master_sw_get
13140 #define alc268_acer_master_sw_put alc262_hp_master_sw_put
13142 static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13143 /* output mixer control */
13144 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13147 .name = "Master Playback Switch",
13148 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13149 .info = snd_ctl_boolean_mono_info,
13150 .get = alc268_acer_master_sw_get,
13151 .put = alc268_acer_master_sw_put,
13153 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13157 static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13158 /* output mixer control */
13159 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13162 .name = "Master Playback Switch",
13163 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13164 .info = snd_ctl_boolean_mono_info,
13165 .get = alc268_acer_master_sw_get,
13166 .put = alc268_acer_master_sw_put,
13168 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13169 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13170 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13174 static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13175 /* output mixer control */
13176 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13179 .name = "Master Playback Switch",
13180 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13181 .info = snd_ctl_boolean_mono_info,
13182 .get = alc268_acer_master_sw_get,
13183 .put = alc268_acer_master_sw_put,
13185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13186 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13190 static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13191 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13192 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13193 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13194 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13195 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13200 static const struct hda_verb alc268_acer_verbs[] = {
13201 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13202 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13205 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13206 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13207 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13211 /* unsolicited event for HP jack sensing */
13212 #define alc268_toshiba_setup alc262_hippo_setup
13214 static void alc268_acer_lc_setup(struct hda_codec *codec)
13216 struct alc_spec *spec = codec->spec;
13217 spec->autocfg.hp_pins[0] = 0x15;
13218 spec->autocfg.speaker_pins[0] = 0x14;
13219 spec->automute = 1;
13220 spec->automute_mode = ALC_AUTOMUTE_AMP;
13221 spec->ext_mic.pin = 0x18;
13222 spec->ext_mic.mux_idx = 0;
13223 spec->int_mic.pin = 0x12;
13224 spec->int_mic.mux_idx = 6;
13225 spec->auto_mic = 1;
13228 static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13229 /* output mixer control */
13230 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13231 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13232 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13233 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13235 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13239 static const struct hda_verb alc268_dell_verbs[] = {
13240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13242 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13243 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13247 /* mute/unmute internal speaker according to the hp jack and mute state */
13248 static void alc268_dell_setup(struct hda_codec *codec)
13250 struct alc_spec *spec = codec->spec;
13252 spec->autocfg.hp_pins[0] = 0x15;
13253 spec->autocfg.speaker_pins[0] = 0x14;
13254 spec->ext_mic.pin = 0x18;
13255 spec->ext_mic.mux_idx = 0;
13256 spec->int_mic.pin = 0x19;
13257 spec->int_mic.mux_idx = 1;
13258 spec->auto_mic = 1;
13259 spec->automute = 1;
13260 spec->automute_mode = ALC_AUTOMUTE_PIN;
13263 static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13264 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13265 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13266 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13267 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13268 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13269 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13270 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13271 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13275 static const struct hda_verb alc267_quanta_il1_verbs[] = {
13276 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13277 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13281 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13283 struct alc_spec *spec = codec->spec;
13284 spec->autocfg.hp_pins[0] = 0x15;
13285 spec->autocfg.speaker_pins[0] = 0x14;
13286 spec->ext_mic.pin = 0x18;
13287 spec->ext_mic.mux_idx = 0;
13288 spec->int_mic.pin = 0x19;
13289 spec->int_mic.mux_idx = 1;
13290 spec->auto_mic = 1;
13291 spec->automute = 1;
13292 spec->automute_mode = ALC_AUTOMUTE_PIN;
13296 * generic initialization of ADC, input mixers and output mixers
13298 static const struct hda_verb alc268_base_init_verbs[] = {
13299 /* Unmute DAC0-1 and set vol = 0 */
13300 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13301 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13304 * Set up output mixers (0x0c - 0x0e)
13306 /* set vol=0 to output mixers */
13307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13308 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13311 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13316 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13317 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13319 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13320 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13322 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13323 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13324 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13325 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13328 /* set PCBEEP vol = 0, mute connections */
13329 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13330 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13331 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13333 /* Unmute Selector 23h,24h and set the default input to mic-in */
13335 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13336 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13337 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13338 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13343 /* only for model=test */
13344 #ifdef CONFIG_SND_DEBUG
13346 * generic initialization of ADC, input mixers and output mixers
13348 static const struct hda_verb alc268_volume_init_verbs[] = {
13349 /* set output DAC */
13350 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13351 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13353 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13355 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13357 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13360 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13361 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13363 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13364 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13367 #endif /* CONFIG_SND_DEBUG */
13369 /* set PCBEEP vol = 0, mute connections */
13370 static const struct hda_verb alc268_beep_init_verbs[] = {
13371 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13373 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13377 static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13378 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13379 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13383 static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13384 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13385 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13390 static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13391 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13392 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13393 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13394 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13399 static const struct hda_input_mux alc268_capture_source = {
13403 { "Front Mic", 0x1 },
13409 static const struct hda_input_mux alc268_acer_capture_source = {
13413 { "Internal Mic", 0x1 },
13418 static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13422 { "Internal Mic", 0x6 },
13427 #ifdef CONFIG_SND_DEBUG
13428 static const struct snd_kcontrol_new alc268_test_mixer[] = {
13429 /* Volume widgets */
13430 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13431 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13432 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13433 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13434 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13435 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13436 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13437 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13438 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13439 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13440 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13441 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13442 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13443 /* The below appears problematic on some hardwares */
13444 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13445 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13446 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13447 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13448 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13450 /* Modes for retasking pin widgets */
13451 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13452 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13453 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13454 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13456 /* Controls for GPIO pins, assuming they are configured as outputs */
13457 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13458 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13459 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13460 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13462 /* Switches to allow the digital SPDIF output pin to be enabled.
13463 * The ALC268 does not have an SPDIF input.
13465 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13467 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13468 * this output to turn on an external amplifier.
13470 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13471 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13477 /* create input playback/capture controls for the given pin */
13478 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13479 const char *ctlname, int idx)
13490 case 0x1a: /* ALC259/269 only */
13491 case 0x1b: /* ALC259/269 only */
13492 case 0x21: /* ALC269vb has this pin, too */
13496 snd_printd(KERN_WARNING "hda_codec: "
13497 "ignoring pin 0x%x as unknown\n", nid);
13500 if (spec->multiout.dac_nids[0] != dac &&
13501 spec->multiout.dac_nids[1] != dac) {
13502 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13503 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13507 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13511 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13512 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13514 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13515 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13521 /* add playback controls from the parsed DAC table */
13522 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13523 const struct auto_pin_cfg *cfg)
13528 spec->multiout.dac_nids = spec->private_dac_nids;
13530 nid = cfg->line_out_pins[0];
13534 name = alc_get_line_out_pfx(spec, 0, true, &index);
13535 err = alc268_new_analog_output(spec, nid, name, 0);
13540 nid = cfg->speaker_pins[0];
13542 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13543 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13547 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13551 nid = cfg->hp_pins[0];
13553 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13558 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13560 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13561 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13568 /* create playback/capture controls for input pins */
13569 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13570 const struct auto_pin_cfg *cfg)
13572 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13575 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13576 hda_nid_t nid, int pin_type)
13580 alc_set_pin_output(codec, nid, pin_type);
13581 if (nid == 0x14 || nid == 0x16)
13585 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13588 static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13592 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13596 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13598 struct alc_spec *spec = codec->spec;
13601 for (i = 0; i < spec->autocfg.line_outs; i++) {
13602 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13603 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13604 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13607 for (i = 0; i < spec->multiout.num_dacs; i++)
13608 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
13611 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13613 struct alc_spec *spec = codec->spec;
13617 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13618 pin = spec->autocfg.hp_pins[i];
13619 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13621 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13622 pin = spec->autocfg.speaker_pins[i];
13623 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13625 if (spec->autocfg.mono_out_pin)
13626 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13627 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13629 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13630 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13631 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
13634 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13636 struct alc_spec *spec = codec->spec;
13637 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13638 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13639 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13640 unsigned int dac_vol1, dac_vol2;
13642 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13643 snd_hda_codec_write(codec, speaker_nid, 0,
13644 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13645 /* mute mixer inputs from 0x1d */
13646 snd_hda_codec_write(codec, 0x0f, 0,
13647 AC_VERB_SET_AMP_GAIN_MUTE,
13649 snd_hda_codec_write(codec, 0x10, 0,
13650 AC_VERB_SET_AMP_GAIN_MUTE,
13653 /* unmute mixer inputs from 0x1d */
13654 snd_hda_codec_write(codec, 0x0f, 0,
13655 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13656 snd_hda_codec_write(codec, 0x10, 0,
13657 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13660 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13661 if (line_nid == 0x14)
13662 dac_vol2 = AMP_OUT_ZERO;
13663 else if (line_nid == 0x15)
13664 dac_vol1 = AMP_OUT_ZERO;
13665 if (hp_nid == 0x14)
13666 dac_vol2 = AMP_OUT_ZERO;
13667 else if (hp_nid == 0x15)
13668 dac_vol1 = AMP_OUT_ZERO;
13669 if (line_nid != 0x16 || hp_nid != 0x16 ||
13670 spec->autocfg.line_out_pins[1] != 0x16 ||
13671 spec->autocfg.line_out_pins[2] != 0x16)
13672 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13674 snd_hda_codec_write(codec, 0x02, 0,
13675 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13676 snd_hda_codec_write(codec, 0x03, 0,
13677 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13680 /* pcm configuration: identical with ALC880 */
13681 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13682 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13683 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13684 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13687 * BIOS auto configuration
13689 static int alc268_parse_auto_config(struct hda_codec *codec)
13691 struct alc_spec *spec = codec->spec;
13693 static const hda_nid_t alc268_ignore[] = { 0 };
13695 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13699 if (!spec->autocfg.line_outs) {
13700 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13701 spec->multiout.max_channels = 2;
13702 spec->no_analog = 1;
13705 return 0; /* can't find valid BIOS pin config */
13707 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13710 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13714 spec->multiout.max_channels = 2;
13717 /* digital only support output */
13718 alc_auto_parse_digital(codec);
13719 if (spec->kctls.list)
13720 add_mixer(spec, spec->kctls.list);
13722 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13723 add_mixer(spec, alc268_beep_mixer);
13725 add_verb(spec, alc268_beep_init_verbs);
13726 spec->num_mux_defs = 2;
13727 spec->input_mux = &spec->private_imux[0];
13729 err = alc_auto_add_mic_boost(codec);
13733 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13738 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13739 #define alc268_auto_init_input_src alc882_auto_init_input_src
13741 /* init callback for auto-configuration model -- overriding the default init */
13742 static void alc268_auto_init(struct hda_codec *codec)
13744 struct alc_spec *spec = codec->spec;
13745 alc268_auto_init_multi_out(codec);
13746 alc268_auto_init_hp_out(codec);
13747 alc268_auto_init_mono_speaker_out(codec);
13748 alc268_auto_init_analog_input(codec);
13749 alc268_auto_init_input_src(codec);
13750 alc_auto_init_digital(codec);
13751 if (spec->unsol_event)
13752 alc_inithook(codec);
13756 * configuration and preset
13758 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13759 [ALC267_QUANTA_IL1] = "quanta-il1",
13760 [ALC268_3ST] = "3stack",
13761 [ALC268_TOSHIBA] = "toshiba",
13762 [ALC268_ACER] = "acer",
13763 [ALC268_ACER_DMIC] = "acer-dmic",
13764 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13765 [ALC268_DELL] = "dell",
13766 [ALC268_ZEPTO] = "zepto",
13767 #ifdef CONFIG_SND_DEBUG
13768 [ALC268_TEST] = "test",
13770 [ALC268_AUTO] = "auto",
13773 static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13774 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13775 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13776 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13777 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13778 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13779 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13780 ALC268_ACER_ASPIRE_ONE),
13781 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13782 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13783 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13784 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13785 /* almost compatible with toshiba but with optional digital outs;
13786 * auto-probing seems working fine
13788 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13790 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13791 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13792 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13793 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13797 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13798 static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13799 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13800 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13801 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13806 static const struct alc_config_preset alc268_presets[] = {
13807 [ALC267_QUANTA_IL1] = {
13808 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13809 alc268_capture_nosrc_mixer },
13810 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13811 alc267_quanta_il1_verbs },
13812 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13813 .dac_nids = alc268_dac_nids,
13814 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13815 .adc_nids = alc268_adc_nids_alt,
13817 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13818 .channel_mode = alc268_modes,
13819 .unsol_event = alc_sku_unsol_event,
13820 .setup = alc267_quanta_il1_setup,
13821 .init_hook = alc_inithook,
13824 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13825 alc268_beep_mixer },
13826 .init_verbs = { alc268_base_init_verbs },
13827 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13828 .dac_nids = alc268_dac_nids,
13829 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13830 .adc_nids = alc268_adc_nids_alt,
13831 .capsrc_nids = alc268_capsrc_nids,
13833 .dig_out_nid = ALC268_DIGOUT_NID,
13834 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13835 .channel_mode = alc268_modes,
13836 .input_mux = &alc268_capture_source,
13838 [ALC268_TOSHIBA] = {
13839 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13840 alc268_beep_mixer },
13841 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13842 alc268_toshiba_verbs },
13843 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13844 .dac_nids = alc268_dac_nids,
13845 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13846 .adc_nids = alc268_adc_nids_alt,
13847 .capsrc_nids = alc268_capsrc_nids,
13849 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13850 .channel_mode = alc268_modes,
13851 .input_mux = &alc268_capture_source,
13852 .unsol_event = alc_sku_unsol_event,
13853 .setup = alc268_toshiba_setup,
13854 .init_hook = alc_inithook,
13857 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13858 alc268_beep_mixer },
13859 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13860 alc268_acer_verbs },
13861 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13862 .dac_nids = alc268_dac_nids,
13863 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13864 .adc_nids = alc268_adc_nids_alt,
13865 .capsrc_nids = alc268_capsrc_nids,
13867 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13868 .channel_mode = alc268_modes,
13869 .input_mux = &alc268_acer_capture_source,
13870 .unsol_event = alc_sku_unsol_event,
13871 .setup = alc268_acer_setup,
13872 .init_hook = alc_inithook,
13874 [ALC268_ACER_DMIC] = {
13875 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13876 alc268_beep_mixer },
13877 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13878 alc268_acer_verbs },
13879 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13880 .dac_nids = alc268_dac_nids,
13881 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13882 .adc_nids = alc268_adc_nids_alt,
13883 .capsrc_nids = alc268_capsrc_nids,
13885 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13886 .channel_mode = alc268_modes,
13887 .input_mux = &alc268_acer_dmic_capture_source,
13888 .unsol_event = alc_sku_unsol_event,
13889 .setup = alc268_acer_setup,
13890 .init_hook = alc_inithook,
13892 [ALC268_ACER_ASPIRE_ONE] = {
13893 .mixers = { alc268_acer_aspire_one_mixer,
13895 alc268_capture_nosrc_mixer },
13896 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13897 alc268_acer_aspire_one_verbs },
13898 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13899 .dac_nids = alc268_dac_nids,
13900 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13901 .adc_nids = alc268_adc_nids_alt,
13902 .capsrc_nids = alc268_capsrc_nids,
13904 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13905 .channel_mode = alc268_modes,
13906 .unsol_event = alc_sku_unsol_event,
13907 .setup = alc268_acer_lc_setup,
13908 .init_hook = alc_inithook,
13911 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13912 alc268_capture_nosrc_mixer },
13913 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13914 alc268_dell_verbs },
13915 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13916 .dac_nids = alc268_dac_nids,
13917 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13918 .adc_nids = alc268_adc_nids_alt,
13919 .capsrc_nids = alc268_capsrc_nids,
13921 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13922 .channel_mode = alc268_modes,
13923 .unsol_event = alc_sku_unsol_event,
13924 .setup = alc268_dell_setup,
13925 .init_hook = alc_inithook,
13928 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13929 alc268_beep_mixer },
13930 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13931 alc268_toshiba_verbs },
13932 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13933 .dac_nids = alc268_dac_nids,
13934 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13935 .adc_nids = alc268_adc_nids_alt,
13936 .capsrc_nids = alc268_capsrc_nids,
13938 .dig_out_nid = ALC268_DIGOUT_NID,
13939 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13940 .channel_mode = alc268_modes,
13941 .input_mux = &alc268_capture_source,
13942 .unsol_event = alc_sku_unsol_event,
13943 .setup = alc268_toshiba_setup,
13944 .init_hook = alc_inithook,
13946 #ifdef CONFIG_SND_DEBUG
13948 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13949 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13950 alc268_volume_init_verbs,
13951 alc268_beep_init_verbs },
13952 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13953 .dac_nids = alc268_dac_nids,
13954 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13955 .adc_nids = alc268_adc_nids_alt,
13956 .capsrc_nids = alc268_capsrc_nids,
13958 .dig_out_nid = ALC268_DIGOUT_NID,
13959 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13960 .channel_mode = alc268_modes,
13961 .input_mux = &alc268_capture_source,
13966 static int patch_alc268(struct hda_codec *codec)
13968 struct alc_spec *spec;
13970 int i, has_beep, err;
13972 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13976 codec->spec = spec;
13978 /* ALC268 has no aa-loopback mixer */
13980 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13984 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13985 board_config = snd_hda_check_board_codec_sid_config(codec,
13986 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13988 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13989 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13991 board_config = ALC268_AUTO;
13994 if (board_config == ALC268_AUTO) {
13995 /* automatic parse from the BIOS config */
13996 err = alc268_parse_auto_config(codec);
14002 "hda_codec: Cannot set up configuration "
14003 "from BIOS. Using base mode...\n");
14004 board_config = ALC268_3ST;
14008 if (board_config != ALC268_AUTO)
14009 setup_preset(codec, &alc268_presets[board_config]);
14011 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14012 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14013 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14015 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14018 for (i = 0; i < spec->num_mixers; i++) {
14019 if (spec->mixers[i] == alc268_beep_mixer) {
14026 err = snd_hda_attach_beep_device(codec, 0x1);
14031 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14032 /* override the amp caps for beep generator */
14033 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14034 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14035 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14036 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14037 (0 << AC_AMPCAP_MUTE_SHIFT));
14040 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14041 /* check whether NID 0x07 is valid */
14042 unsigned int wcap = get_wcaps(codec, 0x07);
14044 spec->capsrc_nids = alc268_capsrc_nids;
14046 wcap = get_wcaps_type(wcap);
14047 if (spec->auto_mic ||
14048 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14049 spec->adc_nids = alc268_adc_nids_alt;
14050 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14051 if (spec->auto_mic)
14052 fixup_automic_adc(codec);
14053 if (spec->auto_mic || spec->input_mux->num_items == 1)
14054 add_mixer(spec, alc268_capture_nosrc_mixer);
14056 add_mixer(spec, alc268_capture_alt_mixer);
14058 spec->adc_nids = alc268_adc_nids;
14059 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14060 add_mixer(spec, alc268_capture_mixer);
14064 spec->vmaster_nid = 0x02;
14066 codec->patch_ops = alc_patch_ops;
14067 if (board_config == ALC268_AUTO)
14068 spec->init_hook = alc268_auto_init;
14069 spec->shutup = alc_eapd_shutup;
14071 alc_init_jacks(codec);
14077 * ALC269 channel source setting (2 channel)
14079 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14081 #define alc269_dac_nids alc260_dac_nids
14083 static const hda_nid_t alc269_adc_nids[1] = {
14088 static const hda_nid_t alc269_capsrc_nids[1] = {
14092 static const hda_nid_t alc269vb_adc_nids[1] = {
14097 static const hda_nid_t alc269vb_capsrc_nids[1] = {
14101 static const hda_nid_t alc269_adc_candidates[] = {
14102 0x08, 0x09, 0x07, 0x11,
14105 #define alc269_modes alc260_modes
14106 #define alc269_capture_source alc880_lg_lw_capture_source
14108 static const struct snd_kcontrol_new alc269_base_mixer[] = {
14109 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14110 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14116 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14117 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14118 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14119 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14120 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14124 static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14125 /* output mixer control */
14126 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14129 .name = "Master Playback Switch",
14130 .subdevice = HDA_SUBDEV_AMP_FLAG,
14131 .info = snd_hda_mixer_amp_switch_info,
14132 .get = snd_hda_mixer_amp_switch_get,
14133 .put = alc268_acer_master_sw_put,
14134 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14139 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14140 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14141 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14145 static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14146 /* output mixer control */
14147 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14150 .name = "Master Playback Switch",
14151 .subdevice = HDA_SUBDEV_AMP_FLAG,
14152 .info = snd_hda_mixer_amp_switch_info,
14153 .get = snd_hda_mixer_amp_switch_get,
14154 .put = alc268_acer_master_sw_put,
14155 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14160 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14161 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14162 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14163 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14164 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14165 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14169 static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14170 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14171 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14172 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14177 static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14178 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14179 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14185 static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14186 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14187 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14191 /* capture mixer elements */
14192 static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14193 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14194 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14196 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14200 static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14201 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14202 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14207 static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14208 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14209 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14210 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14211 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14215 static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14216 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14217 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14218 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14223 #define alc269_fujitsu_mixer alc269_laptop_mixer
14225 static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14227 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14229 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14230 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14231 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14235 static const struct hda_verb alc269_lifebook_verbs[] = {
14236 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14237 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14238 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14240 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14243 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14244 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14245 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14249 /* toggle speaker-output according to the hp-jack state */
14250 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14252 alc_hp_automute(codec);
14254 snd_hda_codec_write(codec, 0x20, 0,
14255 AC_VERB_SET_COEF_INDEX, 0x0c);
14256 snd_hda_codec_write(codec, 0x20, 0,
14257 AC_VERB_SET_PROC_COEF, 0x680);
14259 snd_hda_codec_write(codec, 0x20, 0,
14260 AC_VERB_SET_COEF_INDEX, 0x0c);
14261 snd_hda_codec_write(codec, 0x20, 0,
14262 AC_VERB_SET_PROC_COEF, 0x480);
14265 #define alc269_lifebook_speaker_automute \
14266 alc269_quanta_fl1_speaker_automute
14268 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14270 unsigned int present_laptop;
14271 unsigned int present_dock;
14273 present_laptop = snd_hda_jack_detect(codec, 0x18);
14274 present_dock = snd_hda_jack_detect(codec, 0x1b);
14276 /* Laptop mic port overrides dock mic port, design decision */
14278 snd_hda_codec_write(codec, 0x23, 0,
14279 AC_VERB_SET_CONNECT_SEL, 0x3);
14280 if (present_laptop)
14281 snd_hda_codec_write(codec, 0x23, 0,
14282 AC_VERB_SET_CONNECT_SEL, 0x0);
14283 if (!present_dock && !present_laptop)
14284 snd_hda_codec_write(codec, 0x23, 0,
14285 AC_VERB_SET_CONNECT_SEL, 0x1);
14288 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14291 switch (res >> 26) {
14292 case ALC880_HP_EVENT:
14293 alc269_quanta_fl1_speaker_automute(codec);
14295 case ALC880_MIC_EVENT:
14296 alc_mic_automute(codec);
14301 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14304 if ((res >> 26) == ALC880_HP_EVENT)
14305 alc269_lifebook_speaker_automute(codec);
14306 if ((res >> 26) == ALC880_MIC_EVENT)
14307 alc269_lifebook_mic_autoswitch(codec);
14310 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14312 struct alc_spec *spec = codec->spec;
14313 spec->autocfg.hp_pins[0] = 0x15;
14314 spec->autocfg.speaker_pins[0] = 0x14;
14315 spec->automute_mixer_nid[0] = 0x0c;
14316 spec->automute = 1;
14317 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14318 spec->ext_mic.pin = 0x18;
14319 spec->ext_mic.mux_idx = 0;
14320 spec->int_mic.pin = 0x19;
14321 spec->int_mic.mux_idx = 1;
14322 spec->auto_mic = 1;
14325 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14327 alc269_quanta_fl1_speaker_automute(codec);
14328 alc_mic_automute(codec);
14331 static void alc269_lifebook_setup(struct hda_codec *codec)
14333 struct alc_spec *spec = codec->spec;
14334 spec->autocfg.hp_pins[0] = 0x15;
14335 spec->autocfg.hp_pins[1] = 0x1a;
14336 spec->autocfg.speaker_pins[0] = 0x14;
14337 spec->automute_mixer_nid[0] = 0x0c;
14338 spec->automute = 1;
14339 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14342 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14344 alc269_lifebook_speaker_automute(codec);
14345 alc269_lifebook_mic_autoswitch(codec);
14348 static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14349 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14350 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14351 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14352 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14353 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14354 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14355 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14359 static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14361 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14362 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14364 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14369 static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14370 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14371 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14372 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14374 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14375 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14376 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14380 static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14381 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14382 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14383 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14385 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14386 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14387 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14391 static const struct hda_verb alc271_acer_dmic_verbs[] = {
14392 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14393 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14394 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14396 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14397 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14398 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14399 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14401 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14405 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14407 struct alc_spec *spec = codec->spec;
14408 spec->autocfg.hp_pins[0] = 0x15;
14409 spec->autocfg.speaker_pins[0] = 0x14;
14410 spec->automute_mixer_nid[0] = 0x0c;
14411 spec->automute = 1;
14412 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14413 spec->ext_mic.pin = 0x18;
14414 spec->ext_mic.mux_idx = 0;
14415 spec->int_mic.pin = 0x19;
14416 spec->int_mic.mux_idx = 1;
14417 spec->auto_mic = 1;
14420 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14422 struct alc_spec *spec = codec->spec;
14423 spec->autocfg.hp_pins[0] = 0x15;
14424 spec->autocfg.speaker_pins[0] = 0x14;
14425 spec->automute_mixer_nid[0] = 0x0c;
14426 spec->automute = 1;
14427 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14428 spec->ext_mic.pin = 0x18;
14429 spec->ext_mic.mux_idx = 0;
14430 spec->int_mic.pin = 0x12;
14431 spec->int_mic.mux_idx = 5;
14432 spec->auto_mic = 1;
14435 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14437 struct alc_spec *spec = codec->spec;
14438 spec->autocfg.hp_pins[0] = 0x21;
14439 spec->autocfg.speaker_pins[0] = 0x14;
14440 spec->automute_mixer_nid[0] = 0x0c;
14441 spec->automute = 1;
14442 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14443 spec->ext_mic.pin = 0x18;
14444 spec->ext_mic.mux_idx = 0;
14445 spec->int_mic.pin = 0x19;
14446 spec->int_mic.mux_idx = 1;
14447 spec->auto_mic = 1;
14450 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14452 struct alc_spec *spec = codec->spec;
14453 spec->autocfg.hp_pins[0] = 0x21;
14454 spec->autocfg.speaker_pins[0] = 0x14;
14455 spec->automute_mixer_nid[0] = 0x0c;
14456 spec->automute = 1;
14457 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14458 spec->ext_mic.pin = 0x18;
14459 spec->ext_mic.mux_idx = 0;
14460 spec->int_mic.pin = 0x12;
14461 spec->int_mic.mux_idx = 6;
14462 spec->auto_mic = 1;
14466 * generic initialization of ADC, input mixers and output mixers
14468 static const struct hda_verb alc269_init_verbs[] = {
14470 * Unmute ADC0 and set the default input to mic-in
14472 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14475 * Set up output mixers (0x02 - 0x03)
14477 /* set vol=0 to output mixers */
14478 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14479 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14481 /* set up input amps for analog loopback */
14482 /* Amp Indices: DAC = 0, mixer = 1 */
14483 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14484 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14485 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14486 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14487 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14488 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14490 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14492 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14495 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14501 /* FIXME: use Mux-type input source selection */
14502 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14503 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14504 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14507 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14511 static const struct hda_verb alc269vb_init_verbs[] = {
14513 * Unmute ADC0 and set the default input to mic-in
14515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14518 * Set up output mixers (0x02 - 0x03)
14520 /* set vol=0 to output mixers */
14521 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14522 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14524 /* set up input amps for analog loopback */
14525 /* Amp Indices: DAC = 0, mixer = 1 */
14526 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14528 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14529 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14530 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14531 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14534 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14535 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14536 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14537 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14538 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14541 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14542 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14544 /* FIXME: use Mux-type input source selection */
14545 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14546 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14547 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14550 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14554 #define alc269_auto_create_multi_out_ctls \
14555 alc268_auto_create_multi_out_ctls
14556 #define alc269_auto_create_input_ctls \
14557 alc268_auto_create_input_ctls
14559 #ifdef CONFIG_SND_HDA_POWER_SAVE
14560 #define alc269_loopbacks alc880_loopbacks
14563 /* pcm configuration: identical with ALC880 */
14564 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14565 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14566 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14567 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14569 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14573 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14574 /* NID is set in alc_build_pcms */
14576 .open = alc880_playback_pcm_open,
14577 .prepare = alc880_playback_pcm_prepare,
14578 .cleanup = alc880_playback_pcm_cleanup
14582 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14586 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14587 /* NID is set in alc_build_pcms */
14590 #ifdef CONFIG_SND_HDA_POWER_SAVE
14591 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14593 switch (codec->subsystem_id) {
14600 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14602 /* update mute-LED according to the speaker mute state */
14603 if (nid == 0x01 || nid == 0x14) {
14605 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14610 /* mic2 vref pin is used for mute LED control */
14611 snd_hda_codec_update_cache(codec, 0x19, 0,
14612 AC_VERB_SET_PIN_WIDGET_CONTROL,
14615 return alc_check_power_status(codec, nid);
14617 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14619 static int alc275_setup_dual_adc(struct hda_codec *codec)
14621 struct alc_spec *spec = codec->spec;
14623 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14625 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14626 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14627 if (spec->ext_mic.pin <= 0x12) {
14628 spec->private_adc_nids[0] = 0x08;
14629 spec->private_adc_nids[1] = 0x11;
14630 spec->private_capsrc_nids[0] = 0x23;
14631 spec->private_capsrc_nids[1] = 0x22;
14633 spec->private_adc_nids[0] = 0x11;
14634 spec->private_adc_nids[1] = 0x08;
14635 spec->private_capsrc_nids[0] = 0x22;
14636 spec->private_capsrc_nids[1] = 0x23;
14638 spec->adc_nids = spec->private_adc_nids;
14639 spec->capsrc_nids = spec->private_capsrc_nids;
14640 spec->num_adc_nids = 2;
14641 spec->dual_adc_switch = 1;
14642 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14643 spec->adc_nids[0], spec->adc_nids[1]);
14649 /* different alc269-variants */
14651 ALC269_TYPE_NORMAL,
14652 ALC269_TYPE_ALC258,
14653 ALC269_TYPE_ALC259,
14654 ALC269_TYPE_ALC269VB,
14655 ALC269_TYPE_ALC270,
14656 ALC269_TYPE_ALC271X,
14660 * BIOS auto configuration
14662 static int alc269_parse_auto_config(struct hda_codec *codec)
14664 struct alc_spec *spec = codec->spec;
14666 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14668 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14673 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14676 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14677 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14679 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14684 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14686 alc_auto_parse_digital(codec);
14688 if (spec->kctls.list)
14689 add_mixer(spec, spec->kctls.list);
14691 if (spec->codec_variant != ALC269_TYPE_NORMAL)
14692 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14694 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14696 spec->num_mux_defs = 1;
14697 spec->input_mux = &spec->private_imux[0];
14699 if (!alc275_setup_dual_adc(codec))
14700 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14701 sizeof(alc269_adc_candidates));
14703 err = alc_auto_add_mic_boost(codec);
14707 if (!spec->cap_mixer && !spec->no_analog)
14708 set_capture_mixer(codec);
14713 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14714 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14715 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14716 #define alc269_auto_init_input_src alc882_auto_init_input_src
14719 /* init callback for auto-configuration model -- overriding the default init */
14720 static void alc269_auto_init(struct hda_codec *codec)
14722 struct alc_spec *spec = codec->spec;
14723 alc269_auto_init_multi_out(codec);
14724 alc269_auto_init_hp_out(codec);
14725 alc269_auto_init_analog_input(codec);
14726 if (!spec->dual_adc_switch)
14727 alc269_auto_init_input_src(codec);
14728 alc_auto_init_digital(codec);
14729 if (spec->unsol_event)
14730 alc_inithook(codec);
14733 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14735 int val = alc_read_coef_idx(codec, 0x04);
14740 alc_write_coef_idx(codec, 0x04, val);
14743 static void alc269_shutup(struct hda_codec *codec)
14745 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14746 alc269_toggle_power_output(codec, 0);
14747 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14748 alc269_toggle_power_output(codec, 0);
14753 #ifdef SND_HDA_NEEDS_RESUME
14754 static int alc269_resume(struct hda_codec *codec)
14756 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14757 alc269_toggle_power_output(codec, 0);
14761 codec->patch_ops.init(codec);
14763 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14764 alc269_toggle_power_output(codec, 1);
14768 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14769 alc269_toggle_power_output(codec, 1);
14771 snd_hda_codec_resume_amp(codec);
14772 snd_hda_codec_resume_cache(codec);
14773 hda_call_check_power_status(codec, 0x01);
14776 #endif /* SND_HDA_NEEDS_RESUME */
14778 static void alc269_fixup_hweq(struct hda_codec *codec,
14779 const struct alc_fixup *fix, int action)
14783 if (action != ALC_FIXUP_ACT_INIT)
14785 coef = alc_read_coef_idx(codec, 0x1e);
14786 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14789 static void alc271_fixup_dmic(struct hda_codec *codec,
14790 const struct alc_fixup *fix, int action)
14792 static const struct hda_verb verbs[] = {
14793 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14794 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14799 if (strcmp(codec->chip_name, "ALC271X"))
14801 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14802 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14803 snd_hda_sequence_write(codec, verbs);
14807 ALC269_FIXUP_SONY_VAIO,
14808 ALC275_FIXUP_SONY_VAIO_GPIO2,
14809 ALC269_FIXUP_DELL_M101Z,
14810 ALC269_FIXUP_SKU_IGNORE,
14811 ALC269_FIXUP_ASUS_G73JW,
14812 ALC269_FIXUP_LENOVO_EAPD,
14813 ALC275_FIXUP_SONY_HWEQ,
14817 static const struct alc_fixup alc269_fixups[] = {
14818 [ALC269_FIXUP_SONY_VAIO] = {
14819 .type = ALC_FIXUP_VERBS,
14820 .v.verbs = (const struct hda_verb[]) {
14821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14825 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14826 .type = ALC_FIXUP_VERBS,
14827 .v.verbs = (const struct hda_verb[]) {
14828 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14829 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14830 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14834 .chain_id = ALC269_FIXUP_SONY_VAIO
14836 [ALC269_FIXUP_DELL_M101Z] = {
14837 .type = ALC_FIXUP_VERBS,
14838 .v.verbs = (const struct hda_verb[]) {
14839 /* Enables internal speaker */
14840 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14841 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14845 [ALC269_FIXUP_SKU_IGNORE] = {
14846 .type = ALC_FIXUP_SKU,
14847 .v.sku = ALC_FIXUP_SKU_IGNORE,
14849 [ALC269_FIXUP_ASUS_G73JW] = {
14850 .type = ALC_FIXUP_PINS,
14851 .v.pins = (const struct alc_pincfg[]) {
14852 { 0x17, 0x99130111 }, /* subwoofer */
14856 [ALC269_FIXUP_LENOVO_EAPD] = {
14857 .type = ALC_FIXUP_VERBS,
14858 .v.verbs = (const struct hda_verb[]) {
14859 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14863 [ALC275_FIXUP_SONY_HWEQ] = {
14864 .type = ALC_FIXUP_FUNC,
14865 .v.func = alc269_fixup_hweq,
14867 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14869 [ALC271_FIXUP_DMIC] = {
14870 .type = ALC_FIXUP_FUNC,
14871 .v.func = alc271_fixup_dmic,
14875 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14876 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14877 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14878 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14879 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14880 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14881 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14882 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14883 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14884 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14885 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14886 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14887 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14888 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14894 * configuration and preset
14896 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14897 [ALC269_BASIC] = "basic",
14898 [ALC269_QUANTA_FL1] = "quanta",
14899 [ALC269_AMIC] = "laptop-amic",
14900 [ALC269_DMIC] = "laptop-dmic",
14901 [ALC269_FUJITSU] = "fujitsu",
14902 [ALC269_LIFEBOOK] = "lifebook",
14903 [ALC269_AUTO] = "auto",
14906 static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14907 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14908 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14909 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14911 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14912 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14913 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14914 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14915 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14916 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14917 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14918 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14919 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14920 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14921 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14922 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14923 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14926 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14927 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14928 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14929 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14930 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14931 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14932 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14933 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14934 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14940 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14941 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14943 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14944 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14945 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14949 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14951 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14952 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14953 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14954 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14955 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14956 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14957 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14960 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14964 static const struct alc_config_preset alc269_presets[] = {
14966 .mixers = { alc269_base_mixer },
14967 .init_verbs = { alc269_init_verbs },
14968 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14969 .dac_nids = alc269_dac_nids,
14971 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14972 .channel_mode = alc269_modes,
14973 .input_mux = &alc269_capture_source,
14975 [ALC269_QUANTA_FL1] = {
14976 .mixers = { alc269_quanta_fl1_mixer },
14977 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14978 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14979 .dac_nids = alc269_dac_nids,
14981 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14982 .channel_mode = alc269_modes,
14983 .input_mux = &alc269_capture_source,
14984 .unsol_event = alc269_quanta_fl1_unsol_event,
14985 .setup = alc269_quanta_fl1_setup,
14986 .init_hook = alc269_quanta_fl1_init_hook,
14989 .mixers = { alc269_laptop_mixer },
14990 .cap_mixer = alc269_laptop_analog_capture_mixer,
14991 .init_verbs = { alc269_init_verbs,
14992 alc269_laptop_amic_init_verbs },
14993 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14994 .dac_nids = alc269_dac_nids,
14996 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14997 .channel_mode = alc269_modes,
14998 .unsol_event = alc_sku_unsol_event,
14999 .setup = alc269_laptop_amic_setup,
15000 .init_hook = alc_inithook,
15003 .mixers = { alc269_laptop_mixer },
15004 .cap_mixer = alc269_laptop_digital_capture_mixer,
15005 .init_verbs = { alc269_init_verbs,
15006 alc269_laptop_dmic_init_verbs },
15007 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15008 .dac_nids = alc269_dac_nids,
15010 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15011 .channel_mode = alc269_modes,
15012 .unsol_event = alc_sku_unsol_event,
15013 .setup = alc269_laptop_dmic_setup,
15014 .init_hook = alc_inithook,
15016 [ALC269VB_AMIC] = {
15017 .mixers = { alc269vb_laptop_mixer },
15018 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15019 .init_verbs = { alc269vb_init_verbs,
15020 alc269vb_laptop_amic_init_verbs },
15021 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15022 .dac_nids = alc269_dac_nids,
15024 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15025 .channel_mode = alc269_modes,
15026 .unsol_event = alc_sku_unsol_event,
15027 .setup = alc269vb_laptop_amic_setup,
15028 .init_hook = alc_inithook,
15030 [ALC269VB_DMIC] = {
15031 .mixers = { alc269vb_laptop_mixer },
15032 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15033 .init_verbs = { alc269vb_init_verbs,
15034 alc269vb_laptop_dmic_init_verbs },
15035 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15036 .dac_nids = alc269_dac_nids,
15038 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15039 .channel_mode = alc269_modes,
15040 .unsol_event = alc_sku_unsol_event,
15041 .setup = alc269vb_laptop_dmic_setup,
15042 .init_hook = alc_inithook,
15044 [ALC269_FUJITSU] = {
15045 .mixers = { alc269_fujitsu_mixer },
15046 .cap_mixer = alc269_laptop_digital_capture_mixer,
15047 .init_verbs = { alc269_init_verbs,
15048 alc269_laptop_dmic_init_verbs },
15049 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15050 .dac_nids = alc269_dac_nids,
15052 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15053 .channel_mode = alc269_modes,
15054 .unsol_event = alc_sku_unsol_event,
15055 .setup = alc269_laptop_dmic_setup,
15056 .init_hook = alc_inithook,
15058 [ALC269_LIFEBOOK] = {
15059 .mixers = { alc269_lifebook_mixer },
15060 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15061 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15062 .dac_nids = alc269_dac_nids,
15064 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15065 .channel_mode = alc269_modes,
15066 .input_mux = &alc269_capture_source,
15067 .unsol_event = alc269_lifebook_unsol_event,
15068 .setup = alc269_lifebook_setup,
15069 .init_hook = alc269_lifebook_init_hook,
15072 .mixers = { alc269_asus_mixer },
15073 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15074 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15075 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15076 .dac_nids = alc269_dac_nids,
15077 .adc_nids = alc262_dmic_adc_nids,
15078 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15079 .capsrc_nids = alc262_dmic_capsrc_nids,
15080 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15081 .channel_mode = alc269_modes,
15082 .input_mux = &alc269_capture_source,
15083 .dig_out_nid = ALC880_DIGOUT_NID,
15084 .unsol_event = alc_sku_unsol_event,
15085 .setup = alc269vb_laptop_dmic_setup,
15086 .init_hook = alc_inithook,
15090 static int alc269_fill_coef(struct hda_codec *codec)
15094 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15095 alc_write_coef_idx(codec, 0xf, 0x960b);
15096 alc_write_coef_idx(codec, 0xe, 0x8817);
15099 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15100 alc_write_coef_idx(codec, 0xf, 0x960b);
15101 alc_write_coef_idx(codec, 0xe, 0x8814);
15104 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15105 val = alc_read_coef_idx(codec, 0x04);
15106 /* Power up output pin */
15107 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15110 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15111 val = alc_read_coef_idx(codec, 0xd);
15112 if ((val & 0x0c00) >> 10 != 0x1) {
15113 /* Capless ramp up clock control */
15114 alc_write_coef_idx(codec, 0xd, val | (1<<10));
15116 val = alc_read_coef_idx(codec, 0x17);
15117 if ((val & 0x01c0) >> 6 != 0x4) {
15118 /* Class D power on reset */
15119 alc_write_coef_idx(codec, 0x17, val | (1<<7));
15123 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15124 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15126 val = alc_read_coef_idx(codec, 0x4); /* HP */
15127 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15132 static int patch_alc269(struct hda_codec *codec)
15134 struct alc_spec *spec;
15135 int board_config, coef;
15138 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15142 codec->spec = spec;
15144 spec->mixer_nid = 0x0b;
15146 alc_auto_parse_customize_define(codec);
15148 if (codec->vendor_id == 0x10ec0269) {
15149 coef = alc_read_coef_idx(codec, 0);
15150 if ((coef & 0x00f0) == 0x0010) {
15151 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15152 spec->cdefine.platform_type == 1) {
15153 alc_codec_rename(codec, "ALC271X");
15154 spec->codec_variant = ALC269_TYPE_ALC271X;
15155 } else if ((coef & 0xf000) == 0x1000) {
15156 spec->codec_variant = ALC269_TYPE_ALC270;
15157 } else if ((coef & 0xf000) == 0x2000) {
15158 alc_codec_rename(codec, "ALC259");
15159 spec->codec_variant = ALC269_TYPE_ALC259;
15160 } else if ((coef & 0xf000) == 0x3000) {
15161 alc_codec_rename(codec, "ALC258");
15162 spec->codec_variant = ALC269_TYPE_ALC258;
15164 alc_codec_rename(codec, "ALC269VB");
15165 spec->codec_variant = ALC269_TYPE_ALC269VB;
15168 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15169 alc269_fill_coef(codec);
15172 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15176 if (board_config < 0) {
15177 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15179 board_config = ALC269_AUTO;
15182 if (board_config == ALC269_AUTO) {
15183 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15184 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15187 if (board_config == ALC269_AUTO) {
15188 /* automatic parse from the BIOS config */
15189 err = alc269_parse_auto_config(codec);
15195 "hda_codec: Cannot set up configuration "
15196 "from BIOS. Using base mode...\n");
15197 board_config = ALC269_BASIC;
15201 if (has_cdefine_beep(codec)) {
15202 err = snd_hda_attach_beep_device(codec, 0x1);
15209 if (board_config != ALC269_AUTO)
15210 setup_preset(codec, &alc269_presets[board_config]);
15212 if (board_config == ALC269_QUANTA_FL1) {
15213 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15214 * fix the sample rate of analog I/O to 44.1kHz
15216 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15217 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15218 } else if (spec->dual_adc_switch) {
15219 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15220 /* switch ADC dynamically */
15221 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15223 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15224 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15226 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15227 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15229 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15230 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15231 spec->adc_nids = alc269_adc_nids;
15232 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15233 spec->capsrc_nids = alc269_capsrc_nids;
15235 spec->adc_nids = alc269vb_adc_nids;
15236 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15237 spec->capsrc_nids = alc269vb_capsrc_nids;
15241 if (!spec->cap_mixer)
15242 set_capture_mixer(codec);
15243 if (has_cdefine_beep(codec))
15244 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15246 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15248 spec->vmaster_nid = 0x02;
15250 codec->patch_ops = alc_patch_ops;
15251 #ifdef SND_HDA_NEEDS_RESUME
15252 codec->patch_ops.resume = alc269_resume;
15254 if (board_config == ALC269_AUTO)
15255 spec->init_hook = alc269_auto_init;
15256 spec->shutup = alc269_shutup;
15258 alc_init_jacks(codec);
15259 #ifdef CONFIG_SND_HDA_POWER_SAVE
15260 if (!spec->loopback.amplist)
15261 spec->loopback.amplist = alc269_loopbacks;
15262 if (alc269_mic2_for_mute_led(codec))
15263 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15270 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15274 * set the path ways for 2 channel output
15275 * need to set the codec line out and mic 1 pin widgets to inputs
15277 static const struct hda_verb alc861_threestack_ch2_init[] = {
15278 /* set pin widget 1Ah (line in) for input */
15279 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15280 /* set pin widget 18h (mic1/2) for input, for mic also enable
15283 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15285 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15287 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15288 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15294 * need to set the codec line out and mic 1 pin widgets to outputs
15296 static const struct hda_verb alc861_threestack_ch6_init[] = {
15297 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15298 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15299 /* set pin widget 18h (mic1) for output (CLFE)*/
15300 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15302 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15303 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15305 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15307 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15308 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15313 static const struct hda_channel_mode alc861_threestack_modes[2] = {
15314 { 2, alc861_threestack_ch2_init },
15315 { 6, alc861_threestack_ch6_init },
15317 /* Set mic1 as input and unmute the mixer */
15318 static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15319 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15320 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15323 /* Set mic1 as output and mute mixer */
15324 static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15325 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15326 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15330 static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15331 { 2, alc861_uniwill_m31_ch2_init },
15332 { 4, alc861_uniwill_m31_ch4_init },
15335 /* Set mic1 and line-in as input and unmute the mixer */
15336 static const struct hda_verb alc861_asus_ch2_init[] = {
15337 /* set pin widget 1Ah (line in) for input */
15338 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15339 /* set pin widget 18h (mic1/2) for input, for mic also enable
15342 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15344 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15346 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15347 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15351 /* Set mic1 nad line-in as output and mute mixer */
15352 static const struct hda_verb alc861_asus_ch6_init[] = {
15353 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15354 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15355 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15356 /* set pin widget 18h (mic1) for output (CLFE)*/
15357 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15358 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15359 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15360 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15365 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15370 static const struct hda_channel_mode alc861_asus_modes[2] = {
15371 { 2, alc861_asus_ch2_init },
15372 { 6, alc861_asus_ch6_init },
15377 static const struct snd_kcontrol_new alc861_base_mixer[] = {
15378 /* output mixer control */
15379 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15380 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15381 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15382 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15385 /*Input mixer control */
15386 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15387 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15388 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15389 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15390 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15391 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15393 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15400 static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15401 /* output mixer control */
15402 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15403 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15404 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15405 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15406 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15408 /* Input mixer control */
15409 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15411 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15412 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15413 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15414 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15415 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15416 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15417 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15418 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15421 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15422 .name = "Channel Mode",
15423 .info = alc_ch_mode_info,
15424 .get = alc_ch_mode_get,
15425 .put = alc_ch_mode_put,
15426 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15431 static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15432 /* output mixer control */
15433 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15435 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15440 static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15441 /* output mixer control */
15442 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15443 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15444 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15446 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15448 /* Input mixer control */
15449 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15451 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15452 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15453 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15454 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15456 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15457 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15462 .name = "Channel Mode",
15463 .info = alc_ch_mode_info,
15464 .get = alc_ch_mode_get,
15465 .put = alc_ch_mode_put,
15466 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15471 static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15472 /* output mixer control */
15473 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15475 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15476 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15477 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15479 /* Input mixer control */
15480 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15481 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15482 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15483 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15484 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15485 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15486 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15487 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15488 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15493 .name = "Channel Mode",
15494 .info = alc_ch_mode_info,
15495 .get = alc_ch_mode_get,
15496 .put = alc_ch_mode_put,
15497 .private_value = ARRAY_SIZE(alc861_asus_modes),
15502 /* additional mixer */
15503 static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15504 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15505 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15510 * generic initialization of ADC, input mixers and output mixers
15512 static const struct hda_verb alc861_base_init_verbs[] = {
15514 * Unmute ADC0 and set the default input to mic-in
15516 /* port-A for surround (rear panel) */
15517 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15518 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15519 /* port-B for mic-in (rear panel) with vref */
15520 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15521 /* port-C for line-in (rear panel) */
15522 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15523 /* port-D for Front */
15524 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15525 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15526 /* port-E for HP out (front panel) */
15527 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15528 /* route front PCM to HP */
15529 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15530 /* port-F for mic-in (front panel) with vref */
15531 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15532 /* port-G for CLFE (rear panel) */
15533 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15534 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15535 /* port-H for side (rear panel) */
15536 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15537 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15539 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15540 /* route front mic to ADC1*/
15541 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15544 /* Unmute DAC0~3 & spdif out*/
15545 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15546 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15547 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15548 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15551 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15552 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15553 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15554 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15555 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15557 /* Unmute Stereo Mixer 15 */
15558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15560 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15561 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15564 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15565 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15566 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15568 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15570 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15571 /* hp used DAC 3 (Front) */
15572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15573 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15578 static const struct hda_verb alc861_threestack_init_verbs[] = {
15580 * Unmute ADC0 and set the default input to mic-in
15582 /* port-A for surround (rear panel) */
15583 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15584 /* port-B for mic-in (rear panel) with vref */
15585 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15586 /* port-C for line-in (rear panel) */
15587 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15588 /* port-D for Front */
15589 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15590 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15591 /* port-E for HP out (front panel) */
15592 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15593 /* route front PCM to HP */
15594 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15595 /* port-F for mic-in (front panel) with vref */
15596 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15597 /* port-G for CLFE (rear panel) */
15598 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15599 /* port-H for side (rear panel) */
15600 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15602 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15603 /* route front mic to ADC1*/
15604 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15606 /* Unmute DAC0~3 & spdif out*/
15607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15610 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15613 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15614 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15615 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15616 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15619 /* Unmute Stereo Mixer 15 */
15620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15626 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15627 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 /* hp used DAC 3 (Front) */
15634 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15639 static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15641 * Unmute ADC0 and set the default input to mic-in
15643 /* port-A for surround (rear panel) */
15644 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15645 /* port-B for mic-in (rear panel) with vref */
15646 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15647 /* port-C for line-in (rear panel) */
15648 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15649 /* port-D for Front */
15650 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15651 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15652 /* port-E for HP out (front panel) */
15653 /* this has to be set to VREF80 */
15654 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15655 /* route front PCM to HP */
15656 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15657 /* port-F for mic-in (front panel) with vref */
15658 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15659 /* port-G for CLFE (rear panel) */
15660 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15661 /* port-H for side (rear panel) */
15662 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15664 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15665 /* route front mic to ADC1*/
15666 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15668 /* Unmute DAC0~3 & spdif out*/
15669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15672 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15675 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15676 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15681 /* Unmute Stereo Mixer 15 */
15682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15687 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15688 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15689 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15690 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15691 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 /* hp used DAC 3 (Front) */
15696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15701 static const struct hda_verb alc861_asus_init_verbs[] = {
15703 * Unmute ADC0 and set the default input to mic-in
15705 /* port-A for surround (rear panel)
15706 * according to codec#0 this is the HP jack
15708 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15709 /* route front PCM to HP */
15710 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15711 /* port-B for mic-in (rear panel) with vref */
15712 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15713 /* port-C for line-in (rear panel) */
15714 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15715 /* port-D for Front */
15716 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15717 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15718 /* port-E for HP out (front panel) */
15719 /* this has to be set to VREF80 */
15720 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15721 /* route front PCM to HP */
15722 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15723 /* port-F for mic-in (front panel) with vref */
15724 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15725 /* port-G for CLFE (rear panel) */
15726 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15727 /* port-H for side (rear panel) */
15728 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15730 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15731 /* route front mic to ADC1*/
15732 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15733 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734 /* Unmute DAC0~3 & spdif out*/
15735 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15736 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15737 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15738 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15740 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15741 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15742 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15743 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15744 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15746 /* Unmute Stereo Mixer 15 */
15747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15754 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15760 /* hp used DAC 3 (Front) */
15761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15766 /* additional init verbs for ASUS laptops */
15767 static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15768 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15769 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15773 static const struct hda_verb alc861_toshiba_init_verbs[] = {
15774 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15779 /* toggle speaker-output according to the hp-jack state */
15780 static void alc861_toshiba_automute(struct hda_codec *codec)
15782 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15784 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15785 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15786 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15787 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15790 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15793 if ((res >> 26) == ALC880_HP_EVENT)
15794 alc861_toshiba_automute(codec);
15797 /* pcm configuration: identical with ALC880 */
15798 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15799 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15800 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15801 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15804 #define ALC861_DIGOUT_NID 0x07
15806 static const struct hda_channel_mode alc861_8ch_modes[1] = {
15810 static const hda_nid_t alc861_dac_nids[4] = {
15811 /* front, surround, clfe, side */
15812 0x03, 0x06, 0x05, 0x04
15815 static const hda_nid_t alc660_dac_nids[3] = {
15816 /* front, clfe, surround */
15820 static const hda_nid_t alc861_adc_nids[1] = {
15825 static const struct hda_input_mux alc861_capture_source = {
15829 { "Front Mic", 0x3 },
15836 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15838 struct alc_spec *spec = codec->spec;
15839 hda_nid_t mix, srcs[5];
15842 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15844 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15847 for (i = 0; i < num; i++) {
15849 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15850 if (type != AC_WID_AUD_OUT)
15852 for (j = 0; j < spec->multiout.num_dacs; j++)
15853 if (spec->multiout.dac_nids[j] == srcs[i])
15855 if (j >= spec->multiout.num_dacs)
15861 /* fill in the dac_nids table from the parsed pin configuration */
15862 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15863 const struct auto_pin_cfg *cfg)
15865 struct alc_spec *spec = codec->spec;
15867 hda_nid_t nid, dac;
15869 spec->multiout.dac_nids = spec->private_dac_nids;
15870 for (i = 0; i < cfg->line_outs; i++) {
15871 nid = cfg->line_out_pins[i];
15872 dac = alc861_look_for_dac(codec, nid);
15875 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
15880 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15881 hda_nid_t nid, int idx, unsigned int chs)
15883 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15884 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15887 #define alc861_create_out_sw(codec, pfx, nid, chs) \
15888 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15890 /* add playback controls from the parsed DAC table */
15891 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15892 const struct auto_pin_cfg *cfg)
15894 struct alc_spec *spec = codec->spec;
15896 int i, err, noutputs;
15898 noutputs = cfg->line_outs;
15899 if (spec->multi_ios > 0)
15900 noutputs += spec->multi_ios;
15902 for (i = 0; i < noutputs; i++) {
15905 nid = spec->multiout.dac_nids[i];
15908 name = alc_get_line_out_pfx(spec, i, true, &index);
15911 err = alc861_create_out_sw(codec, "Center", nid, 1);
15914 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15918 err = __alc861_create_out_sw(codec, name, nid, index, 3);
15926 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15928 struct alc_spec *spec = codec->spec;
15935 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15936 nid = alc861_look_for_dac(codec, pin);
15938 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15941 spec->multiout.hp_nid = nid;
15947 /* create playback/capture controls for input pins */
15948 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
15949 const struct auto_pin_cfg *cfg)
15951 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
15954 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15956 int pin_type, hda_nid_t dac)
15958 hda_nid_t mix, srcs[5];
15961 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15963 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15965 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15967 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15970 for (i = 0; i < num; i++) {
15972 if (srcs[i] == dac || srcs[i] == 0x15)
15973 mute = AMP_IN_UNMUTE(i);
15975 mute = AMP_IN_MUTE(i);
15976 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15981 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15983 struct alc_spec *spec = codec->spec;
15986 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
15987 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15988 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15990 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15991 spec->multiout.dac_nids[i]);
15995 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15997 struct alc_spec *spec = codec->spec;
15999 if (spec->autocfg.hp_outs)
16000 alc861_auto_set_output_and_unmute(codec,
16001 spec->autocfg.hp_pins[0],
16003 spec->multiout.hp_nid);
16004 if (spec->autocfg.speaker_outs)
16005 alc861_auto_set_output_and_unmute(codec,
16006 spec->autocfg.speaker_pins[0],
16008 spec->multiout.dac_nids[0]);
16011 #define alc861_auto_init_analog_input alc880_auto_init_analog_input
16013 /* parse the BIOS configuration and set up the alc_spec */
16014 /* return 1 if successful, 0 if the proper config is not found,
16015 * or a negative error code
16017 static int alc861_parse_auto_config(struct hda_codec *codec)
16019 struct alc_spec *spec = codec->spec;
16021 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16023 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16027 if (!spec->autocfg.line_outs)
16028 return 0; /* can't find valid BIOS pin config */
16030 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16033 err = alc_auto_add_multi_channel_mode(codec);
16036 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16039 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16042 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16046 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16048 alc_auto_parse_digital(codec);
16050 if (spec->kctls.list)
16051 add_mixer(spec, spec->kctls.list);
16053 spec->num_mux_defs = 1;
16054 spec->input_mux = &spec->private_imux[0];
16056 spec->adc_nids = alc861_adc_nids;
16057 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16058 set_capture_mixer(codec);
16060 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16065 /* additional initialization for auto-configuration model */
16066 static void alc861_auto_init(struct hda_codec *codec)
16068 struct alc_spec *spec = codec->spec;
16069 alc861_auto_init_multi_out(codec);
16070 alc861_auto_init_hp_out(codec);
16071 alc861_auto_init_analog_input(codec);
16072 alc_auto_init_digital(codec);
16073 if (spec->unsol_event)
16074 alc_inithook(codec);
16077 #ifdef CONFIG_SND_HDA_POWER_SAVE
16078 static const struct hda_amp_list alc861_loopbacks[] = {
16079 { 0x15, HDA_INPUT, 0 },
16080 { 0x15, HDA_INPUT, 1 },
16081 { 0x15, HDA_INPUT, 2 },
16082 { 0x15, HDA_INPUT, 3 },
16089 * configuration and preset
16091 static const char * const alc861_models[ALC861_MODEL_LAST] = {
16092 [ALC861_3ST] = "3stack",
16093 [ALC660_3ST] = "3stack-660",
16094 [ALC861_3ST_DIG] = "3stack-dig",
16095 [ALC861_6ST_DIG] = "6stack-dig",
16096 [ALC861_UNIWILL_M31] = "uniwill-m31",
16097 [ALC861_TOSHIBA] = "toshiba",
16098 [ALC861_ASUS] = "asus",
16099 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16100 [ALC861_AUTO] = "auto",
16103 static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16104 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16105 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16106 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16107 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16108 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16109 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16110 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16111 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16112 * Any other models that need this preset?
16114 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16115 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16116 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16117 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16118 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16119 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16120 /* FIXME: the below seems conflict */
16121 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16122 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16123 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16127 static const struct alc_config_preset alc861_presets[] = {
16129 .mixers = { alc861_3ST_mixer },
16130 .init_verbs = { alc861_threestack_init_verbs },
16131 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16132 .dac_nids = alc861_dac_nids,
16133 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16134 .channel_mode = alc861_threestack_modes,
16136 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16137 .adc_nids = alc861_adc_nids,
16138 .input_mux = &alc861_capture_source,
16140 [ALC861_3ST_DIG] = {
16141 .mixers = { alc861_base_mixer },
16142 .init_verbs = { alc861_threestack_init_verbs },
16143 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16144 .dac_nids = alc861_dac_nids,
16145 .dig_out_nid = ALC861_DIGOUT_NID,
16146 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16147 .channel_mode = alc861_threestack_modes,
16149 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16150 .adc_nids = alc861_adc_nids,
16151 .input_mux = &alc861_capture_source,
16153 [ALC861_6ST_DIG] = {
16154 .mixers = { alc861_base_mixer },
16155 .init_verbs = { alc861_base_init_verbs },
16156 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16157 .dac_nids = alc861_dac_nids,
16158 .dig_out_nid = ALC861_DIGOUT_NID,
16159 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16160 .channel_mode = alc861_8ch_modes,
16161 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16162 .adc_nids = alc861_adc_nids,
16163 .input_mux = &alc861_capture_source,
16166 .mixers = { alc861_3ST_mixer },
16167 .init_verbs = { alc861_threestack_init_verbs },
16168 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16169 .dac_nids = alc660_dac_nids,
16170 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16171 .channel_mode = alc861_threestack_modes,
16173 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16174 .adc_nids = alc861_adc_nids,
16175 .input_mux = &alc861_capture_source,
16177 [ALC861_UNIWILL_M31] = {
16178 .mixers = { alc861_uniwill_m31_mixer },
16179 .init_verbs = { alc861_uniwill_m31_init_verbs },
16180 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16181 .dac_nids = alc861_dac_nids,
16182 .dig_out_nid = ALC861_DIGOUT_NID,
16183 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16184 .channel_mode = alc861_uniwill_m31_modes,
16186 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16187 .adc_nids = alc861_adc_nids,
16188 .input_mux = &alc861_capture_source,
16190 [ALC861_TOSHIBA] = {
16191 .mixers = { alc861_toshiba_mixer },
16192 .init_verbs = { alc861_base_init_verbs,
16193 alc861_toshiba_init_verbs },
16194 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16195 .dac_nids = alc861_dac_nids,
16196 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16197 .channel_mode = alc883_3ST_2ch_modes,
16198 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16199 .adc_nids = alc861_adc_nids,
16200 .input_mux = &alc861_capture_source,
16201 .unsol_event = alc861_toshiba_unsol_event,
16202 .init_hook = alc861_toshiba_automute,
16205 .mixers = { alc861_asus_mixer },
16206 .init_verbs = { alc861_asus_init_verbs },
16207 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16208 .dac_nids = alc861_dac_nids,
16209 .dig_out_nid = ALC861_DIGOUT_NID,
16210 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16211 .channel_mode = alc861_asus_modes,
16214 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16215 .adc_nids = alc861_adc_nids,
16216 .input_mux = &alc861_capture_source,
16218 [ALC861_ASUS_LAPTOP] = {
16219 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16220 .init_verbs = { alc861_asus_init_verbs,
16221 alc861_asus_laptop_init_verbs },
16222 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16223 .dac_nids = alc861_dac_nids,
16224 .dig_out_nid = ALC861_DIGOUT_NID,
16225 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16226 .channel_mode = alc883_3ST_2ch_modes,
16228 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16229 .adc_nids = alc861_adc_nids,
16230 .input_mux = &alc861_capture_source,
16234 /* Pin config fixes */
16236 PINFIX_FSC_AMILO_PI1505,
16239 static const struct alc_fixup alc861_fixups[] = {
16240 [PINFIX_FSC_AMILO_PI1505] = {
16241 .type = ALC_FIXUP_PINS,
16242 .v.pins = (const struct alc_pincfg[]) {
16243 { 0x0b, 0x0221101f }, /* HP */
16244 { 0x0f, 0x90170310 }, /* speaker */
16250 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16251 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16255 static int patch_alc861(struct hda_codec *codec)
16257 struct alc_spec *spec;
16261 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16265 codec->spec = spec;
16267 spec->mixer_nid = 0x15;
16269 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16273 if (board_config < 0) {
16274 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16276 board_config = ALC861_AUTO;
16279 if (board_config == ALC861_AUTO) {
16280 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16281 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16284 if (board_config == ALC861_AUTO) {
16285 /* automatic parse from the BIOS config */
16286 err = alc861_parse_auto_config(codec);
16292 "hda_codec: Cannot set up configuration "
16293 "from BIOS. Using base mode...\n");
16294 board_config = ALC861_3ST_DIG;
16298 err = snd_hda_attach_beep_device(codec, 0x23);
16304 if (board_config != ALC861_AUTO)
16305 setup_preset(codec, &alc861_presets[board_config]);
16307 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16308 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16310 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16311 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16313 if (!spec->cap_mixer)
16314 set_capture_mixer(codec);
16315 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16317 spec->vmaster_nid = 0x03;
16319 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16321 codec->patch_ops = alc_patch_ops;
16322 if (board_config == ALC861_AUTO) {
16323 spec->init_hook = alc861_auto_init;
16324 #ifdef CONFIG_SND_HDA_POWER_SAVE
16325 spec->power_hook = alc_power_eapd;
16328 #ifdef CONFIG_SND_HDA_POWER_SAVE
16329 if (!spec->loopback.amplist)
16330 spec->loopback.amplist = alc861_loopbacks;
16337 * ALC861-VD support
16341 * In addition, an independent DAC
16343 #define ALC861VD_DIGOUT_NID 0x06
16345 static const hda_nid_t alc861vd_dac_nids[4] = {
16346 /* front, surr, clfe, side surr */
16347 0x02, 0x03, 0x04, 0x05
16350 /* dac_nids for ALC660vd are in a different order - according to
16351 * Realtek's driver.
16352 * This should probably result in a different mixer for 6stack models
16353 * of ALC660vd codecs, but for now there is only 3stack mixer
16354 * - and it is the same as in 861vd.
16355 * adc_nids in ALC660vd are (is) the same as in 861vd
16357 static const hda_nid_t alc660vd_dac_nids[3] = {
16358 /* front, rear, clfe, rear_surr */
16362 static const hda_nid_t alc861vd_adc_nids[1] = {
16367 static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16370 /* FIXME: should be a matrix-type input source selection */
16371 static const struct hda_input_mux alc861vd_capture_source = {
16375 { "Front Mic", 0x1 },
16381 static const struct hda_input_mux alc861vd_dallas_capture_source = {
16385 { "Internal Mic", 0x1 },
16389 static const struct hda_input_mux alc861vd_hp_capture_source = {
16392 { "Front Mic", 0x0 },
16393 { "ATAPI Mic", 0x1 },
16400 static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16407 static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16408 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16409 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16410 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16411 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16418 static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16419 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16420 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16421 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16422 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16426 static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16427 { 6, alc861vd_6stack_ch6_init },
16428 { 8, alc861vd_6stack_ch8_init },
16431 static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16434 .name = "Channel Mode",
16435 .info = alc_ch_mode_info,
16436 .get = alc_ch_mode_get,
16437 .put = alc_ch_mode_put,
16442 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16443 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16445 static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16446 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16447 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16449 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16450 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16452 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16454 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16456 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16457 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16459 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16460 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16468 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16469 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16470 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16472 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16473 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16475 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16476 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16481 static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16482 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16483 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16487 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16491 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16492 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16493 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16495 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16496 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16498 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16499 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16504 static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16505 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16506 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16507 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16509 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16511 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16513 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16515 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16516 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16517 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16519 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16520 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16525 /* Pin assignment: Speaker=0x14, HP = 0x15,
16526 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16528 static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16529 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16530 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16531 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16532 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16533 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16536 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16537 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16538 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16542 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16543 * Front Mic=0x18, ATAPI Mic = 0x19,
16545 static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16546 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16547 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16548 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16549 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16550 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16552 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16553 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16559 * generic initialization of ADC, input mixers and output mixers
16561 static const struct hda_verb alc861vd_volume_init_verbs[] = {
16563 * Unmute ADC0 and set the default input to mic-in
16565 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16566 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16568 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16569 * the analog-loopback mixer widget
16571 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16578 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16585 * Set up output mixers (0x02 - 0x05)
16587 /* set vol=0 to output mixers */
16588 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16589 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16590 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16591 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16593 /* set up input amps for analog loopback */
16594 /* Amp Indices: DAC = 0, mixer = 1 */
16595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16596 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16601 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16602 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16608 * 3-stack pin configuration:
16609 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16611 static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16613 * Set pin mode and muting
16615 /* set front pin widgets 0x14 for output */
16616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16617 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16618 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16620 /* Mic (rear) pin: input vref at 80% */
16621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16623 /* Front Mic pin: input vref at 80% */
16624 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16625 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16626 /* Line In pin: input */
16627 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16629 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16631 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16633 /* CD pin widget for input */
16634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16640 * 6-stack pin configuration:
16642 static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16644 * Set pin mode and muting
16646 /* set front pin widgets 0x14 for output */
16647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16649 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16651 /* Rear Pin: output 1 (0x0d) */
16652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16655 /* CLFE Pin: output 2 (0x0e) */
16656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16659 /* Side Pin: output 3 (0x0f) */
16660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16662 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16664 /* Mic (rear) pin: input vref at 80% */
16665 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16666 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16667 /* Front Mic pin: input vref at 80% */
16668 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16669 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16670 /* Line In pin: input */
16671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16672 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16673 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16676 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16677 /* CD pin widget for input */
16678 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16683 static const struct hda_verb alc861vd_eapd_verbs[] = {
16684 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16688 static const struct hda_verb alc660vd_eapd_verbs[] = {
16689 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16690 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16694 static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16698 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16699 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16703 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16705 struct alc_spec *spec = codec->spec;
16706 spec->autocfg.hp_pins[0] = 0x1b;
16707 spec->autocfg.speaker_pins[0] = 0x14;
16708 spec->automute = 1;
16709 spec->automute_mode = ALC_AUTOMUTE_AMP;
16712 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16714 alc_hp_automute(codec);
16715 alc88x_simple_mic_automute(codec);
16718 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16721 switch (res >> 26) {
16722 case ALC880_MIC_EVENT:
16723 alc88x_simple_mic_automute(codec);
16726 alc_sku_unsol_event(codec, res);
16731 static const struct hda_verb alc861vd_dallas_verbs[] = {
16732 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16733 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16734 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16735 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16739 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16741 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16743 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16750 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16752 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16753 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16755 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16761 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16762 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16769 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16770 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16771 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16776 /* toggle speaker-output according to the hp-jack state */
16777 static void alc861vd_dallas_setup(struct hda_codec *codec)
16779 struct alc_spec *spec = codec->spec;
16781 spec->autocfg.hp_pins[0] = 0x15;
16782 spec->autocfg.speaker_pins[0] = 0x14;
16783 spec->automute = 1;
16784 spec->automute_mode = ALC_AUTOMUTE_AMP;
16787 #ifdef CONFIG_SND_HDA_POWER_SAVE
16788 #define alc861vd_loopbacks alc880_loopbacks
16791 /* pcm configuration: identical with ALC880 */
16792 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16793 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16794 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16795 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16798 * configuration and preset
16800 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16801 [ALC660VD_3ST] = "3stack-660",
16802 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16803 [ALC660VD_ASUS_V1S] = "asus-v1s",
16804 [ALC861VD_3ST] = "3stack",
16805 [ALC861VD_3ST_DIG] = "3stack-digout",
16806 [ALC861VD_6ST_DIG] = "6stack-digout",
16807 [ALC861VD_LENOVO] = "lenovo",
16808 [ALC861VD_DALLAS] = "dallas",
16809 [ALC861VD_HP] = "hp",
16810 [ALC861VD_AUTO] = "auto",
16813 static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16814 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16815 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16816 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16817 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16818 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16819 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16820 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16821 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16822 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16823 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16824 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16825 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16826 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16827 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16828 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16832 static const struct alc_config_preset alc861vd_presets[] = {
16834 .mixers = { alc861vd_3st_mixer },
16835 .init_verbs = { alc861vd_volume_init_verbs,
16836 alc861vd_3stack_init_verbs },
16837 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16838 .dac_nids = alc660vd_dac_nids,
16839 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16840 .channel_mode = alc861vd_3stack_2ch_modes,
16841 .input_mux = &alc861vd_capture_source,
16843 [ALC660VD_3ST_DIG] = {
16844 .mixers = { alc861vd_3st_mixer },
16845 .init_verbs = { alc861vd_volume_init_verbs,
16846 alc861vd_3stack_init_verbs },
16847 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16848 .dac_nids = alc660vd_dac_nids,
16849 .dig_out_nid = ALC861VD_DIGOUT_NID,
16850 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16851 .channel_mode = alc861vd_3stack_2ch_modes,
16852 .input_mux = &alc861vd_capture_source,
16855 .mixers = { alc861vd_3st_mixer },
16856 .init_verbs = { alc861vd_volume_init_verbs,
16857 alc861vd_3stack_init_verbs },
16858 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16859 .dac_nids = alc861vd_dac_nids,
16860 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16861 .channel_mode = alc861vd_3stack_2ch_modes,
16862 .input_mux = &alc861vd_capture_source,
16864 [ALC861VD_3ST_DIG] = {
16865 .mixers = { alc861vd_3st_mixer },
16866 .init_verbs = { alc861vd_volume_init_verbs,
16867 alc861vd_3stack_init_verbs },
16868 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16869 .dac_nids = alc861vd_dac_nids,
16870 .dig_out_nid = ALC861VD_DIGOUT_NID,
16871 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16872 .channel_mode = alc861vd_3stack_2ch_modes,
16873 .input_mux = &alc861vd_capture_source,
16875 [ALC861VD_6ST_DIG] = {
16876 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16877 .init_verbs = { alc861vd_volume_init_verbs,
16878 alc861vd_6stack_init_verbs },
16879 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16880 .dac_nids = alc861vd_dac_nids,
16881 .dig_out_nid = ALC861VD_DIGOUT_NID,
16882 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16883 .channel_mode = alc861vd_6stack_modes,
16884 .input_mux = &alc861vd_capture_source,
16886 [ALC861VD_LENOVO] = {
16887 .mixers = { alc861vd_lenovo_mixer },
16888 .init_verbs = { alc861vd_volume_init_verbs,
16889 alc861vd_3stack_init_verbs,
16890 alc861vd_eapd_verbs,
16891 alc861vd_lenovo_unsol_verbs },
16892 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16893 .dac_nids = alc660vd_dac_nids,
16894 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16895 .channel_mode = alc861vd_3stack_2ch_modes,
16896 .input_mux = &alc861vd_capture_source,
16897 .unsol_event = alc861vd_lenovo_unsol_event,
16898 .setup = alc861vd_lenovo_setup,
16899 .init_hook = alc861vd_lenovo_init_hook,
16901 [ALC861VD_DALLAS] = {
16902 .mixers = { alc861vd_dallas_mixer },
16903 .init_verbs = { alc861vd_dallas_verbs },
16904 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16905 .dac_nids = alc861vd_dac_nids,
16906 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16907 .channel_mode = alc861vd_3stack_2ch_modes,
16908 .input_mux = &alc861vd_dallas_capture_source,
16909 .unsol_event = alc_sku_unsol_event,
16910 .setup = alc861vd_dallas_setup,
16911 .init_hook = alc_hp_automute,
16914 .mixers = { alc861vd_hp_mixer },
16915 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16916 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16917 .dac_nids = alc861vd_dac_nids,
16918 .dig_out_nid = ALC861VD_DIGOUT_NID,
16919 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16920 .channel_mode = alc861vd_3stack_2ch_modes,
16921 .input_mux = &alc861vd_hp_capture_source,
16922 .unsol_event = alc_sku_unsol_event,
16923 .setup = alc861vd_dallas_setup,
16924 .init_hook = alc_hp_automute,
16926 [ALC660VD_ASUS_V1S] = {
16927 .mixers = { alc861vd_lenovo_mixer },
16928 .init_verbs = { alc861vd_volume_init_verbs,
16929 alc861vd_3stack_init_verbs,
16930 alc861vd_eapd_verbs,
16931 alc861vd_lenovo_unsol_verbs },
16932 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16933 .dac_nids = alc660vd_dac_nids,
16934 .dig_out_nid = ALC861VD_DIGOUT_NID,
16935 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16936 .channel_mode = alc861vd_3stack_2ch_modes,
16937 .input_mux = &alc861vd_capture_source,
16938 .unsol_event = alc861vd_lenovo_unsol_event,
16939 .setup = alc861vd_lenovo_setup,
16940 .init_hook = alc861vd_lenovo_init_hook,
16945 * BIOS auto configuration
16947 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16948 const struct auto_pin_cfg *cfg)
16950 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
16954 #define alc861vd_auto_init_multi_out alc882_auto_init_multi_out
16955 #define alc861vd_auto_init_hp_out alc882_auto_init_hp_out
16956 #define alc861vd_auto_init_analog_input alc882_auto_init_analog_input
16957 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
16959 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16960 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16962 /* add playback controls from the parsed DAC table */
16963 /* Based on ALC880 version. But ALC861VD has separate,
16964 * different NIDs for mute/unmute switch and volume control */
16965 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16966 const struct auto_pin_cfg *cfg)
16968 hda_nid_t nid_v, nid_s;
16969 int i, err, noutputs;
16971 noutputs = cfg->line_outs;
16972 if (spec->multi_ios > 0)
16973 noutputs += spec->multi_ios;
16975 for (i = 0; i < noutputs; i++) {
16978 if (!spec->multiout.dac_nids[i])
16980 nid_v = alc861vd_idx_to_mixer_vol(
16982 spec->multiout.dac_nids[i]));
16983 nid_s = alc861vd_idx_to_mixer_switch(
16985 spec->multiout.dac_nids[i]));
16987 name = alc_get_line_out_pfx(spec, i, true, &index);
16990 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16992 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16996 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16998 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17002 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17004 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17008 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17010 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17015 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17017 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17021 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17023 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17032 /* add playback controls for speaker and HP outputs */
17033 /* Based on ALC880 version. But ALC861VD has separate,
17034 * different NIDs for mute/unmute switch and volume control */
17035 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17036 hda_nid_t pin, const char *pfx)
17038 hda_nid_t nid_v, nid_s;
17044 if (alc880_is_fixed_pin(pin)) {
17045 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17046 /* specify the DAC as the extra output */
17047 if (!spec->multiout.hp_nid)
17048 spec->multiout.hp_nid = nid_v;
17050 spec->multiout.extra_out_nid[0] = nid_v;
17051 /* control HP volume/switch on the output mixer amp */
17052 nid_v = alc861vd_idx_to_mixer_vol(
17053 alc880_fixed_pin_idx(pin));
17054 nid_s = alc861vd_idx_to_mixer_switch(
17055 alc880_fixed_pin_idx(pin));
17057 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17058 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17061 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17062 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17065 } else if (alc880_is_multi_pin(pin)) {
17066 /* set manual connection */
17067 /* we have only a switch on HP-out PIN */
17068 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17069 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17076 /* parse the BIOS configuration and set up the alc_spec
17077 * return 1 if successful, 0 if the proper config is not found,
17078 * or a negative error code
17079 * Based on ALC880 version - had to change it to override
17080 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17081 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17083 struct alc_spec *spec = codec->spec;
17085 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17087 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17091 if (!spec->autocfg.line_outs)
17092 return 0; /* can't find valid BIOS pin config */
17094 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17097 err = alc_auto_add_multi_channel_mode(codec);
17100 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17103 err = alc861vd_auto_create_extra_out(spec,
17104 spec->autocfg.speaker_pins[0],
17108 err = alc861vd_auto_create_extra_out(spec,
17109 spec->autocfg.hp_pins[0],
17113 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17117 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17119 alc_auto_parse_digital(codec);
17121 if (spec->kctls.list)
17122 add_mixer(spec, spec->kctls.list);
17124 spec->num_mux_defs = 1;
17125 spec->input_mux = &spec->private_imux[0];
17127 err = alc_auto_add_mic_boost(codec);
17131 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17136 /* additional initialization for auto-configuration model */
17137 static void alc861vd_auto_init(struct hda_codec *codec)
17139 struct alc_spec *spec = codec->spec;
17140 alc861vd_auto_init_multi_out(codec);
17141 alc861vd_auto_init_hp_out(codec);
17142 alc861vd_auto_init_analog_input(codec);
17143 alc861vd_auto_init_input_src(codec);
17144 alc_auto_init_digital(codec);
17145 if (spec->unsol_event)
17146 alc_inithook(codec);
17150 ALC660VD_FIX_ASUS_GPIO1
17154 static const struct alc_fixup alc861vd_fixups[] = {
17155 [ALC660VD_FIX_ASUS_GPIO1] = {
17156 .type = ALC_FIXUP_VERBS,
17157 .v.verbs = (const struct hda_verb[]) {
17158 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17159 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17160 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17166 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17167 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17171 static int patch_alc861vd(struct hda_codec *codec)
17173 struct alc_spec *spec;
17174 int err, board_config;
17176 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17180 codec->spec = spec;
17182 spec->mixer_nid = 0x0b;
17184 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17188 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17189 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17191 board_config = ALC861VD_AUTO;
17194 if (board_config == ALC861VD_AUTO) {
17195 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17196 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17199 if (board_config == ALC861VD_AUTO) {
17200 /* automatic parse from the BIOS config */
17201 err = alc861vd_parse_auto_config(codec);
17207 "hda_codec: Cannot set up configuration "
17208 "from BIOS. Using base mode...\n");
17209 board_config = ALC861VD_3ST;
17213 err = snd_hda_attach_beep_device(codec, 0x23);
17219 if (board_config != ALC861VD_AUTO)
17220 setup_preset(codec, &alc861vd_presets[board_config]);
17222 if (codec->vendor_id == 0x10ec0660) {
17223 /* always turn on EAPD */
17224 add_verb(spec, alc660vd_eapd_verbs);
17227 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17228 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17230 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17231 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17233 if (!spec->adc_nids) {
17234 spec->adc_nids = alc861vd_adc_nids;
17235 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17237 if (!spec->capsrc_nids)
17238 spec->capsrc_nids = alc861vd_capsrc_nids;
17240 set_capture_mixer(codec);
17241 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17243 spec->vmaster_nid = 0x02;
17245 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17247 codec->patch_ops = alc_patch_ops;
17249 if (board_config == ALC861VD_AUTO)
17250 spec->init_hook = alc861vd_auto_init;
17251 spec->shutup = alc_eapd_shutup;
17252 #ifdef CONFIG_SND_HDA_POWER_SAVE
17253 if (!spec->loopback.amplist)
17254 spec->loopback.amplist = alc861vd_loopbacks;
17263 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17264 * configuration. Each pin widget can choose any input DACs and a mixer.
17265 * Each ADC is connected from a mixer of all inputs. This makes possible
17266 * 6-channel independent captures.
17268 * In addition, an independent DAC for the multi-playback (not used in this
17271 #define ALC662_DIGOUT_NID 0x06
17272 #define ALC662_DIGIN_NID 0x0a
17274 static const hda_nid_t alc662_dac_nids[3] = {
17275 /* front, rear, clfe */
17279 static const hda_nid_t alc272_dac_nids[2] = {
17283 static const hda_nid_t alc662_adc_nids[2] = {
17288 static const hda_nid_t alc272_adc_nids[1] = {
17293 static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17294 static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17298 /* FIXME: should be a matrix-type input source selection */
17299 static const struct hda_input_mux alc662_capture_source = {
17303 { "Front Mic", 0x1 },
17309 static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17317 static const struct hda_input_mux alc663_capture_source = {
17321 { "Front Mic", 0x1 },
17326 #if 0 /* set to 1 for testing other input sources below */
17327 static const struct hda_input_mux alc272_nc10_capture_source = {
17330 { "Autoselect Mic", 0x0 },
17331 { "Internal Mic", 0x1 },
17332 { "In-0x02", 0x2 },
17333 { "In-0x03", 0x3 },
17334 { "In-0x04", 0x4 },
17335 { "In-0x05", 0x5 },
17336 { "In-0x06", 0x6 },
17337 { "In-0x07", 0x7 },
17338 { "In-0x08", 0x8 },
17339 { "In-0x09", 0x9 },
17340 { "In-0x0a", 0x0a },
17341 { "In-0x0b", 0x0b },
17342 { "In-0x0c", 0x0c },
17343 { "In-0x0d", 0x0d },
17344 { "In-0x0e", 0x0e },
17345 { "In-0x0f", 0x0f },
17353 static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17360 static const struct hda_verb alc662_3ST_ch2_init[] = {
17361 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17362 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17363 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17364 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17371 static const struct hda_verb alc662_3ST_ch6_init[] = {
17372 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17373 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17374 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17375 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17376 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17377 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17381 static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17382 { 2, alc662_3ST_ch2_init },
17383 { 6, alc662_3ST_ch6_init },
17389 static const struct hda_verb alc662_sixstack_ch6_init[] = {
17390 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17391 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17392 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17399 static const struct hda_verb alc662_sixstack_ch8_init[] = {
17400 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17401 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17402 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17406 static const struct hda_channel_mode alc662_5stack_modes[2] = {
17407 { 2, alc662_sixstack_ch6_init },
17408 { 6, alc662_sixstack_ch8_init },
17411 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17412 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17415 static const struct snd_kcontrol_new alc662_base_mixer[] = {
17416 /* output mixer control */
17417 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17418 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17419 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17420 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17421 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17422 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17423 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17424 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17427 /*Input mixer control */
17428 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17429 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17430 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17431 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17432 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17433 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17439 static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17440 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17441 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17442 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17443 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17444 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17445 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17446 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17454 static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17455 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17456 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17457 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17458 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17459 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17460 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17461 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17462 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17470 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17471 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17475 static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17476 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17477 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17478 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17479 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17488 static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17489 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17490 ALC262_HIPPO_MASTER_SWITCH,
17492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17496 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17497 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17498 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17502 static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17503 ALC262_HIPPO_MASTER_SWITCH,
17504 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17505 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17506 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17507 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17508 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17509 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17510 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17516 static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17517 .ops = &snd_hda_bind_vol,
17519 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17520 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17525 static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17526 .ops = &snd_hda_bind_sw,
17528 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17529 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17534 static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17535 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17536 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17542 static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17543 .ops = &snd_hda_bind_sw,
17545 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17546 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17547 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17552 static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17553 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17554 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17555 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17556 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17557 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17558 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17563 static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17564 .ops = &snd_hda_bind_sw,
17566 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17567 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17568 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17573 static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17574 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17575 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17578 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17579 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17583 static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17584 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17585 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17589 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17590 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17594 static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17595 .ops = &snd_hda_bind_vol,
17597 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17598 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17603 static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17604 .ops = &snd_hda_bind_sw,
17606 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17607 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17612 static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17613 HDA_BIND_VOL("Master Playback Volume",
17614 &alc663_asus_two_bind_master_vol),
17615 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17617 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17623 static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17624 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17625 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17626 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17633 static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17634 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17635 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17636 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17637 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17642 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17643 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17647 static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17648 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17649 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17654 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17655 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17656 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17657 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17661 static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17662 .ops = &snd_hda_bind_sw,
17664 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17665 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17666 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17667 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17668 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17673 static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17674 .ops = &snd_hda_bind_sw,
17676 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17677 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17682 static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17683 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17684 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17685 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17686 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17687 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17688 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17689 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17695 static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17696 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17697 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17698 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17699 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17700 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17707 static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17710 .name = "Channel Mode",
17711 .info = alc_ch_mode_info,
17712 .get = alc_ch_mode_get,
17713 .put = alc_ch_mode_put,
17718 static const struct hda_verb alc662_init_verbs[] = {
17719 /* ADC: mute amp left and right */
17720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17721 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17730 /* Front Pin: output 0 (0x0c) */
17731 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17732 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17734 /* Rear Pin: output 1 (0x0d) */
17735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17738 /* CLFE Pin: output 2 (0x0e) */
17739 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17742 /* Mic (rear) pin: input vref at 80% */
17743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17745 /* Front Mic pin: input vref at 80% */
17746 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17747 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17748 /* Line In pin: input */
17749 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17750 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17751 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17752 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17753 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17754 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17755 /* CD pin widget for input */
17756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17758 /* FIXME: use matrix-type input source selection */
17759 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17767 static const struct hda_verb alc662_eapd_init_verbs[] = {
17768 /* always trun on EAPD */
17769 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17770 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17774 static const struct hda_verb alc662_sue_init_verbs[] = {
17775 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17776 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17780 static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17781 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17782 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17786 /* Set Unsolicited Event*/
17787 static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17789 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17793 static const struct hda_verb alc663_m51va_init_verbs[] = {
17794 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17795 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17796 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17797 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17798 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17799 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17800 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17801 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17802 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17806 static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17807 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17808 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17809 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17811 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17812 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17813 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17817 static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17819 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17820 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17821 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17825 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17829 static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17831 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17832 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17833 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17834 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17835 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17836 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17840 static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17841 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17842 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17843 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17844 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17847 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17850 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17851 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17852 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17856 static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17857 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17858 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17859 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17860 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17864 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17865 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17867 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17868 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17872 static const struct hda_verb alc663_g71v_init_verbs[] = {
17873 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17874 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17875 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17877 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17878 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17879 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17882 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17883 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17887 static const struct hda_verb alc663_g50v_init_verbs[] = {
17888 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17889 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17890 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17892 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17893 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17897 static const struct hda_verb alc662_ecs_init_verbs[] = {
17898 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17899 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17901 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17905 static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17906 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17907 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17909 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17910 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17911 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17912 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17915 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17916 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17920 static const struct hda_verb alc272_dell_init_verbs[] = {
17921 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17922 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17924 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17925 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17926 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17927 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17929 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17930 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17931 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17935 static const struct hda_verb alc663_mode7_init_verbs[] = {
17936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17937 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17938 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17939 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17941 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17942 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17943 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17944 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17947 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17948 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17949 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17950 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17954 static const struct hda_verb alc663_mode8_init_verbs[] = {
17955 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17958 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17959 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17960 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17961 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17962 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17963 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17964 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17966 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17967 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17968 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17970 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17974 static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17975 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17976 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17980 static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17981 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17982 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17986 static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17988 struct alc_spec *spec = codec->spec;
17990 spec->autocfg.hp_pins[0] = 0x1b;
17991 spec->autocfg.line_out_pins[0] = 0x14;
17992 spec->autocfg.speaker_pins[0] = 0x15;
17993 spec->automute = 1;
17994 spec->detect_line = 1;
17995 spec->automute_lines = 1;
17996 spec->automute_mode = ALC_AUTOMUTE_AMP;
17999 static void alc662_eeepc_setup(struct hda_codec *codec)
18001 struct alc_spec *spec = codec->spec;
18003 alc262_hippo1_setup(codec);
18004 spec->ext_mic.pin = 0x18;
18005 spec->ext_mic.mux_idx = 0;
18006 spec->int_mic.pin = 0x19;
18007 spec->int_mic.mux_idx = 1;
18008 spec->auto_mic = 1;
18011 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18013 struct alc_spec *spec = codec->spec;
18015 spec->autocfg.hp_pins[0] = 0x14;
18016 spec->autocfg.speaker_pins[0] = 0x1b;
18017 spec->automute = 1;
18018 spec->automute_mode = ALC_AUTOMUTE_AMP;
18021 static void alc663_m51va_setup(struct hda_codec *codec)
18023 struct alc_spec *spec = codec->spec;
18024 spec->autocfg.hp_pins[0] = 0x21;
18025 spec->autocfg.speaker_pins[0] = 0x14;
18026 spec->automute_mixer_nid[0] = 0x0c;
18027 spec->automute = 1;
18028 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18029 spec->ext_mic.pin = 0x18;
18030 spec->ext_mic.mux_idx = 0;
18031 spec->int_mic.pin = 0x12;
18032 spec->int_mic.mux_idx = 9;
18033 spec->auto_mic = 1;
18036 /* ***************** Mode1 ******************************/
18037 static void alc663_mode1_setup(struct hda_codec *codec)
18039 struct alc_spec *spec = codec->spec;
18040 spec->autocfg.hp_pins[0] = 0x21;
18041 spec->autocfg.speaker_pins[0] = 0x14;
18042 spec->automute_mixer_nid[0] = 0x0c;
18043 spec->automute = 1;
18044 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18045 spec->ext_mic.pin = 0x18;
18046 spec->ext_mic.mux_idx = 0;
18047 spec->int_mic.pin = 0x19;
18048 spec->int_mic.mux_idx = 1;
18049 spec->auto_mic = 1;
18052 /* ***************** Mode2 ******************************/
18053 static void alc662_mode2_setup(struct hda_codec *codec)
18055 struct alc_spec *spec = codec->spec;
18056 spec->autocfg.hp_pins[0] = 0x1b;
18057 spec->autocfg.speaker_pins[0] = 0x14;
18058 spec->automute = 1;
18059 spec->automute_mode = ALC_AUTOMUTE_PIN;
18060 spec->ext_mic.pin = 0x18;
18061 spec->ext_mic.mux_idx = 0;
18062 spec->int_mic.pin = 0x19;
18063 spec->int_mic.mux_idx = 1;
18064 spec->auto_mic = 1;
18067 /* ***************** Mode3 ******************************/
18068 static void alc663_mode3_setup(struct hda_codec *codec)
18070 struct alc_spec *spec = codec->spec;
18071 spec->autocfg.hp_pins[0] = 0x21;
18072 spec->autocfg.hp_pins[0] = 0x15;
18073 spec->autocfg.speaker_pins[0] = 0x14;
18074 spec->automute = 1;
18075 spec->automute_mode = ALC_AUTOMUTE_PIN;
18076 spec->ext_mic.pin = 0x18;
18077 spec->ext_mic.mux_idx = 0;
18078 spec->int_mic.pin = 0x19;
18079 spec->int_mic.mux_idx = 1;
18080 spec->auto_mic = 1;
18083 /* ***************** Mode4 ******************************/
18084 static void alc663_mode4_setup(struct hda_codec *codec)
18086 struct alc_spec *spec = codec->spec;
18087 spec->autocfg.hp_pins[0] = 0x21;
18088 spec->autocfg.speaker_pins[0] = 0x14;
18089 spec->autocfg.speaker_pins[1] = 0x16;
18090 spec->automute_mixer_nid[0] = 0x0c;
18091 spec->automute_mixer_nid[1] = 0x0e;
18092 spec->automute = 1;
18093 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18094 spec->ext_mic.pin = 0x18;
18095 spec->ext_mic.mux_idx = 0;
18096 spec->int_mic.pin = 0x19;
18097 spec->int_mic.mux_idx = 1;
18098 spec->auto_mic = 1;
18101 /* ***************** Mode5 ******************************/
18102 static void alc663_mode5_setup(struct hda_codec *codec)
18104 struct alc_spec *spec = codec->spec;
18105 spec->autocfg.hp_pins[0] = 0x15;
18106 spec->autocfg.speaker_pins[0] = 0x14;
18107 spec->autocfg.speaker_pins[1] = 0x16;
18108 spec->automute_mixer_nid[0] = 0x0c;
18109 spec->automute_mixer_nid[1] = 0x0e;
18110 spec->automute = 1;
18111 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18112 spec->ext_mic.pin = 0x18;
18113 spec->ext_mic.mux_idx = 0;
18114 spec->int_mic.pin = 0x19;
18115 spec->int_mic.mux_idx = 1;
18116 spec->auto_mic = 1;
18119 /* ***************** Mode6 ******************************/
18120 static void alc663_mode6_setup(struct hda_codec *codec)
18122 struct alc_spec *spec = codec->spec;
18123 spec->autocfg.hp_pins[0] = 0x1b;
18124 spec->autocfg.hp_pins[0] = 0x15;
18125 spec->autocfg.speaker_pins[0] = 0x14;
18126 spec->automute_mixer_nid[0] = 0x0c;
18127 spec->automute = 1;
18128 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18129 spec->ext_mic.pin = 0x18;
18130 spec->ext_mic.mux_idx = 0;
18131 spec->int_mic.pin = 0x19;
18132 spec->int_mic.mux_idx = 1;
18133 spec->auto_mic = 1;
18136 /* ***************** Mode7 ******************************/
18137 static void alc663_mode7_setup(struct hda_codec *codec)
18139 struct alc_spec *spec = codec->spec;
18140 spec->autocfg.hp_pins[0] = 0x1b;
18141 spec->autocfg.hp_pins[0] = 0x21;
18142 spec->autocfg.speaker_pins[0] = 0x14;
18143 spec->autocfg.speaker_pins[0] = 0x17;
18144 spec->automute = 1;
18145 spec->automute_mode = ALC_AUTOMUTE_PIN;
18146 spec->ext_mic.pin = 0x18;
18147 spec->ext_mic.mux_idx = 0;
18148 spec->int_mic.pin = 0x19;
18149 spec->int_mic.mux_idx = 1;
18150 spec->auto_mic = 1;
18153 /* ***************** Mode8 ******************************/
18154 static void alc663_mode8_setup(struct hda_codec *codec)
18156 struct alc_spec *spec = codec->spec;
18157 spec->autocfg.hp_pins[0] = 0x21;
18158 spec->autocfg.hp_pins[1] = 0x15;
18159 spec->autocfg.speaker_pins[0] = 0x14;
18160 spec->autocfg.speaker_pins[0] = 0x17;
18161 spec->automute = 1;
18162 spec->automute_mode = ALC_AUTOMUTE_PIN;
18163 spec->ext_mic.pin = 0x18;
18164 spec->ext_mic.mux_idx = 0;
18165 spec->int_mic.pin = 0x12;
18166 spec->int_mic.mux_idx = 9;
18167 spec->auto_mic = 1;
18170 static void alc663_g71v_setup(struct hda_codec *codec)
18172 struct alc_spec *spec = codec->spec;
18173 spec->autocfg.hp_pins[0] = 0x21;
18174 spec->autocfg.line_out_pins[0] = 0x15;
18175 spec->autocfg.speaker_pins[0] = 0x14;
18176 spec->automute = 1;
18177 spec->automute_mode = ALC_AUTOMUTE_AMP;
18178 spec->detect_line = 1;
18179 spec->automute_lines = 1;
18180 spec->ext_mic.pin = 0x18;
18181 spec->ext_mic.mux_idx = 0;
18182 spec->int_mic.pin = 0x12;
18183 spec->int_mic.mux_idx = 9;
18184 spec->auto_mic = 1;
18187 #define alc663_g50v_setup alc663_m51va_setup
18189 static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18190 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18191 ALC262_HIPPO_MASTER_SWITCH,
18193 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18194 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18195 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18197 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18198 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18199 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18203 static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18204 /* Master Playback automatically created from Speaker and Headphone */
18205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18214 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18215 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18216 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18220 #ifdef CONFIG_SND_HDA_POWER_SAVE
18221 #define alc662_loopbacks alc880_loopbacks
18225 /* pcm configuration: identical with ALC880 */
18226 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18227 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18228 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18229 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18232 * configuration and preset
18234 static const char * const alc662_models[ALC662_MODEL_LAST] = {
18235 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18236 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18237 [ALC662_3ST_6ch] = "3stack-6ch",
18238 [ALC662_5ST_DIG] = "5stack-dig",
18239 [ALC662_LENOVO_101E] = "lenovo-101e",
18240 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18241 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18242 [ALC662_ECS] = "ecs",
18243 [ALC663_ASUS_M51VA] = "m51va",
18244 [ALC663_ASUS_G71V] = "g71v",
18245 [ALC663_ASUS_H13] = "h13",
18246 [ALC663_ASUS_G50V] = "g50v",
18247 [ALC663_ASUS_MODE1] = "asus-mode1",
18248 [ALC662_ASUS_MODE2] = "asus-mode2",
18249 [ALC663_ASUS_MODE3] = "asus-mode3",
18250 [ALC663_ASUS_MODE4] = "asus-mode4",
18251 [ALC663_ASUS_MODE5] = "asus-mode5",
18252 [ALC663_ASUS_MODE6] = "asus-mode6",
18253 [ALC663_ASUS_MODE7] = "asus-mode7",
18254 [ALC663_ASUS_MODE8] = "asus-mode8",
18255 [ALC272_DELL] = "dell",
18256 [ALC272_DELL_ZM1] = "dell-zm1",
18257 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18258 [ALC662_AUTO] = "auto",
18261 static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18262 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18263 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18264 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18265 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18266 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18267 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18268 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18269 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18270 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18271 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18272 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18273 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18274 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18275 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18276 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18277 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18278 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18279 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18280 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18281 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18282 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18283 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18284 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18285 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18286 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18287 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18288 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18289 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18290 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18291 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18292 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18293 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18294 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18295 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18296 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18297 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18298 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18299 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18300 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18301 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18302 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18303 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18304 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18305 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18306 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18307 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18308 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18309 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18310 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18311 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18312 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18313 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18314 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18315 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18316 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18317 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18318 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18319 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18320 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18321 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18322 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18323 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18324 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18325 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18326 ALC662_3ST_6ch_DIG),
18327 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18328 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18329 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18330 ALC662_3ST_6ch_DIG),
18331 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18332 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18333 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18334 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18335 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18336 ALC662_3ST_6ch_DIG),
18337 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18339 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18343 static const struct alc_config_preset alc662_presets[] = {
18344 [ALC662_3ST_2ch_DIG] = {
18345 .mixers = { alc662_3ST_2ch_mixer },
18346 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18347 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18348 .dac_nids = alc662_dac_nids,
18349 .dig_out_nid = ALC662_DIGOUT_NID,
18350 .dig_in_nid = ALC662_DIGIN_NID,
18351 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18352 .channel_mode = alc662_3ST_2ch_modes,
18353 .input_mux = &alc662_capture_source,
18355 [ALC662_3ST_6ch_DIG] = {
18356 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18357 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18358 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18359 .dac_nids = alc662_dac_nids,
18360 .dig_out_nid = ALC662_DIGOUT_NID,
18361 .dig_in_nid = ALC662_DIGIN_NID,
18362 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18363 .channel_mode = alc662_3ST_6ch_modes,
18365 .input_mux = &alc662_capture_source,
18367 [ALC662_3ST_6ch] = {
18368 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18369 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18370 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18371 .dac_nids = alc662_dac_nids,
18372 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18373 .channel_mode = alc662_3ST_6ch_modes,
18375 .input_mux = &alc662_capture_source,
18377 [ALC662_5ST_DIG] = {
18378 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18379 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18380 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18381 .dac_nids = alc662_dac_nids,
18382 .dig_out_nid = ALC662_DIGOUT_NID,
18383 .dig_in_nid = ALC662_DIGIN_NID,
18384 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18385 .channel_mode = alc662_5stack_modes,
18386 .input_mux = &alc662_capture_source,
18388 [ALC662_LENOVO_101E] = {
18389 .mixers = { alc662_lenovo_101e_mixer },
18390 .init_verbs = { alc662_init_verbs,
18391 alc662_eapd_init_verbs,
18392 alc662_sue_init_verbs },
18393 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18394 .dac_nids = alc662_dac_nids,
18395 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18396 .channel_mode = alc662_3ST_2ch_modes,
18397 .input_mux = &alc662_lenovo_101e_capture_source,
18398 .unsol_event = alc_sku_unsol_event,
18399 .setup = alc662_lenovo_101e_setup,
18400 .init_hook = alc_inithook,
18402 [ALC662_ASUS_EEEPC_P701] = {
18403 .mixers = { alc662_eeepc_p701_mixer },
18404 .init_verbs = { alc662_init_verbs,
18405 alc662_eapd_init_verbs,
18406 alc662_eeepc_sue_init_verbs },
18407 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18408 .dac_nids = alc662_dac_nids,
18409 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18410 .channel_mode = alc662_3ST_2ch_modes,
18411 .unsol_event = alc_sku_unsol_event,
18412 .setup = alc662_eeepc_setup,
18413 .init_hook = alc_inithook,
18415 [ALC662_ASUS_EEEPC_EP20] = {
18416 .mixers = { alc662_eeepc_ep20_mixer,
18417 alc662_chmode_mixer },
18418 .init_verbs = { alc662_init_verbs,
18419 alc662_eapd_init_verbs,
18420 alc662_eeepc_ep20_sue_init_verbs },
18421 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18422 .dac_nids = alc662_dac_nids,
18423 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18424 .channel_mode = alc662_3ST_6ch_modes,
18425 .input_mux = &alc662_lenovo_101e_capture_source,
18426 .unsol_event = alc_sku_unsol_event,
18427 .setup = alc662_eeepc_ep20_setup,
18428 .init_hook = alc_inithook,
18431 .mixers = { alc662_ecs_mixer },
18432 .init_verbs = { alc662_init_verbs,
18433 alc662_eapd_init_verbs,
18434 alc662_ecs_init_verbs },
18435 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18436 .dac_nids = alc662_dac_nids,
18437 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18438 .channel_mode = alc662_3ST_2ch_modes,
18439 .unsol_event = alc_sku_unsol_event,
18440 .setup = alc662_eeepc_setup,
18441 .init_hook = alc_inithook,
18443 [ALC663_ASUS_M51VA] = {
18444 .mixers = { alc663_m51va_mixer },
18445 .init_verbs = { alc662_init_verbs,
18446 alc662_eapd_init_verbs,
18447 alc663_m51va_init_verbs },
18448 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18449 .dac_nids = alc662_dac_nids,
18450 .dig_out_nid = ALC662_DIGOUT_NID,
18451 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18452 .channel_mode = alc662_3ST_2ch_modes,
18453 .unsol_event = alc_sku_unsol_event,
18454 .setup = alc663_m51va_setup,
18455 .init_hook = alc_inithook,
18457 [ALC663_ASUS_G71V] = {
18458 .mixers = { alc663_g71v_mixer },
18459 .init_verbs = { alc662_init_verbs,
18460 alc662_eapd_init_verbs,
18461 alc663_g71v_init_verbs },
18462 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18463 .dac_nids = alc662_dac_nids,
18464 .dig_out_nid = ALC662_DIGOUT_NID,
18465 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18466 .channel_mode = alc662_3ST_2ch_modes,
18467 .unsol_event = alc_sku_unsol_event,
18468 .setup = alc663_g71v_setup,
18469 .init_hook = alc_inithook,
18471 [ALC663_ASUS_H13] = {
18472 .mixers = { alc663_m51va_mixer },
18473 .init_verbs = { alc662_init_verbs,
18474 alc662_eapd_init_verbs,
18475 alc663_m51va_init_verbs },
18476 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18477 .dac_nids = alc662_dac_nids,
18478 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18479 .channel_mode = alc662_3ST_2ch_modes,
18480 .setup = alc663_m51va_setup,
18481 .unsol_event = alc_sku_unsol_event,
18482 .init_hook = alc_inithook,
18484 [ALC663_ASUS_G50V] = {
18485 .mixers = { alc663_g50v_mixer },
18486 .init_verbs = { alc662_init_verbs,
18487 alc662_eapd_init_verbs,
18488 alc663_g50v_init_verbs },
18489 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18490 .dac_nids = alc662_dac_nids,
18491 .dig_out_nid = ALC662_DIGOUT_NID,
18492 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18493 .channel_mode = alc662_3ST_6ch_modes,
18494 .input_mux = &alc663_capture_source,
18495 .unsol_event = alc_sku_unsol_event,
18496 .setup = alc663_g50v_setup,
18497 .init_hook = alc_inithook,
18499 [ALC663_ASUS_MODE1] = {
18500 .mixers = { alc663_m51va_mixer },
18501 .cap_mixer = alc662_auto_capture_mixer,
18502 .init_verbs = { alc662_init_verbs,
18503 alc662_eapd_init_verbs,
18504 alc663_21jd_amic_init_verbs },
18505 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18507 .dac_nids = alc662_dac_nids,
18508 .dig_out_nid = ALC662_DIGOUT_NID,
18509 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18510 .channel_mode = alc662_3ST_2ch_modes,
18511 .unsol_event = alc_sku_unsol_event,
18512 .setup = alc663_mode1_setup,
18513 .init_hook = alc_inithook,
18515 [ALC662_ASUS_MODE2] = {
18516 .mixers = { alc662_1bjd_mixer },
18517 .cap_mixer = alc662_auto_capture_mixer,
18518 .init_verbs = { alc662_init_verbs,
18519 alc662_eapd_init_verbs,
18520 alc662_1bjd_amic_init_verbs },
18521 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18522 .dac_nids = alc662_dac_nids,
18523 .dig_out_nid = ALC662_DIGOUT_NID,
18524 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18525 .channel_mode = alc662_3ST_2ch_modes,
18526 .unsol_event = alc_sku_unsol_event,
18527 .setup = alc662_mode2_setup,
18528 .init_hook = alc_inithook,
18530 [ALC663_ASUS_MODE3] = {
18531 .mixers = { alc663_two_hp_m1_mixer },
18532 .cap_mixer = alc662_auto_capture_mixer,
18533 .init_verbs = { alc662_init_verbs,
18534 alc662_eapd_init_verbs,
18535 alc663_two_hp_amic_m1_init_verbs },
18536 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18538 .dac_nids = alc662_dac_nids,
18539 .dig_out_nid = ALC662_DIGOUT_NID,
18540 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18541 .channel_mode = alc662_3ST_2ch_modes,
18542 .unsol_event = alc_sku_unsol_event,
18543 .setup = alc663_mode3_setup,
18544 .init_hook = alc_inithook,
18546 [ALC663_ASUS_MODE4] = {
18547 .mixers = { alc663_asus_21jd_clfe_mixer },
18548 .cap_mixer = alc662_auto_capture_mixer,
18549 .init_verbs = { alc662_init_verbs,
18550 alc662_eapd_init_verbs,
18551 alc663_21jd_amic_init_verbs},
18552 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18554 .dac_nids = alc662_dac_nids,
18555 .dig_out_nid = ALC662_DIGOUT_NID,
18556 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18557 .channel_mode = alc662_3ST_2ch_modes,
18558 .unsol_event = alc_sku_unsol_event,
18559 .setup = alc663_mode4_setup,
18560 .init_hook = alc_inithook,
18562 [ALC663_ASUS_MODE5] = {
18563 .mixers = { alc663_asus_15jd_clfe_mixer },
18564 .cap_mixer = alc662_auto_capture_mixer,
18565 .init_verbs = { alc662_init_verbs,
18566 alc662_eapd_init_verbs,
18567 alc663_15jd_amic_init_verbs },
18568 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18570 .dac_nids = alc662_dac_nids,
18571 .dig_out_nid = ALC662_DIGOUT_NID,
18572 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18573 .channel_mode = alc662_3ST_2ch_modes,
18574 .unsol_event = alc_sku_unsol_event,
18575 .setup = alc663_mode5_setup,
18576 .init_hook = alc_inithook,
18578 [ALC663_ASUS_MODE6] = {
18579 .mixers = { alc663_two_hp_m2_mixer },
18580 .cap_mixer = alc662_auto_capture_mixer,
18581 .init_verbs = { alc662_init_verbs,
18582 alc662_eapd_init_verbs,
18583 alc663_two_hp_amic_m2_init_verbs },
18584 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18586 .dac_nids = alc662_dac_nids,
18587 .dig_out_nid = ALC662_DIGOUT_NID,
18588 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18589 .channel_mode = alc662_3ST_2ch_modes,
18590 .unsol_event = alc_sku_unsol_event,
18591 .setup = alc663_mode6_setup,
18592 .init_hook = alc_inithook,
18594 [ALC663_ASUS_MODE7] = {
18595 .mixers = { alc663_mode7_mixer },
18596 .cap_mixer = alc662_auto_capture_mixer,
18597 .init_verbs = { alc662_init_verbs,
18598 alc662_eapd_init_verbs,
18599 alc663_mode7_init_verbs },
18600 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18602 .dac_nids = alc662_dac_nids,
18603 .dig_out_nid = ALC662_DIGOUT_NID,
18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18605 .channel_mode = alc662_3ST_2ch_modes,
18606 .unsol_event = alc_sku_unsol_event,
18607 .setup = alc663_mode7_setup,
18608 .init_hook = alc_inithook,
18610 [ALC663_ASUS_MODE8] = {
18611 .mixers = { alc663_mode8_mixer },
18612 .cap_mixer = alc662_auto_capture_mixer,
18613 .init_verbs = { alc662_init_verbs,
18614 alc662_eapd_init_verbs,
18615 alc663_mode8_init_verbs },
18616 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18618 .dac_nids = alc662_dac_nids,
18619 .dig_out_nid = ALC662_DIGOUT_NID,
18620 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18621 .channel_mode = alc662_3ST_2ch_modes,
18622 .unsol_event = alc_sku_unsol_event,
18623 .setup = alc663_mode8_setup,
18624 .init_hook = alc_inithook,
18627 .mixers = { alc663_m51va_mixer },
18628 .cap_mixer = alc272_auto_capture_mixer,
18629 .init_verbs = { alc662_init_verbs,
18630 alc662_eapd_init_verbs,
18631 alc272_dell_init_verbs },
18632 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18633 .dac_nids = alc272_dac_nids,
18634 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18635 .adc_nids = alc272_adc_nids,
18636 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18637 .capsrc_nids = alc272_capsrc_nids,
18638 .channel_mode = alc662_3ST_2ch_modes,
18639 .unsol_event = alc_sku_unsol_event,
18640 .setup = alc663_m51va_setup,
18641 .init_hook = alc_inithook,
18643 [ALC272_DELL_ZM1] = {
18644 .mixers = { alc663_m51va_mixer },
18645 .cap_mixer = alc662_auto_capture_mixer,
18646 .init_verbs = { alc662_init_verbs,
18647 alc662_eapd_init_verbs,
18648 alc272_dell_zm1_init_verbs },
18649 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18650 .dac_nids = alc272_dac_nids,
18651 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18652 .adc_nids = alc662_adc_nids,
18654 .capsrc_nids = alc662_capsrc_nids,
18655 .channel_mode = alc662_3ST_2ch_modes,
18656 .unsol_event = alc_sku_unsol_event,
18657 .setup = alc663_m51va_setup,
18658 .init_hook = alc_inithook,
18660 [ALC272_SAMSUNG_NC10] = {
18661 .mixers = { alc272_nc10_mixer },
18662 .init_verbs = { alc662_init_verbs,
18663 alc662_eapd_init_verbs,
18664 alc663_21jd_amic_init_verbs },
18665 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18666 .dac_nids = alc272_dac_nids,
18667 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18668 .channel_mode = alc662_3ST_2ch_modes,
18669 /*.input_mux = &alc272_nc10_capture_source,*/
18670 .unsol_event = alc_sku_unsol_event,
18671 .setup = alc663_mode4_setup,
18672 .init_hook = alc_inithook,
18678 * BIOS auto configuration
18681 /* convert from MIX nid to DAC */
18682 static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18687 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18688 for (i = 0; i < num; i++) {
18689 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18695 /* go down to the selector widget before the mixer */
18696 static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18699 int num = snd_hda_get_connections(codec, pin, srcs,
18702 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18707 /* get MIX nid connected to the given pin targeted to DAC */
18708 static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18714 pin = alc_go_down_to_selector(codec, pin);
18715 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18716 for (i = 0; i < num; i++) {
18717 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18723 /* select the connection from pin to DAC if needed */
18724 static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18730 pin = alc_go_down_to_selector(codec, pin);
18731 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18734 for (i = 0; i < num; i++) {
18735 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18736 snd_hda_codec_update_cache(codec, pin, 0,
18737 AC_VERB_SET_CONNECT_SEL, i);
18744 /* look for an empty DAC slot */
18745 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18747 struct alc_spec *spec = codec->spec;
18751 pin = alc_go_down_to_selector(codec, pin);
18752 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18753 for (i = 0; i < num; i++) {
18754 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18757 for (j = 0; j < spec->multiout.num_dacs; j++)
18758 if (spec->multiout.dac_nids[j] == nid)
18760 if (j >= spec->multiout.num_dacs)
18766 /* fill in the dac_nids table from the parsed pin configuration */
18767 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18768 const struct auto_pin_cfg *cfg)
18770 struct alc_spec *spec = codec->spec;
18774 spec->multiout.dac_nids = spec->private_dac_nids;
18775 spec->multiout.num_dacs = 0;
18776 for (i = 0; i < cfg->line_outs; i++) {
18777 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
18780 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18785 static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18786 hda_nid_t nid, int idx, unsigned int chs)
18788 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
18789 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18792 static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18793 hda_nid_t nid, int idx, unsigned int chs)
18795 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
18796 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18799 #define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18800 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18801 #define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18802 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
18803 #define alc662_add_stereo_vol(spec, pfx, nid) \
18804 alc662_add_vol_ctl(spec, pfx, nid, 3)
18805 #define alc662_add_stereo_sw(spec, pfx, nid) \
18806 alc662_add_sw_ctl(spec, pfx, nid, 3)
18808 /* add playback controls from the parsed DAC table */
18809 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18810 const struct auto_pin_cfg *cfg)
18812 struct alc_spec *spec = codec->spec;
18813 hda_nid_t nid, mix, pin;
18814 int i, err, noutputs;
18816 noutputs = cfg->line_outs;
18817 if (spec->multi_ios > 0)
18818 noutputs += spec->multi_ios;
18820 for (i = 0; i < noutputs; i++) {
18823 nid = spec->multiout.dac_nids[i];
18826 if (i >= cfg->line_outs)
18827 pin = spec->multi_io[i - 1].pin;
18829 pin = cfg->line_out_pins[i];
18830 mix = alc_auto_dac_to_mix(codec, pin, nid);
18833 name = alc_get_line_out_pfx(spec, i, true, &index);
18836 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
18839 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
18842 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
18845 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
18849 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
18852 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
18860 /* add playback controls for speaker and HP outputs */
18861 /* return DAC nid if any new DAC is assigned */
18862 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18865 struct alc_spec *spec = codec->spec;
18866 hda_nid_t nid, mix;
18871 nid = alc_auto_look_for_dac(codec, pin);
18873 /* the corresponding DAC is already occupied */
18874 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18875 return 0; /* no way */
18876 /* create a switch only */
18877 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18878 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18881 mix = alc_auto_dac_to_mix(codec, pin, nid);
18884 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18887 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18893 /* create playback/capture controls for input pins */
18894 #define alc662_auto_create_input_ctls \
18895 alc882_auto_create_input_ctls
18897 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18898 hda_nid_t nid, int pin_type,
18902 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18904 alc_set_pin_output(codec, nid, pin_type);
18905 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18906 for (i = 0; i < num; i++) {
18907 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18909 /* need the manual connection? */
18911 snd_hda_codec_write(codec, nid, 0,
18912 AC_VERB_SET_CONNECT_SEL, i);
18913 /* unmute mixer widget inputs */
18914 snd_hda_codec_write(codec, srcs[i], 0,
18915 AC_VERB_SET_AMP_GAIN_MUTE,
18917 snd_hda_codec_write(codec, srcs[i], 0,
18918 AC_VERB_SET_AMP_GAIN_MUTE,
18924 static void alc662_auto_init_multi_out(struct hda_codec *codec)
18926 struct alc_spec *spec = codec->spec;
18927 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18930 for (i = 0; i <= HDA_SIDE; i++) {
18931 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18933 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
18934 spec->multiout.dac_nids[i]);
18938 static void alc662_auto_init_hp_out(struct hda_codec *codec)
18940 struct alc_spec *spec = codec->spec;
18943 pin = spec->autocfg.hp_pins[0];
18945 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18946 spec->multiout.hp_nid);
18947 pin = spec->autocfg.speaker_pins[0];
18949 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18950 spec->multiout.extra_out_nid[0]);
18953 #define alc662_auto_init_analog_input alc882_auto_init_analog_input
18954 #define alc662_auto_init_input_src alc882_auto_init_input_src
18959 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18960 unsigned int location)
18962 struct alc_spec *spec = codec->spec;
18963 struct auto_pin_cfg *cfg = &spec->autocfg;
18964 int type, i, num_pins = 0;
18966 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18967 for (i = 0; i < cfg->num_inputs; i++) {
18968 hda_nid_t nid = cfg->inputs[i].pin;
18970 unsigned int defcfg, caps;
18971 if (cfg->inputs[i].type != type)
18973 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18974 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18976 if (location && get_defcfg_location(defcfg) != location)
18978 caps = snd_hda_query_pin_caps(codec, nid);
18979 if (!(caps & AC_PINCAP_OUT))
18981 dac = alc_auto_look_for_dac(codec, nid);
18984 spec->multi_io[num_pins].pin = nid;
18985 spec->multi_io[num_pins].dac = dac;
18987 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18990 spec->multiout.num_dacs = 1;
18996 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18997 struct snd_ctl_elem_info *uinfo)
18999 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19000 struct alc_spec *spec = codec->spec;
19002 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19004 uinfo->value.enumerated.items = spec->multi_ios + 1;
19005 if (uinfo->value.enumerated.item > spec->multi_ios)
19006 uinfo->value.enumerated.item = spec->multi_ios;
19007 sprintf(uinfo->value.enumerated.name, "%dch",
19008 (uinfo->value.enumerated.item + 1) * 2);
19012 static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19013 struct snd_ctl_elem_value *ucontrol)
19015 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19016 struct alc_spec *spec = codec->spec;
19017 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19021 static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19023 struct alc_spec *spec = codec->spec;
19024 hda_nid_t nid = spec->multi_io[idx].pin;
19026 if (!spec->multi_io[idx].ctl_in)
19027 spec->multi_io[idx].ctl_in =
19028 snd_hda_codec_read(codec, nid, 0,
19029 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19031 snd_hda_codec_update_cache(codec, nid, 0,
19032 AC_VERB_SET_PIN_WIDGET_CONTROL,
19034 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19035 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19037 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19039 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19040 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19041 HDA_AMP_MUTE, HDA_AMP_MUTE);
19042 snd_hda_codec_update_cache(codec, nid, 0,
19043 AC_VERB_SET_PIN_WIDGET_CONTROL,
19044 spec->multi_io[idx].ctl_in);
19049 static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19050 struct snd_ctl_elem_value *ucontrol)
19052 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19053 struct alc_spec *spec = codec->spec;
19056 ch = ucontrol->value.enumerated.item[0];
19057 if (ch < 0 || ch > spec->multi_ios)
19059 if (ch == (spec->ext_channel_count - 1) / 2)
19061 spec->ext_channel_count = (ch + 1) * 2;
19062 for (i = 0; i < spec->multi_ios; i++)
19063 alc_set_multi_io(codec, i, i < ch);
19064 spec->multiout.max_channels = spec->ext_channel_count;
19068 static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19070 .name = "Channel Mode",
19071 .info = alc_auto_ch_mode_info,
19072 .get = alc_auto_ch_mode_get,
19073 .put = alc_auto_ch_mode_put,
19076 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19078 struct alc_spec *spec = codec->spec;
19079 struct auto_pin_cfg *cfg = &spec->autocfg;
19080 unsigned int location, defcfg;
19083 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
19084 /* use HP as primary out */
19085 cfg->speaker_outs = cfg->line_outs;
19086 memcpy(cfg->speaker_pins, cfg->line_out_pins,
19087 sizeof(cfg->speaker_pins));
19088 cfg->line_outs = cfg->hp_outs;
19089 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
19091 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
19092 cfg->line_out_type = AUTO_PIN_HP_OUT;
19093 alc662_auto_fill_dac_nids(codec, cfg);
19095 if (cfg->line_outs != 1 ||
19096 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19099 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19100 location = get_defcfg_location(defcfg);
19102 num_pins = alc_auto_fill_multi_ios(codec, location);
19103 if (num_pins > 0) {
19104 struct snd_kcontrol_new *knew;
19106 knew = alc_kcontrol_new(spec);
19109 *knew = alc_auto_channel_mode_enum;
19110 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19114 spec->multi_ios = num_pins;
19115 spec->ext_channel_count = 2;
19116 spec->multiout.num_dacs = num_pins + 1;
19121 static int alc662_parse_auto_config(struct hda_codec *codec)
19123 struct alc_spec *spec = codec->spec;
19125 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19127 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19131 if (!spec->autocfg.line_outs)
19132 return 0; /* can't find valid BIOS pin config */
19134 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19137 err = alc_auto_add_multi_channel_mode(codec);
19140 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19143 err = alc662_auto_create_extra_out(codec,
19144 spec->autocfg.speaker_pins[0],
19149 spec->multiout.extra_out_nid[0] = err;
19150 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19155 spec->multiout.hp_nid = err;
19156 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19160 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19162 alc_auto_parse_digital(codec);
19164 if (spec->kctls.list)
19165 add_mixer(spec, spec->kctls.list);
19167 spec->num_mux_defs = 1;
19168 spec->input_mux = &spec->private_imux[0];
19170 err = alc_auto_add_mic_boost(codec);
19174 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19175 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19176 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19178 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19183 /* additional initialization for auto-configuration model */
19184 static void alc662_auto_init(struct hda_codec *codec)
19186 struct alc_spec *spec = codec->spec;
19187 alc662_auto_init_multi_out(codec);
19188 alc662_auto_init_hp_out(codec);
19189 alc662_auto_init_analog_input(codec);
19190 alc662_auto_init_input_src(codec);
19191 alc_auto_init_digital(codec);
19192 if (spec->unsol_event)
19193 alc_inithook(codec);
19196 static void alc272_fixup_mario(struct hda_codec *codec,
19197 const struct alc_fixup *fix, int action)
19199 if (action != ALC_FIXUP_ACT_PROBE)
19201 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19202 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19203 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19204 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19205 (0 << AC_AMPCAP_MUTE_SHIFT)))
19206 printk(KERN_WARNING
19207 "hda_codec: failed to override amp caps for NID 0x2\n");
19211 ALC662_FIXUP_ASPIRE,
19212 ALC662_FIXUP_IDEAPAD,
19213 ALC272_FIXUP_MARIO,
19214 ALC662_FIXUP_CZC_P10T,
19215 ALC662_FIXUP_SKU_IGNORE,
19218 static const struct alc_fixup alc662_fixups[] = {
19219 [ALC662_FIXUP_ASPIRE] = {
19220 .type = ALC_FIXUP_PINS,
19221 .v.pins = (const struct alc_pincfg[]) {
19222 { 0x15, 0x99130112 }, /* subwoofer */
19226 [ALC662_FIXUP_IDEAPAD] = {
19227 .type = ALC_FIXUP_PINS,
19228 .v.pins = (const struct alc_pincfg[]) {
19229 { 0x17, 0x99130112 }, /* subwoofer */
19233 [ALC272_FIXUP_MARIO] = {
19234 .type = ALC_FIXUP_FUNC,
19235 .v.func = alc272_fixup_mario,
19237 [ALC662_FIXUP_CZC_P10T] = {
19238 .type = ALC_FIXUP_VERBS,
19239 .v.verbs = (const struct hda_verb[]) {
19240 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19244 [ALC662_FIXUP_SKU_IGNORE] = {
19245 .type = ALC_FIXUP_SKU,
19246 .v.sku = ALC_FIXUP_SKU_IGNORE,
19250 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19251 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19252 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19253 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19254 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19255 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19256 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19257 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19261 static const struct alc_model_fixup alc662_fixup_models[] = {
19262 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19267 static int patch_alc662(struct hda_codec *codec)
19269 struct alc_spec *spec;
19270 int err, board_config;
19273 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19277 codec->spec = spec;
19279 spec->mixer_nid = 0x0b;
19281 alc_auto_parse_customize_define(codec);
19283 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19285 coef = alc_read_coef_idx(codec, 0);
19286 if (coef == 0x8020 || coef == 0x8011)
19287 alc_codec_rename(codec, "ALC661");
19288 else if (coef & (1 << 14) &&
19289 codec->bus->pci->subsystem_vendor == 0x1025 &&
19290 spec->cdefine.platform_type == 1)
19291 alc_codec_rename(codec, "ALC272X");
19292 else if (coef == 0x4011)
19293 alc_codec_rename(codec, "ALC656");
19295 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19298 if (board_config < 0) {
19299 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19301 board_config = ALC662_AUTO;
19304 if (board_config == ALC662_AUTO) {
19305 alc_pick_fixup(codec, alc662_fixup_models,
19306 alc662_fixup_tbl, alc662_fixups);
19307 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19308 /* automatic parse from the BIOS config */
19309 err = alc662_parse_auto_config(codec);
19315 "hda_codec: Cannot set up configuration "
19316 "from BIOS. Using base mode...\n");
19317 board_config = ALC662_3ST_2ch_DIG;
19321 if (has_cdefine_beep(codec)) {
19322 err = snd_hda_attach_beep_device(codec, 0x1);
19329 if (board_config != ALC662_AUTO)
19330 setup_preset(codec, &alc662_presets[board_config]);
19332 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19333 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19335 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19336 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19338 if (!spec->adc_nids) {
19339 spec->adc_nids = alc662_adc_nids;
19340 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19342 if (!spec->capsrc_nids)
19343 spec->capsrc_nids = alc662_capsrc_nids;
19345 if (!spec->cap_mixer)
19346 set_capture_mixer(codec);
19348 if (has_cdefine_beep(codec)) {
19349 switch (codec->vendor_id) {
19351 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19356 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19359 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19363 spec->vmaster_nid = 0x02;
19365 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19367 codec->patch_ops = alc_patch_ops;
19368 if (board_config == ALC662_AUTO)
19369 spec->init_hook = alc662_auto_init;
19370 spec->shutup = alc_eapd_shutup;
19372 alc_init_jacks(codec);
19374 #ifdef CONFIG_SND_HDA_POWER_SAVE
19375 if (!spec->loopback.amplist)
19376 spec->loopback.amplist = alc662_loopbacks;
19382 static int patch_alc888(struct hda_codec *codec)
19384 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19385 kfree(codec->chip_name);
19386 if (codec->vendor_id == 0x10ec0887)
19387 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19389 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19390 if (!codec->chip_name) {
19394 return patch_alc662(codec);
19396 return patch_alc882(codec);
19399 static int patch_alc899(struct hda_codec *codec)
19401 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19402 kfree(codec->chip_name);
19403 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19405 return patch_alc882(codec);
19411 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19412 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19413 #define alc680_modes alc260_modes
19415 static const hda_nid_t alc680_dac_nids[3] = {
19416 /* Lout1, Lout2, hp */
19420 static const hda_nid_t alc680_adc_nids[3] = {
19422 /* DMIC, MIC, Line-in*/
19427 * Analog capture ADC cgange
19429 static void alc680_rec_autoswitch(struct hda_codec *codec)
19431 struct alc_spec *spec = codec->spec;
19432 struct auto_pin_cfg *cfg = &spec->autocfg;
19434 int type_found = AUTO_PIN_LAST;
19438 for (i = 0; i < cfg->num_inputs; i++) {
19439 nid = cfg->inputs[i].pin;
19440 if (!is_jack_detectable(codec, nid))
19442 if (snd_hda_jack_detect(codec, nid)) {
19443 if (cfg->inputs[i].type < type_found) {
19444 type_found = cfg->inputs[i].type;
19452 snd_hda_get_connections(codec, pin_found, &nid, 1);
19454 if (nid != spec->cur_adc)
19455 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19456 spec->cur_adc = nid;
19457 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19458 spec->cur_adc_format);
19461 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19462 struct hda_codec *codec,
19463 unsigned int stream_tag,
19464 unsigned int format,
19465 struct snd_pcm_substream *substream)
19467 struct alc_spec *spec = codec->spec;
19469 spec->cur_adc = 0x07;
19470 spec->cur_adc_stream_tag = stream_tag;
19471 spec->cur_adc_format = format;
19473 alc680_rec_autoswitch(codec);
19477 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19478 struct hda_codec *codec,
19479 struct snd_pcm_substream *substream)
19481 snd_hda_codec_cleanup_stream(codec, 0x07);
19482 snd_hda_codec_cleanup_stream(codec, 0x08);
19483 snd_hda_codec_cleanup_stream(codec, 0x09);
19487 static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19488 .substreams = 1, /* can be overridden */
19491 /* NID is set in alc_build_pcms */
19493 .prepare = alc680_capture_pcm_prepare,
19494 .cleanup = alc680_capture_pcm_cleanup
19498 static const struct snd_kcontrol_new alc680_base_mixer[] = {
19499 /* output mixer control */
19500 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19501 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19502 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19503 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19504 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19505 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19506 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19510 static const struct hda_bind_ctls alc680_bind_cap_vol = {
19511 .ops = &snd_hda_bind_vol,
19513 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19514 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19515 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19520 static const struct hda_bind_ctls alc680_bind_cap_switch = {
19521 .ops = &snd_hda_bind_sw,
19523 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19524 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19525 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19530 static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19531 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19532 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19537 * generic initialization of ADC, input mixers and output mixers
19539 static const struct hda_verb alc680_init_verbs[] = {
19540 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19541 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19542 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19544 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19545 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19547 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19548 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19549 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19553 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19557 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19558 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19559 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19564 /* toggle speaker-output according to the hp-jack state */
19565 static void alc680_base_setup(struct hda_codec *codec)
19567 struct alc_spec *spec = codec->spec;
19569 spec->autocfg.hp_pins[0] = 0x16;
19570 spec->autocfg.speaker_pins[0] = 0x14;
19571 spec->autocfg.speaker_pins[1] = 0x15;
19572 spec->autocfg.num_inputs = 2;
19573 spec->autocfg.inputs[0].pin = 0x18;
19574 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19575 spec->autocfg.inputs[1].pin = 0x19;
19576 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19577 spec->automute = 1;
19578 spec->automute_mode = ALC_AUTOMUTE_AMP;
19581 static void alc680_unsol_event(struct hda_codec *codec,
19584 if ((res >> 26) == ALC880_HP_EVENT)
19585 alc_hp_automute(codec);
19586 if ((res >> 26) == ALC880_MIC_EVENT)
19587 alc680_rec_autoswitch(codec);
19590 static void alc680_inithook(struct hda_codec *codec)
19592 alc_hp_automute(codec);
19593 alc680_rec_autoswitch(codec);
19596 /* create input playback/capture controls for the given pin */
19597 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19598 const char *ctlname, int idx)
19616 if (spec->multiout.dac_nids[0] != dac &&
19617 spec->multiout.dac_nids[1] != dac) {
19618 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19619 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19624 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19625 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19629 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19635 /* add playback controls from the parsed DAC table */
19636 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19637 const struct auto_pin_cfg *cfg)
19642 spec->multiout.dac_nids = spec->private_dac_nids;
19644 nid = cfg->line_out_pins[0];
19648 name = alc_get_line_out_pfx(spec, 0, true, &index);
19649 err = alc680_new_analog_output(spec, nid, name, 0);
19654 nid = cfg->speaker_pins[0];
19656 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19660 nid = cfg->hp_pins[0];
19662 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19670 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19671 hda_nid_t nid, int pin_type)
19673 alc_set_pin_output(codec, nid, pin_type);
19676 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19678 struct alc_spec *spec = codec->spec;
19679 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19681 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19682 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19686 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19688 struct alc_spec *spec = codec->spec;
19691 pin = spec->autocfg.hp_pins[0];
19693 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19694 pin = spec->autocfg.speaker_pins[0];
19696 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19699 /* pcm configuration: identical with ALC880 */
19700 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19701 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19702 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19703 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19704 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19707 * BIOS auto configuration
19709 static int alc680_parse_auto_config(struct hda_codec *codec)
19711 struct alc_spec *spec = codec->spec;
19713 static const hda_nid_t alc680_ignore[] = { 0 };
19715 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19720 if (!spec->autocfg.line_outs) {
19721 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19722 spec->multiout.max_channels = 2;
19723 spec->no_analog = 1;
19726 return 0; /* can't find valid BIOS pin config */
19728 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19732 spec->multiout.max_channels = 2;
19735 /* digital only support output */
19736 alc_auto_parse_digital(codec);
19737 if (spec->kctls.list)
19738 add_mixer(spec, spec->kctls.list);
19740 err = alc_auto_add_mic_boost(codec);
19747 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19749 /* init callback for auto-configuration model -- overriding the default init */
19750 static void alc680_auto_init(struct hda_codec *codec)
19752 struct alc_spec *spec = codec->spec;
19753 alc680_auto_init_multi_out(codec);
19754 alc680_auto_init_hp_out(codec);
19755 alc680_auto_init_analog_input(codec);
19756 alc_auto_init_digital(codec);
19757 if (spec->unsol_event)
19758 alc_inithook(codec);
19762 * configuration and preset
19764 static const char * const alc680_models[ALC680_MODEL_LAST] = {
19765 [ALC680_BASE] = "base",
19766 [ALC680_AUTO] = "auto",
19769 static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19770 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19774 static const struct alc_config_preset alc680_presets[] = {
19776 .mixers = { alc680_base_mixer },
19777 .cap_mixer = alc680_master_capture_mixer,
19778 .init_verbs = { alc680_init_verbs },
19779 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19780 .dac_nids = alc680_dac_nids,
19781 .dig_out_nid = ALC680_DIGOUT_NID,
19782 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19783 .channel_mode = alc680_modes,
19784 .unsol_event = alc680_unsol_event,
19785 .setup = alc680_base_setup,
19786 .init_hook = alc680_inithook,
19791 static int patch_alc680(struct hda_codec *codec)
19793 struct alc_spec *spec;
19797 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19801 codec->spec = spec;
19803 /* ALC680 has no aa-loopback mixer */
19805 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19809 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19810 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19812 board_config = ALC680_AUTO;
19815 if (board_config == ALC680_AUTO) {
19816 /* automatic parse from the BIOS config */
19817 err = alc680_parse_auto_config(codec);
19823 "hda_codec: Cannot set up configuration "
19824 "from BIOS. Using base mode...\n");
19825 board_config = ALC680_BASE;
19829 if (board_config != ALC680_AUTO)
19830 setup_preset(codec, &alc680_presets[board_config]);
19832 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19833 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
19834 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19835 spec->stream_digital_capture = &alc680_pcm_digital_capture;
19837 if (!spec->adc_nids) {
19838 spec->adc_nids = alc680_adc_nids;
19839 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19842 if (!spec->cap_mixer)
19843 set_capture_mixer(codec);
19845 spec->vmaster_nid = 0x02;
19847 codec->patch_ops = alc_patch_ops;
19848 if (board_config == ALC680_AUTO)
19849 spec->init_hook = alc680_auto_init;
19857 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
19858 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
19859 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19860 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19861 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
19862 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
19863 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
19864 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19865 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19866 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
19867 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
19868 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19869 .patch = patch_alc861 },
19870 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19871 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19872 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
19873 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
19874 .patch = patch_alc882 },
19875 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19876 .patch = patch_alc662 },
19877 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
19878 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19879 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19880 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
19881 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
19882 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
19883 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
19884 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
19885 .patch = patch_alc882 },
19886 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19887 .patch = patch_alc882 },
19888 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19889 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
19890 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19891 .patch = patch_alc882 },
19892 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19893 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19894 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
19895 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
19896 {} /* terminator */
19899 MODULE_ALIAS("snd-hda-codec-id:10ec*");
19901 MODULE_LICENSE("GPL");
19902 MODULE_DESCRIPTION("Realtek HD-audio codec");
19904 static struct hda_codec_preset_list realtek_list = {
19905 .preset = snd_hda_preset_realtek,
19906 .owner = THIS_MODULE,
19909 static int __init patch_realtek_init(void)
19911 return snd_hda_add_codec_preset(&realtek_list);
19914 static void __exit patch_realtek_exit(void)
19916 snd_hda_delete_codec_preset(&realtek_list);
19919 module_init(patch_realtek_init)
19920 module_exit(patch_realtek_exit)