2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
222 ALC883_TARGA_2ch_DIG,
225 ALC888_ACER_ASPIRE_4930G,
226 ALC888_ACER_ASPIRE_8930G,
230 ALC883_LENOVO_101E_2ch,
231 ALC883_LENOVO_NB0763,
232 ALC888_LENOVO_MS7195_DIG,
239 ALC883_FUJITSU_PI2515,
240 ALC888_FUJITSU_XA3530,
241 ALC883_3ST_6ch_INTEL,
250 /* styles of capture selection */
252 CAPT_MUX = 0, /* only mux based */
253 CAPT_MIX, /* only mixer based */
254 CAPT_1MUX_MIX, /* first mux and other mixers */
258 #define GPIO_MASK 0x03
260 /* extra amp-initialization sequence types */
270 /* codec parameterization */
271 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
272 unsigned int num_mixers;
273 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
274 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
276 const struct hda_verb *init_verbs[5]; /* initialization verbs
280 unsigned int num_init_verbs;
282 char stream_name_analog[16]; /* analog PCM stream */
283 struct hda_pcm_stream *stream_analog_playback;
284 struct hda_pcm_stream *stream_analog_capture;
285 struct hda_pcm_stream *stream_analog_alt_playback;
286 struct hda_pcm_stream *stream_analog_alt_capture;
288 char stream_name_digital[16]; /* digital PCM stream */
289 struct hda_pcm_stream *stream_digital_playback;
290 struct hda_pcm_stream *stream_digital_capture;
293 struct hda_multi_out multiout; /* playback set-up
294 * max_channels, dacs must be set
295 * dig_out_nid and hp_nid are optional
297 hda_nid_t alt_dac_nid;
298 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
302 unsigned int num_adc_nids;
304 hda_nid_t *capsrc_nids;
305 hda_nid_t dig_in_nid; /* digital-in NID; optional */
306 int capture_style; /* capture style (CAPT_*) */
309 unsigned int num_mux_defs;
310 const struct hda_input_mux *input_mux;
311 unsigned int cur_mux[3];
314 const struct hda_channel_mode *channel_mode;
315 int num_channel_mode;
317 int const_channel_count;
318 int ext_channel_count;
320 /* PCM information */
321 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
323 /* dynamic controls, init_verbs and input_mux */
324 struct auto_pin_cfg autocfg;
325 struct snd_array kctls;
326 struct hda_input_mux private_imux[3];
327 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
330 void (*init_hook)(struct hda_codec *codec);
331 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
333 /* for pin sensing */
334 unsigned int sense_updated: 1;
335 unsigned int jack_present: 1;
336 unsigned int master_sw: 1;
339 unsigned int no_analog :1; /* digital I/O only */
342 /* for virtual master */
343 hda_nid_t vmaster_nid;
344 #ifdef CONFIG_SND_HDA_POWER_SAVE
345 struct hda_loopback_check loopback;
350 unsigned int pll_coef_idx, pll_coef_bit;
354 * configuration template - to be copied to the spec instance
356 struct alc_config_preset {
357 struct snd_kcontrol_new *mixers[5]; /* should be identical size
360 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
361 const struct hda_verb *init_verbs[5];
362 unsigned int num_dacs;
364 hda_nid_t dig_out_nid; /* optional */
365 hda_nid_t hp_nid; /* optional */
366 hda_nid_t *slave_dig_outs;
367 unsigned int num_adc_nids;
369 hda_nid_t *capsrc_nids;
370 hda_nid_t dig_in_nid;
371 unsigned int num_channel_mode;
372 const struct hda_channel_mode *channel_mode;
374 int const_channel_count;
375 unsigned int num_mux_defs;
376 const struct hda_input_mux *input_mux;
377 void (*unsol_event)(struct hda_codec *, unsigned int);
378 void (*init_hook)(struct hda_codec *);
379 #ifdef CONFIG_SND_HDA_POWER_SAVE
380 struct hda_amp_list *loopbacks;
388 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
389 struct snd_ctl_elem_info *uinfo)
391 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
392 struct alc_spec *spec = codec->spec;
393 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
394 if (mux_idx >= spec->num_mux_defs)
396 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
399 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
400 struct snd_ctl_elem_value *ucontrol)
402 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
403 struct alc_spec *spec = codec->spec;
404 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
406 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
410 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
411 struct snd_ctl_elem_value *ucontrol)
413 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
414 struct alc_spec *spec = codec->spec;
415 const struct hda_input_mux *imux;
416 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
417 unsigned int mux_idx;
418 hda_nid_t nid = spec->capsrc_nids ?
419 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
421 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
422 imux = &spec->input_mux[mux_idx];
424 if (spec->capture_style &&
425 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
426 /* Matrix-mixer style (e.g. ALC882) */
427 unsigned int *cur_val = &spec->cur_mux[adc_idx];
430 idx = ucontrol->value.enumerated.item[0];
431 if (idx >= imux->num_items)
432 idx = imux->num_items - 1;
435 for (i = 0; i < imux->num_items; i++) {
436 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
437 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
438 imux->items[i].index,
444 /* MUX style (e.g. ALC880) */
445 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
446 &spec->cur_mux[adc_idx]);
451 * channel mode setting
453 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_info *uinfo)
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct alc_spec *spec = codec->spec;
458 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
459 spec->num_channel_mode);
462 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
463 struct snd_ctl_elem_value *ucontrol)
465 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
466 struct alc_spec *spec = codec->spec;
467 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
468 spec->num_channel_mode,
469 spec->ext_channel_count);
472 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
477 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
478 spec->num_channel_mode,
479 &spec->ext_channel_count);
480 if (err >= 0 && !spec->const_channel_count) {
481 spec->multiout.max_channels = spec->ext_channel_count;
482 if (spec->need_dac_fix)
483 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
489 * Control the mode of pin widget settings via the mixer. "pc" is used
490 * instead of "%" to avoid consequences of accidently treating the % as
491 * being part of a format specifier. Maximum allowed length of a value is
492 * 63 characters plus NULL terminator.
494 * Note: some retasking pin complexes seem to ignore requests for input
495 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
496 * are requested. Therefore order this list so that this behaviour will not
497 * cause problems when mixer clients move through the enum sequentially.
498 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
501 static char *alc_pin_mode_names[] = {
502 "Mic 50pc bias", "Mic 80pc bias",
503 "Line in", "Line out", "Headphone out",
505 static unsigned char alc_pin_mode_values[] = {
506 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
508 /* The control can present all 5 options, or it can limit the options based
509 * in the pin being assumed to be exclusively an input or an output pin. In
510 * addition, "input" pins may or may not process the mic bias option
511 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
512 * accept requests for bias as of chip versions up to March 2006) and/or
513 * wiring in the computer.
515 #define ALC_PIN_DIR_IN 0x00
516 #define ALC_PIN_DIR_OUT 0x01
517 #define ALC_PIN_DIR_INOUT 0x02
518 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
519 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
521 /* Info about the pin modes supported by the different pin direction modes.
522 * For each direction the minimum and maximum values are given.
524 static signed char alc_pin_mode_dir_info[5][2] = {
525 { 0, 2 }, /* ALC_PIN_DIR_IN */
526 { 3, 4 }, /* ALC_PIN_DIR_OUT */
527 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
528 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
529 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
531 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
532 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
533 #define alc_pin_mode_n_items(_dir) \
534 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
536 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
537 struct snd_ctl_elem_info *uinfo)
539 unsigned int item_num = uinfo->value.enumerated.item;
540 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
542 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
544 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
546 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
547 item_num = alc_pin_mode_min(dir);
548 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
552 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 hda_nid_t nid = kcontrol->private_value & 0xffff;
558 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
559 long *valp = ucontrol->value.integer.value;
560 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
561 AC_VERB_GET_PIN_WIDGET_CONTROL,
564 /* Find enumerated value for current pinctl setting */
565 i = alc_pin_mode_min(dir);
566 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
568 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
572 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
573 struct snd_ctl_elem_value *ucontrol)
576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577 hda_nid_t nid = kcontrol->private_value & 0xffff;
578 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
579 long val = *ucontrol->value.integer.value;
580 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
581 AC_VERB_GET_PIN_WIDGET_CONTROL,
584 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
585 val = alc_pin_mode_min(dir);
587 change = pinctl != alc_pin_mode_values[val];
589 /* Set pin mode to that requested */
590 snd_hda_codec_write_cache(codec, nid, 0,
591 AC_VERB_SET_PIN_WIDGET_CONTROL,
592 alc_pin_mode_values[val]);
594 /* Also enable the retasking pin's input/output as required
595 * for the requested pin mode. Enum values of 2 or less are
598 * Dynamically switching the input/output buffers probably
599 * reduces noise slightly (particularly on input) so we'll
600 * do it. However, having both input and output buffers
601 * enabled simultaneously doesn't seem to be problematic if
602 * this turns out to be necessary in the future.
605 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
606 HDA_AMP_MUTE, HDA_AMP_MUTE);
607 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
610 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
611 HDA_AMP_MUTE, HDA_AMP_MUTE);
612 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
619 #define ALC_PIN_MODE(xname, nid, dir) \
620 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
621 .info = alc_pin_mode_info, \
622 .get = alc_pin_mode_get, \
623 .put = alc_pin_mode_put, \
624 .private_value = nid | (dir<<16) }
626 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
627 * together using a mask with more than one bit set. This control is
628 * currently used only by the ALC260 test model. At this stage they are not
629 * needed for any "production" models.
631 #ifdef CONFIG_SND_DEBUG
632 #define alc_gpio_data_info snd_ctl_boolean_mono_info
634 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
638 hda_nid_t nid = kcontrol->private_value & 0xffff;
639 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
640 long *valp = ucontrol->value.integer.value;
641 unsigned int val = snd_hda_codec_read(codec, nid, 0,
642 AC_VERB_GET_GPIO_DATA, 0x00);
644 *valp = (val & mask) != 0;
647 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_value *ucontrol)
651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
652 hda_nid_t nid = kcontrol->private_value & 0xffff;
653 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
654 long val = *ucontrol->value.integer.value;
655 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
656 AC_VERB_GET_GPIO_DATA,
659 /* Set/unset the masked GPIO bit(s) as needed */
660 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
665 snd_hda_codec_write_cache(codec, nid, 0,
666 AC_VERB_SET_GPIO_DATA, gpio_data);
670 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
672 .info = alc_gpio_data_info, \
673 .get = alc_gpio_data_get, \
674 .put = alc_gpio_data_put, \
675 .private_value = nid | (mask<<16) }
676 #endif /* CONFIG_SND_DEBUG */
678 /* A switch control to allow the enabling of the digital IO pins on the
679 * ALC260. This is incredibly simplistic; the intention of this control is
680 * to provide something in the test model allowing digital outputs to be
681 * identified if present. If models are found which can utilise these
682 * outputs a more complete mixer control can be devised for those models if
685 #ifdef CONFIG_SND_DEBUG
686 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
688 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol)
691 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
692 hda_nid_t nid = kcontrol->private_value & 0xffff;
693 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
694 long *valp = ucontrol->value.integer.value;
695 unsigned int val = snd_hda_codec_read(codec, nid, 0,
696 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
698 *valp = (val & mask) != 0;
701 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol)
705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706 hda_nid_t nid = kcontrol->private_value & 0xffff;
707 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
708 long val = *ucontrol->value.integer.value;
709 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
710 AC_VERB_GET_DIGI_CONVERT_1,
713 /* Set/unset the masked control bit(s) as needed */
714 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
719 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
724 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
725 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
726 .info = alc_spdif_ctrl_info, \
727 .get = alc_spdif_ctrl_get, \
728 .put = alc_spdif_ctrl_put, \
729 .private_value = nid | (mask<<16) }
730 #endif /* CONFIG_SND_DEBUG */
732 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
733 * Again, this is only used in the ALC26x test models to help identify when
734 * the EAPD line must be asserted for features to work.
736 #ifdef CONFIG_SND_DEBUG
737 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
739 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
740 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 *valp = ucontrol->value.integer.value;
746 unsigned int val = snd_hda_codec_read(codec, nid, 0,
747 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
749 *valp = (val & mask) != 0;
753 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
757 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
758 hda_nid_t nid = kcontrol->private_value & 0xffff;
759 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
760 long val = *ucontrol->value.integer.value;
761 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
762 AC_VERB_GET_EAPD_BTLENABLE,
765 /* Set/unset the masked control bit(s) as needed */
766 change = (!val ? 0 : mask) != (ctrl_data & mask);
771 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
777 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
779 .info = alc_eapd_ctrl_info, \
780 .get = alc_eapd_ctrl_get, \
781 .put = alc_eapd_ctrl_put, \
782 .private_value = nid | (mask<<16) }
783 #endif /* CONFIG_SND_DEBUG */
786 * set up the input pin config (depending on the given auto-pin type)
788 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
791 unsigned int val = PIN_IN;
793 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
795 pincap = snd_hda_query_pin_caps(codec, nid);
796 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
797 if (pincap & AC_PINCAP_VREF_80)
799 else if (pincap & AC_PINCAP_VREF_50)
801 else if (pincap & AC_PINCAP_VREF_100)
803 else if (pincap & AC_PINCAP_VREF_GRD)
806 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
811 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
813 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
815 spec->mixers[spec->num_mixers++] = mix;
818 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
820 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
822 spec->init_verbs[spec->num_init_verbs++] = verb;
825 #ifdef CONFIG_PROC_FS
829 static void print_realtek_coef(struct snd_info_buffer *buffer,
830 struct hda_codec *codec, hda_nid_t nid)
836 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
837 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
838 coeff = snd_hda_codec_read(codec, nid, 0,
839 AC_VERB_GET_COEF_INDEX, 0);
840 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
843 #define print_realtek_coef NULL
847 * set up from the preset table
849 static void setup_preset(struct alc_spec *spec,
850 const struct alc_config_preset *preset)
854 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
855 add_mixer(spec, preset->mixers[i]);
856 spec->cap_mixer = preset->cap_mixer;
857 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
859 add_verb(spec, preset->init_verbs[i]);
861 spec->channel_mode = preset->channel_mode;
862 spec->num_channel_mode = preset->num_channel_mode;
863 spec->need_dac_fix = preset->need_dac_fix;
864 spec->const_channel_count = preset->const_channel_count;
866 if (preset->const_channel_count)
867 spec->multiout.max_channels = preset->const_channel_count;
869 spec->multiout.max_channels = spec->channel_mode[0].channels;
870 spec->ext_channel_count = spec->channel_mode[0].channels;
872 spec->multiout.num_dacs = preset->num_dacs;
873 spec->multiout.dac_nids = preset->dac_nids;
874 spec->multiout.dig_out_nid = preset->dig_out_nid;
875 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
876 spec->multiout.hp_nid = preset->hp_nid;
878 spec->num_mux_defs = preset->num_mux_defs;
879 if (!spec->num_mux_defs)
880 spec->num_mux_defs = 1;
881 spec->input_mux = preset->input_mux;
883 spec->num_adc_nids = preset->num_adc_nids;
884 spec->adc_nids = preset->adc_nids;
885 spec->capsrc_nids = preset->capsrc_nids;
886 spec->dig_in_nid = preset->dig_in_nid;
888 spec->unsol_event = preset->unsol_event;
889 spec->init_hook = preset->init_hook;
890 #ifdef CONFIG_SND_HDA_POWER_SAVE
891 spec->loopback.amplist = preset->loopbacks;
895 /* Enable GPIO mask and set output */
896 static struct hda_verb alc_gpio1_init_verbs[] = {
897 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
898 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
899 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
903 static struct hda_verb alc_gpio2_init_verbs[] = {
904 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
905 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
906 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
910 static struct hda_verb alc_gpio3_init_verbs[] = {
911 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
912 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
913 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
918 * Fix hardware PLL issue
919 * On some codecs, the analog PLL gating control must be off while
920 * the default value is 1.
922 static void alc_fix_pll(struct hda_codec *codec)
924 struct alc_spec *spec = codec->spec;
929 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
931 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
932 AC_VERB_GET_PROC_COEF, 0);
933 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
935 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
936 val & ~(1 << spec->pll_coef_bit));
939 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
940 unsigned int coef_idx, unsigned int coef_bit)
942 struct alc_spec *spec = codec->spec;
944 spec->pll_coef_idx = coef_idx;
945 spec->pll_coef_bit = coef_bit;
949 static void alc_automute_pin(struct hda_codec *codec)
951 struct alc_spec *spec = codec->spec;
952 unsigned int present;
953 unsigned int nid = spec->autocfg.hp_pins[0];
956 /* need to execute and sync at first */
957 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
958 present = snd_hda_codec_read(codec, nid, 0,
959 AC_VERB_GET_PIN_SENSE, 0);
960 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
961 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
962 nid = spec->autocfg.speaker_pins[i];
965 snd_hda_codec_write(codec, nid, 0,
966 AC_VERB_SET_PIN_WIDGET_CONTROL,
967 spec->jack_present ? 0 : PIN_OUT);
971 #if 0 /* it's broken in some acses -- temporarily disabled */
972 static void alc_mic_automute(struct hda_codec *codec)
974 struct alc_spec *spec = codec->spec;
975 unsigned int present;
976 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
977 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
978 unsigned int mix_nid = spec->capsrc_nids[0];
979 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
981 capsrc_idx_mic = mic_nid - 0x18;
982 capsrc_idx_fmic = fmic_nid - 0x18;
983 present = snd_hda_codec_read(codec, mic_nid, 0,
984 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
985 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
986 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
987 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
988 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
989 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
990 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
993 #define alc_mic_automute(codec) do {} while(0) /* NOP */
994 #endif /* disabled */
996 /* unsolicited event for HP jack sensing */
997 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
999 if (codec->vendor_id == 0x10ec0880)
1004 case ALC880_HP_EVENT:
1005 alc_automute_pin(codec);
1007 case ALC880_MIC_EVENT:
1008 alc_mic_automute(codec);
1013 static void alc_inithook(struct hda_codec *codec)
1015 alc_automute_pin(codec);
1016 alc_mic_automute(codec);
1019 /* additional initialization for ALC888 variants */
1020 static void alc888_coef_init(struct hda_codec *codec)
1024 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1025 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1026 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1027 if ((tmp & 0xf0) == 0x20)
1029 snd_hda_codec_read(codec, 0x20, 0,
1030 AC_VERB_SET_PROC_COEF, 0x830);
1033 snd_hda_codec_read(codec, 0x20, 0,
1034 AC_VERB_SET_PROC_COEF, 0x3030);
1037 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1042 case ALC_INIT_GPIO1:
1043 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1045 case ALC_INIT_GPIO2:
1046 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1048 case ALC_INIT_GPIO3:
1049 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1051 case ALC_INIT_DEFAULT:
1052 switch (codec->vendor_id) {
1054 snd_hda_codec_write(codec, 0x0f, 0,
1055 AC_VERB_SET_EAPD_BTLENABLE, 2);
1056 snd_hda_codec_write(codec, 0x10, 0,
1057 AC_VERB_SET_EAPD_BTLENABLE, 2);
1069 snd_hda_codec_write(codec, 0x14, 0,
1070 AC_VERB_SET_EAPD_BTLENABLE, 2);
1071 snd_hda_codec_write(codec, 0x15, 0,
1072 AC_VERB_SET_EAPD_BTLENABLE, 2);
1075 switch (codec->vendor_id) {
1077 snd_hda_codec_write(codec, 0x1a, 0,
1078 AC_VERB_SET_COEF_INDEX, 7);
1079 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1080 AC_VERB_GET_PROC_COEF, 0);
1081 snd_hda_codec_write(codec, 0x1a, 0,
1082 AC_VERB_SET_COEF_INDEX, 7);
1083 snd_hda_codec_write(codec, 0x1a, 0,
1084 AC_VERB_SET_PROC_COEF,
1094 snd_hda_codec_write(codec, 0x20, 0,
1095 AC_VERB_SET_COEF_INDEX, 7);
1096 tmp = snd_hda_codec_read(codec, 0x20, 0,
1097 AC_VERB_GET_PROC_COEF, 0);
1098 snd_hda_codec_write(codec, 0x20, 0,
1099 AC_VERB_SET_COEF_INDEX, 7);
1100 snd_hda_codec_write(codec, 0x20, 0,
1101 AC_VERB_SET_PROC_COEF,
1105 alc888_coef_init(codec);
1109 snd_hda_codec_write(codec, 0x20, 0,
1110 AC_VERB_SET_COEF_INDEX, 7);
1111 tmp = snd_hda_codec_read(codec, 0x20, 0,
1112 AC_VERB_GET_PROC_COEF, 0);
1113 snd_hda_codec_write(codec, 0x20, 0,
1114 AC_VERB_SET_COEF_INDEX, 7);
1115 snd_hda_codec_write(codec, 0x20, 0,
1116 AC_VERB_SET_PROC_COEF,
1124 static void alc_init_auto_hp(struct hda_codec *codec)
1126 struct alc_spec *spec = codec->spec;
1128 if (!spec->autocfg.hp_pins[0])
1131 if (!spec->autocfg.speaker_pins[0]) {
1132 if (spec->autocfg.line_out_pins[0] &&
1133 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1134 spec->autocfg.speaker_pins[0] =
1135 spec->autocfg.line_out_pins[0];
1140 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1141 spec->autocfg.hp_pins[0]);
1142 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1143 AC_VERB_SET_UNSOLICITED_ENABLE,
1144 AC_USRSP_EN | ALC880_HP_EVENT);
1145 spec->unsol_event = alc_sku_unsol_event;
1148 /* check subsystem ID and set up device-specific initialization;
1149 * return 1 if initialized, 0 if invalid SSID
1151 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1152 * 31 ~ 16 : Manufacture ID
1154 * 7 ~ 0 : Assembly ID
1155 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1157 static int alc_subsystem_id(struct hda_codec *codec,
1158 hda_nid_t porta, hda_nid_t porte,
1161 unsigned int ass, tmp, i;
1163 struct alc_spec *spec = codec->spec;
1165 ass = codec->subsystem_id & 0xffff;
1166 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1169 /* invalid SSID, check the special NID pin defcfg instead */
1171 * 31~30 : port conetcivity
1174 * 19~16 : Check sum (15:1)
1179 if (codec->vendor_id == 0x10ec0260)
1181 ass = snd_hda_codec_get_pincfg(codec, nid);
1182 snd_printd("realtek: No valid SSID, "
1183 "checking pincfg 0x%08x for NID 0x%x\n",
1185 if (!(ass & 1) && !(ass & 0x100000))
1187 if ((ass >> 30) != 1) /* no physical connection */
1192 for (i = 1; i < 16; i++) {
1196 if (((ass >> 16) & 0xf) != tmp)
1199 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1200 ass & 0xffff, codec->vendor_id);
1204 * 2 : 0 --> Desktop, 1 --> Laptop
1205 * 3~5 : External Amplifier control
1208 tmp = (ass & 0x38) >> 3; /* external Amp control */
1211 spec->init_amp = ALC_INIT_GPIO1;
1214 spec->init_amp = ALC_INIT_GPIO2;
1217 spec->init_amp = ALC_INIT_GPIO3;
1220 spec->init_amp = ALC_INIT_DEFAULT;
1224 /* is laptop or Desktop and enable the function "Mute internal speaker
1225 * when the external headphone out jack is plugged"
1227 if (!(ass & 0x8000))
1230 * 10~8 : Jack location
1231 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1233 * 15 : 1 --> enable the function "Mute internal speaker
1234 * when the external headphone out jack is plugged"
1236 if (!spec->autocfg.hp_pins[0]) {
1237 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1239 spec->autocfg.hp_pins[0] = porta;
1241 spec->autocfg.hp_pins[0] = porte;
1243 spec->autocfg.hp_pins[0] = portd;
1248 alc_init_auto_hp(codec);
1252 static void alc_ssid_check(struct hda_codec *codec,
1253 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1255 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1256 struct alc_spec *spec = codec->spec;
1257 snd_printd("realtek: "
1258 "Enable default setup for auto mode as fallback\n");
1259 spec->init_amp = ALC_INIT_DEFAULT;
1260 alc_init_auto_hp(codec);
1265 * Fix-up pin default configurations
1273 static void alc_fix_pincfg(struct hda_codec *codec,
1274 const struct snd_pci_quirk *quirk,
1275 const struct alc_pincfg **pinfix)
1277 const struct alc_pincfg *cfg;
1279 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1283 cfg = pinfix[quirk->value];
1284 for (; cfg->nid; cfg++)
1285 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1295 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1296 /* Mic-in jack as mic in */
1297 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1298 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1299 /* Line-in jack as Line in */
1300 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1301 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1302 /* Line-Out as Front */
1303 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1310 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1311 /* Mic-in jack as mic in */
1312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1314 /* Line-in jack as Surround */
1315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1317 /* Line-Out as Front */
1318 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1325 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1326 /* Mic-in jack as CLFE */
1327 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1328 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1329 /* Line-in jack as Surround */
1330 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1331 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1332 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1333 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1340 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1341 /* Mic-in jack as CLFE */
1342 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1343 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1344 /* Line-in jack as Surround */
1345 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1346 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1347 /* Line-Out as Side */
1348 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1352 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1353 { 2, alc888_4ST_ch2_intel_init },
1354 { 4, alc888_4ST_ch4_intel_init },
1355 { 6, alc888_4ST_ch6_intel_init },
1356 { 8, alc888_4ST_ch8_intel_init },
1360 * ALC888 Fujitsu Siemens Amillo xa3530
1363 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1364 /* Front Mic: set to PIN_IN (empty by default) */
1365 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1366 /* Connect Internal HP to Front */
1367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1370 /* Connect Bass HP to Front */
1371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1374 /* Connect Line-Out side jack (SPDIF) to Side */
1375 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1377 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1378 /* Connect Mic jack to CLFE */
1379 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1382 /* Connect Line-in jack to Surround */
1383 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1384 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1385 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1386 /* Connect HP out jack to Front */
1387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1389 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1390 /* Enable unsolicited event for HP jack and Line-out jack */
1391 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1392 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1396 static void alc_automute_amp(struct hda_codec *codec)
1398 struct alc_spec *spec = codec->spec;
1399 unsigned int val, mute;
1403 spec->jack_present = 0;
1404 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1405 nid = spec->autocfg.hp_pins[i];
1408 val = snd_hda_codec_read(codec, nid, 0,
1409 AC_VERB_GET_PIN_SENSE, 0);
1410 if (val & AC_PINSENSE_PRESENCE) {
1411 spec->jack_present = 1;
1416 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1417 /* Toggle internal speakers muting */
1418 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1419 nid = spec->autocfg.speaker_pins[i];
1422 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1423 HDA_AMP_MUTE, mute);
1427 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1430 if (codec->vendor_id == 0x10ec0880)
1434 if (res == ALC880_HP_EVENT)
1435 alc_automute_amp(codec);
1438 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1440 struct alc_spec *spec = codec->spec;
1442 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1443 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1444 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1445 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1446 alc_automute_amp(codec);
1450 * ALC888 Acer Aspire 4930G model
1453 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1454 /* Front Mic: set to PIN_IN (empty by default) */
1455 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1456 /* Unselect Front Mic by default in input mixer 3 */
1457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1458 /* Enable unsolicited event for HP jack */
1459 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1460 /* Connect Internal HP to front */
1461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1462 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1464 /* Connect HP out to front */
1465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1472 * ALC888 Acer Aspire 8930G model
1475 static struct hda_verb alc888_acer_aspire_8930g_verbs[] = {
1476 /* Front Mic: set to PIN_IN (empty by default) */
1477 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1478 /* Unselect Front Mic by default in input mixer 3 */
1479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1480 /* Enable unsolicited event for HP jack */
1481 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1482 /* Connect Internal Front to Front */
1483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1486 /* Connect Internal Rear to Rear */
1487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1488 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1489 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1490 /* Connect Internal CLFE to CLFE */
1491 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1494 /* Connect HP out to Front */
1495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1498 /* Enable all DACs */
1499 /* DAC DISABLE/MUTE 1? */
1500 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1501 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1502 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1503 /* DAC DISABLE/MUTE 2? */
1504 /* some bit here disables the other DACs. Init=0x4900 */
1505 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1506 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1507 /* Enable amplifiers */
1508 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1509 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1513 static struct hda_input_mux alc888_2_capture_sources[2] = {
1514 /* Front mic only available on one ADC */
1521 { "Front Mic", 0xb },
1534 static struct snd_kcontrol_new alc888_base_mixer[] = {
1535 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1536 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1537 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1538 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1539 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1541 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1542 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1543 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1544 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1545 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1548 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1549 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1550 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1551 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1556 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1558 struct alc_spec *spec = codec->spec;
1560 spec->autocfg.hp_pins[0] = 0x15;
1561 spec->autocfg.speaker_pins[0] = 0x14;
1562 alc_automute_amp(codec);
1565 static void alc888_acer_aspire_8930g_init_hook(struct hda_codec *codec)
1567 struct alc_spec *spec = codec->spec;
1569 spec->autocfg.hp_pins[0] = 0x15;
1570 spec->autocfg.speaker_pins[0] = 0x14;
1571 spec->autocfg.speaker_pins[1] = 0x16;
1572 spec->autocfg.speaker_pins[2] = 0x1b;
1573 alc_automute_amp(codec);
1577 * ALC880 3-stack model
1579 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1580 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1581 * F-Mic = 0x1b, HP = 0x19
1584 static hda_nid_t alc880_dac_nids[4] = {
1585 /* front, rear, clfe, rear_surr */
1586 0x02, 0x05, 0x04, 0x03
1589 static hda_nid_t alc880_adc_nids[3] = {
1594 /* The datasheet says the node 0x07 is connected from inputs,
1595 * but it shows zero connection in the real implementation on some devices.
1596 * Note: this is a 915GAV bug, fixed on 915GLV
1598 static hda_nid_t alc880_adc_nids_alt[2] = {
1603 #define ALC880_DIGOUT_NID 0x06
1604 #define ALC880_DIGIN_NID 0x0a
1606 static struct hda_input_mux alc880_capture_source = {
1610 { "Front Mic", 0x3 },
1616 /* channel source setting (2/6 channel selection for 3-stack) */
1618 static struct hda_verb alc880_threestack_ch2_init[] = {
1619 /* set line-in to input, mute it */
1620 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1621 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1622 /* set mic-in to input vref 80%, mute it */
1623 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1624 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1629 static struct hda_verb alc880_threestack_ch6_init[] = {
1630 /* set line-in to output, unmute it */
1631 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1632 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1633 /* set mic-in to output, unmute it */
1634 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1635 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1639 static struct hda_channel_mode alc880_threestack_modes[2] = {
1640 { 2, alc880_threestack_ch2_init },
1641 { 6, alc880_threestack_ch6_init },
1644 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1645 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1646 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1647 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1648 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1649 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1650 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1651 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1652 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1653 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1654 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1656 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1659 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1660 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1661 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1664 .name = "Channel Mode",
1665 .info = alc_ch_mode_info,
1666 .get = alc_ch_mode_get,
1667 .put = alc_ch_mode_put,
1672 /* capture mixer elements */
1673 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1674 struct snd_ctl_elem_info *uinfo)
1676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1677 struct alc_spec *spec = codec->spec;
1680 mutex_lock(&codec->control_mutex);
1681 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1683 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1684 mutex_unlock(&codec->control_mutex);
1688 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1689 unsigned int size, unsigned int __user *tlv)
1691 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1692 struct alc_spec *spec = codec->spec;
1695 mutex_lock(&codec->control_mutex);
1696 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1698 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1699 mutex_unlock(&codec->control_mutex);
1703 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1704 struct snd_ctl_elem_value *ucontrol);
1706 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol,
1710 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1711 struct alc_spec *spec = codec->spec;
1712 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1715 mutex_lock(&codec->control_mutex);
1716 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1718 err = func(kcontrol, ucontrol);
1719 mutex_unlock(&codec->control_mutex);
1723 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1724 struct snd_ctl_elem_value *ucontrol)
1726 return alc_cap_getput_caller(kcontrol, ucontrol,
1727 snd_hda_mixer_amp_volume_get);
1730 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1731 struct snd_ctl_elem_value *ucontrol)
1733 return alc_cap_getput_caller(kcontrol, ucontrol,
1734 snd_hda_mixer_amp_volume_put);
1737 /* capture mixer elements */
1738 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1740 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1741 struct snd_ctl_elem_value *ucontrol)
1743 return alc_cap_getput_caller(kcontrol, ucontrol,
1744 snd_hda_mixer_amp_switch_get);
1747 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1748 struct snd_ctl_elem_value *ucontrol)
1750 return alc_cap_getput_caller(kcontrol, ucontrol,
1751 snd_hda_mixer_amp_switch_put);
1754 #define _DEFINE_CAPMIX(num) \
1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1757 .name = "Capture Switch", \
1758 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1760 .info = alc_cap_sw_info, \
1761 .get = alc_cap_sw_get, \
1762 .put = alc_cap_sw_put, \
1765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1766 .name = "Capture Volume", \
1767 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1768 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1769 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1771 .info = alc_cap_vol_info, \
1772 .get = alc_cap_vol_get, \
1773 .put = alc_cap_vol_put, \
1774 .tlv = { .c = alc_cap_vol_tlv }, \
1777 #define _DEFINE_CAPSRC(num) \
1779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1780 /* .name = "Capture Source", */ \
1781 .name = "Input Source", \
1783 .info = alc_mux_enum_info, \
1784 .get = alc_mux_enum_get, \
1785 .put = alc_mux_enum_put, \
1788 #define DEFINE_CAPMIX(num) \
1789 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1790 _DEFINE_CAPMIX(num), \
1791 _DEFINE_CAPSRC(num), \
1795 #define DEFINE_CAPMIX_NOSRC(num) \
1796 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1797 _DEFINE_CAPMIX(num), \
1801 /* up to three ADCs */
1805 DEFINE_CAPMIX_NOSRC(1);
1806 DEFINE_CAPMIX_NOSRC(2);
1807 DEFINE_CAPMIX_NOSRC(3);
1810 * ALC880 5-stack model
1812 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1814 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1815 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1818 /* additional mixers to alc880_three_stack_mixer */
1819 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1820 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1821 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1825 /* channel source setting (6/8 channel selection for 5-stack) */
1827 static struct hda_verb alc880_fivestack_ch6_init[] = {
1828 /* set line-in to input, mute it */
1829 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1830 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1835 static struct hda_verb alc880_fivestack_ch8_init[] = {
1836 /* set line-in to output, unmute it */
1837 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1838 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1842 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1843 { 6, alc880_fivestack_ch6_init },
1844 { 8, alc880_fivestack_ch8_init },
1849 * ALC880 6-stack model
1851 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1852 * Side = 0x05 (0x0f)
1853 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1854 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1857 static hda_nid_t alc880_6st_dac_nids[4] = {
1858 /* front, rear, clfe, rear_surr */
1859 0x02, 0x03, 0x04, 0x05
1862 static struct hda_input_mux alc880_6stack_capture_source = {
1866 { "Front Mic", 0x1 },
1872 /* fixed 8-channels */
1873 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1877 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1878 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1879 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1880 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1881 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1882 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1883 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1884 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1885 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1886 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1887 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1888 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1889 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1890 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1891 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1893 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1894 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1895 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1897 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1898 .name = "Channel Mode",
1899 .info = alc_ch_mode_info,
1900 .get = alc_ch_mode_get,
1901 .put = alc_ch_mode_put,
1910 * W810 has rear IO for:
1913 * Center/LFE (DAC 04)
1916 * The system also has a pair of internal speakers, and a headphone jack.
1917 * These are both connected to Line2 on the codec, hence to DAC 02.
1919 * There is a variable resistor to control the speaker or headphone
1920 * volume. This is a hardware-only device without a software API.
1922 * Plugging headphones in will disable the internal speakers. This is
1923 * implemented in hardware, not via the driver using jack sense. In
1924 * a similar fashion, plugging into the rear socket marked "front" will
1925 * disable both the speakers and headphones.
1927 * For input, there's a microphone jack, and an "audio in" jack.
1928 * These may not do anything useful with this driver yet, because I
1929 * haven't setup any initialization verbs for these yet...
1932 static hda_nid_t alc880_w810_dac_nids[3] = {
1933 /* front, rear/surround, clfe */
1937 /* fixed 6 channels */
1938 static struct hda_channel_mode alc880_w810_modes[1] = {
1942 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1943 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1944 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1945 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1946 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1947 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1948 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1949 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1950 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1951 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1960 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1961 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1965 static hda_nid_t alc880_z71v_dac_nids[1] = {
1968 #define ALC880_Z71V_HP_DAC 0x03
1970 /* fixed 2 channels */
1971 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1975 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1976 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1977 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1978 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1979 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1980 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1981 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1989 * ALC880 F1734 model
1991 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1992 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1995 static hda_nid_t alc880_f1734_dac_nids[1] = {
1998 #define ALC880_F1734_HP_DAC 0x02
2000 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2001 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2002 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2003 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2004 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2012 static struct hda_input_mux alc880_f1734_capture_source = {
2024 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2025 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2026 * Mic = 0x18, Line = 0x1a
2029 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2030 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2032 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2033 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2034 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2035 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2036 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2037 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2038 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2039 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2040 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2049 .name = "Channel Mode",
2050 .info = alc_ch_mode_info,
2051 .get = alc_ch_mode_get,
2052 .put = alc_ch_mode_put,
2058 * ALC880 ASUS W1V model
2060 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2061 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2062 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2065 /* additional mixers to alc880_asus_mixer */
2066 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2067 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2068 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2073 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2075 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2076 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2077 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2078 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2080 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2081 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2082 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2087 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2088 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2089 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2091 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2092 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2102 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2103 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2106 .name = "Channel Mode",
2107 .info = alc_ch_mode_info,
2108 .get = alc_ch_mode_get,
2109 .put = alc_ch_mode_put,
2114 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2115 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2116 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2117 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2118 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2119 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2120 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2121 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2122 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2123 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2124 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2128 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2129 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2130 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2132 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2134 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2139 * virtual master controls
2143 * slave controls for virtual master
2145 static const char *alc_slave_vols[] = {
2146 "Front Playback Volume",
2147 "Surround Playback Volume",
2148 "Center Playback Volume",
2149 "LFE Playback Volume",
2150 "Side Playback Volume",
2151 "Headphone Playback Volume",
2152 "Speaker Playback Volume",
2153 "Mono Playback Volume",
2154 "Line-Out Playback Volume",
2155 "PCM Playback Volume",
2159 static const char *alc_slave_sws[] = {
2160 "Front Playback Switch",
2161 "Surround Playback Switch",
2162 "Center Playback Switch",
2163 "LFE Playback Switch",
2164 "Side Playback Switch",
2165 "Headphone Playback Switch",
2166 "Speaker Playback Switch",
2167 "Mono Playback Switch",
2168 "IEC958 Playback Switch",
2173 * build control elements
2176 static void alc_free_kctls(struct hda_codec *codec);
2178 /* additional beep mixers; the actual parameters are overwritten at build */
2179 static struct snd_kcontrol_new alc_beep_mixer[] = {
2180 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2181 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2185 static int alc_build_controls(struct hda_codec *codec)
2187 struct alc_spec *spec = codec->spec;
2191 for (i = 0; i < spec->num_mixers; i++) {
2192 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2196 if (spec->cap_mixer) {
2197 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2201 if (spec->multiout.dig_out_nid) {
2202 err = snd_hda_create_spdif_out_ctls(codec,
2203 spec->multiout.dig_out_nid);
2206 if (!spec->no_analog) {
2207 err = snd_hda_create_spdif_share_sw(codec,
2211 spec->multiout.share_spdif = 1;
2214 if (spec->dig_in_nid) {
2215 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2220 /* create beep controls if needed */
2221 if (spec->beep_amp) {
2222 struct snd_kcontrol_new *knew;
2223 for (knew = alc_beep_mixer; knew->name; knew++) {
2224 struct snd_kcontrol *kctl;
2225 kctl = snd_ctl_new1(knew, codec);
2228 kctl->private_value = spec->beep_amp;
2229 err = snd_hda_ctl_add(codec, kctl);
2235 /* if we have no master control, let's create it */
2236 if (!spec->no_analog &&
2237 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2238 unsigned int vmaster_tlv[4];
2239 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2240 HDA_OUTPUT, vmaster_tlv);
2241 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2242 vmaster_tlv, alc_slave_vols);
2246 if (!spec->no_analog &&
2247 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2248 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2249 NULL, alc_slave_sws);
2254 alc_free_kctls(codec); /* no longer needed */
2260 * initialize the codec volumes, etc
2264 * generic initialization of ADC, input mixers and output mixers
2266 static struct hda_verb alc880_volume_init_verbs[] = {
2268 * Unmute ADC0-2 and set the default input to mic-in
2270 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2272 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2273 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2274 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2275 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2277 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2279 * Note: PASD motherboards uses the Line In 2 as the input for front
2282 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2292 * Set up output mixers (0x0c - 0x0f)
2294 /* set vol=0 to output mixers */
2295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2297 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2298 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2299 /* set up input amps for analog loopback */
2300 /* Amp Indices: DAC = 0, mixer = 1 */
2301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2302 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2303 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2304 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2305 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2307 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2314 * 3-stack pin configuration:
2315 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2317 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2319 * preset connection lists of input pins
2320 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2322 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2323 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2324 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2327 * Set pin mode and muting
2329 /* set front pin widgets 0x14 for output */
2330 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2331 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2333 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2335 /* Mic2 (as headphone out) for HP output */
2336 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2337 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2338 /* Line In pin widget for input */
2339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2340 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2341 /* Line2 (as front mic) pin widget for input and vref at 80% */
2342 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2343 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2344 /* CD pin widget for input */
2345 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2351 * 5-stack pin configuration:
2352 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2353 * line-in/side = 0x1a, f-mic = 0x1b
2355 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2357 * preset connection lists of input pins
2358 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2360 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2361 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2364 * Set pin mode and muting
2366 /* set pin widgets 0x14-0x17 for output */
2367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2369 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2370 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2371 /* unmute pins for output (no gain on this amp) */
2372 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2374 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2378 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2379 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2380 /* Mic2 (as headphone out) for HP output */
2381 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2382 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2383 /* Line In pin widget for input */
2384 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2386 /* Line2 (as front mic) pin widget for input and vref at 80% */
2387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2389 /* CD pin widget for input */
2390 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2396 * W810 pin configuration:
2397 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2399 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2400 /* hphone/speaker input selector: front DAC */
2401 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2403 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2404 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2406 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2407 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2408 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2410 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2411 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2417 * Z71V pin configuration:
2418 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2420 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2422 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2427 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2428 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2429 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2435 * 6-stack pin configuration:
2436 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2437 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2439 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2440 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2442 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2443 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2446 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2447 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2448 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2449 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2455 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2456 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2458 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2459 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2465 * Uniwill pin configuration:
2466 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2469 static struct hda_verb alc880_uniwill_init_verbs[] = {
2470 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2475 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2477 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2478 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2479 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2487 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2488 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2489 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2490 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2492 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2493 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2494 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2495 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2497 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2498 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2505 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2507 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2508 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2510 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2511 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2515 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2521 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2523 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2524 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2526 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2527 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2531 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2536 static struct hda_verb alc880_beep_init_verbs[] = {
2537 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2541 /* auto-toggle front mic */
2542 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2544 unsigned int present;
2547 present = snd_hda_codec_read(codec, 0x18, 0,
2548 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2549 bits = present ? HDA_AMP_MUTE : 0;
2550 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2553 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2555 struct alc_spec *spec = codec->spec;
2557 spec->autocfg.hp_pins[0] = 0x14;
2558 spec->autocfg.speaker_pins[0] = 0x15;
2559 spec->autocfg.speaker_pins[0] = 0x16;
2560 alc_automute_amp(codec);
2561 alc880_uniwill_mic_automute(codec);
2564 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2567 /* Looks like the unsol event is incompatible with the standard
2568 * definition. 4bit tag is placed at 28 bit!
2570 switch (res >> 28) {
2571 case ALC880_MIC_EVENT:
2572 alc880_uniwill_mic_automute(codec);
2575 alc_automute_amp_unsol_event(codec, res);
2580 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2582 struct alc_spec *spec = codec->spec;
2584 spec->autocfg.hp_pins[0] = 0x14;
2585 spec->autocfg.speaker_pins[0] = 0x15;
2586 alc_automute_amp(codec);
2589 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2591 unsigned int present;
2593 present = snd_hda_codec_read(codec, 0x21, 0,
2594 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2595 present &= HDA_AMP_VOLMASK;
2596 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2597 HDA_AMP_VOLMASK, present);
2598 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2599 HDA_AMP_VOLMASK, present);
2602 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2605 /* Looks like the unsol event is incompatible with the standard
2606 * definition. 4bit tag is placed at 28 bit!
2608 if ((res >> 28) == ALC880_DCVOL_EVENT)
2609 alc880_uniwill_p53_dcvol_automute(codec);
2611 alc_automute_amp_unsol_event(codec, res);
2615 * F1734 pin configuration:
2616 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2618 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2619 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2620 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2621 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2622 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2623 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2628 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2632 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2633 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2634 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2636 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2637 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2638 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2640 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2641 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2647 * ASUS pin configuration:
2648 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2650 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2651 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2652 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2653 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2654 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2657 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2659 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2660 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2662 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2665 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2666 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2669 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2670 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2672 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2673 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2678 /* Enable GPIO mask and set output */
2679 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2680 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2682 /* Clevo m520g init */
2683 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2684 /* headphone output */
2685 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2687 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2688 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2690 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2693 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2694 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2695 /* Mic1 (rear panel) */
2696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2698 /* Mic2 (front panel) */
2699 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2700 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2702 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2703 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2704 /* change to EAPD mode */
2705 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2706 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2711 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2712 /* change to EAPD mode */
2713 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2714 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2716 /* Headphone output */
2717 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2719 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2720 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2722 /* Line In pin widget for input */
2723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2724 /* CD pin widget for input */
2725 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2726 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2729 /* change to EAPD mode */
2730 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2731 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2737 * LG m1 express dual
2740 * Rear Line-In/Out (blue): 0x14
2741 * Build-in Mic-In: 0x15
2743 * HP-Out (green): 0x1b
2744 * Mic-In/Out (red): 0x19
2748 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2749 static hda_nid_t alc880_lg_dac_nids[3] = {
2753 /* seems analog CD is not working */
2754 static struct hda_input_mux alc880_lg_capture_source = {
2759 { "Internal Mic", 0x6 },
2763 /* 2,4,6 channel modes */
2764 static struct hda_verb alc880_lg_ch2_init[] = {
2765 /* set line-in and mic-in to input */
2766 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2767 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2771 static struct hda_verb alc880_lg_ch4_init[] = {
2772 /* set line-in to out and mic-in to input */
2773 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2774 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2778 static struct hda_verb alc880_lg_ch6_init[] = {
2779 /* set line-in and mic-in to output */
2780 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2781 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2785 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2786 { 2, alc880_lg_ch2_init },
2787 { 4, alc880_lg_ch4_init },
2788 { 6, alc880_lg_ch6_init },
2791 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2792 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2793 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2794 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2795 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2796 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2797 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2798 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2799 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2801 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2802 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2803 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2804 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2805 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2808 .name = "Channel Mode",
2809 .info = alc_ch_mode_info,
2810 .get = alc_ch_mode_get,
2811 .put = alc_ch_mode_put,
2816 static struct hda_verb alc880_lg_init_verbs[] = {
2817 /* set capture source to mic-in */
2818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2819 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2820 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2821 /* mute all amp mixer inputs */
2822 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2823 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2824 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2825 /* line-in to input */
2826 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2827 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2832 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2834 /* mic-in to input */
2835 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2836 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2839 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2840 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2841 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2843 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2847 /* toggle speaker-output according to the hp-jack state */
2848 static void alc880_lg_init_hook(struct hda_codec *codec)
2850 struct alc_spec *spec = codec->spec;
2852 spec->autocfg.hp_pins[0] = 0x1b;
2853 spec->autocfg.speaker_pins[0] = 0x17;
2854 alc_automute_amp(codec);
2863 * Built-in Mic-In: 0x19
2869 static struct hda_input_mux alc880_lg_lw_capture_source = {
2873 { "Internal Mic", 0x1 },
2878 #define alc880_lg_lw_modes alc880_threestack_modes
2880 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2883 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2884 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2885 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2886 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2887 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2888 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2889 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2890 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2892 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2893 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2894 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2897 .name = "Channel Mode",
2898 .info = alc_ch_mode_info,
2899 .get = alc_ch_mode_get,
2900 .put = alc_ch_mode_put,
2905 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2906 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2907 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2908 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2910 /* set capture source to mic-in */
2911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2913 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2914 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2917 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2920 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2921 /* mic-in to input */
2922 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2928 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2932 /* toggle speaker-output according to the hp-jack state */
2933 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2935 struct alc_spec *spec = codec->spec;
2937 spec->autocfg.hp_pins[0] = 0x1b;
2938 spec->autocfg.speaker_pins[0] = 0x14;
2939 alc_automute_amp(codec);
2942 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2943 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2944 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2946 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2947 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2948 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2952 static struct hda_input_mux alc880_medion_rim_capture_source = {
2956 { "Internal Mic", 0x1 },
2960 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2961 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2966 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2967 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2968 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2969 /* Mic2 (as headphone out) for HP output */
2970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2971 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2972 /* Internal Speaker */
2973 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2974 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2976 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2977 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2979 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2983 /* toggle speaker-output according to the hp-jack state */
2984 static void alc880_medion_rim_automute(struct hda_codec *codec)
2986 struct alc_spec *spec = codec->spec;
2987 alc_automute_amp(codec);
2989 if (spec->jack_present)
2990 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2992 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2995 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2998 /* Looks like the unsol event is incompatible with the standard
2999 * definition. 4bit tag is placed at 28 bit!
3001 if ((res >> 28) == ALC880_HP_EVENT)
3002 alc880_medion_rim_automute(codec);
3005 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3007 struct alc_spec *spec = codec->spec;
3009 spec->autocfg.hp_pins[0] = 0x14;
3010 spec->autocfg.speaker_pins[0] = 0x1b;
3011 alc880_medion_rim_automute(codec);
3014 #ifdef CONFIG_SND_HDA_POWER_SAVE
3015 static struct hda_amp_list alc880_loopbacks[] = {
3016 { 0x0b, HDA_INPUT, 0 },
3017 { 0x0b, HDA_INPUT, 1 },
3018 { 0x0b, HDA_INPUT, 2 },
3019 { 0x0b, HDA_INPUT, 3 },
3020 { 0x0b, HDA_INPUT, 4 },
3024 static struct hda_amp_list alc880_lg_loopbacks[] = {
3025 { 0x0b, HDA_INPUT, 1 },
3026 { 0x0b, HDA_INPUT, 6 },
3027 { 0x0b, HDA_INPUT, 7 },
3036 static int alc_init(struct hda_codec *codec)
3038 struct alc_spec *spec = codec->spec;
3042 alc_auto_init_amp(codec, spec->init_amp);
3044 for (i = 0; i < spec->num_init_verbs; i++)
3045 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3047 if (spec->init_hook)
3048 spec->init_hook(codec);
3053 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3055 struct alc_spec *spec = codec->spec;
3057 if (spec->unsol_event)
3058 spec->unsol_event(codec, res);
3061 #ifdef CONFIG_SND_HDA_POWER_SAVE
3062 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3064 struct alc_spec *spec = codec->spec;
3065 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3070 * Analog playback callbacks
3072 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3073 struct hda_codec *codec,
3074 struct snd_pcm_substream *substream)
3076 struct alc_spec *spec = codec->spec;
3077 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3081 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3082 struct hda_codec *codec,
3083 unsigned int stream_tag,
3084 unsigned int format,
3085 struct snd_pcm_substream *substream)
3087 struct alc_spec *spec = codec->spec;
3088 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3089 stream_tag, format, substream);
3092 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3093 struct hda_codec *codec,
3094 struct snd_pcm_substream *substream)
3096 struct alc_spec *spec = codec->spec;
3097 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3103 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3104 struct hda_codec *codec,
3105 struct snd_pcm_substream *substream)
3107 struct alc_spec *spec = codec->spec;
3108 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3111 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3112 struct hda_codec *codec,
3113 unsigned int stream_tag,
3114 unsigned int format,
3115 struct snd_pcm_substream *substream)
3117 struct alc_spec *spec = codec->spec;
3118 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3119 stream_tag, format, substream);
3122 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3123 struct hda_codec *codec,
3124 struct snd_pcm_substream *substream)
3126 struct alc_spec *spec = codec->spec;
3127 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3130 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3131 struct hda_codec *codec,
3132 struct snd_pcm_substream *substream)
3134 struct alc_spec *spec = codec->spec;
3135 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3141 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3142 struct hda_codec *codec,
3143 unsigned int stream_tag,
3144 unsigned int format,
3145 struct snd_pcm_substream *substream)
3147 struct alc_spec *spec = codec->spec;
3149 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3150 stream_tag, 0, format);
3154 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3155 struct hda_codec *codec,
3156 struct snd_pcm_substream *substream)
3158 struct alc_spec *spec = codec->spec;
3160 snd_hda_codec_cleanup_stream(codec,
3161 spec->adc_nids[substream->number + 1]);
3168 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3172 /* NID is set in alc_build_pcms */
3174 .open = alc880_playback_pcm_open,
3175 .prepare = alc880_playback_pcm_prepare,
3176 .cleanup = alc880_playback_pcm_cleanup
3180 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3184 /* NID is set in alc_build_pcms */
3187 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3191 /* NID is set in alc_build_pcms */
3194 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3195 .substreams = 2, /* can be overridden */
3198 /* NID is set in alc_build_pcms */
3200 .prepare = alc880_alt_capture_pcm_prepare,
3201 .cleanup = alc880_alt_capture_pcm_cleanup
3205 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3209 /* NID is set in alc_build_pcms */
3211 .open = alc880_dig_playback_pcm_open,
3212 .close = alc880_dig_playback_pcm_close,
3213 .prepare = alc880_dig_playback_pcm_prepare,
3214 .cleanup = alc880_dig_playback_pcm_cleanup
3218 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3222 /* NID is set in alc_build_pcms */
3225 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3226 static struct hda_pcm_stream alc_pcm_null_stream = {
3232 static int alc_build_pcms(struct hda_codec *codec)
3234 struct alc_spec *spec = codec->spec;
3235 struct hda_pcm *info = spec->pcm_rec;
3238 codec->num_pcms = 1;
3239 codec->pcm_info = info;
3241 if (spec->no_analog)
3244 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3245 "%s Analog", codec->chip_name);
3246 info->name = spec->stream_name_analog;
3248 if (spec->stream_analog_playback) {
3249 if (snd_BUG_ON(!spec->multiout.dac_nids))
3251 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3252 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3254 if (spec->stream_analog_capture) {
3255 if (snd_BUG_ON(!spec->adc_nids))
3257 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3258 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3261 if (spec->channel_mode) {
3262 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3263 for (i = 0; i < spec->num_channel_mode; i++) {
3264 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3265 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3271 /* SPDIF for stream index #1 */
3272 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3273 snprintf(spec->stream_name_digital,
3274 sizeof(spec->stream_name_digital),
3275 "%s Digital", codec->chip_name);
3276 codec->num_pcms = 2;
3277 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3278 info = spec->pcm_rec + 1;
3279 info->name = spec->stream_name_digital;
3280 if (spec->dig_out_type)
3281 info->pcm_type = spec->dig_out_type;
3283 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3284 if (spec->multiout.dig_out_nid &&
3285 spec->stream_digital_playback) {
3286 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3287 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3289 if (spec->dig_in_nid &&
3290 spec->stream_digital_capture) {
3291 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3292 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3294 /* FIXME: do we need this for all Realtek codec models? */
3295 codec->spdif_status_reset = 1;
3298 if (spec->no_analog)
3301 /* If the use of more than one ADC is requested for the current
3302 * model, configure a second analog capture-only PCM.
3304 /* Additional Analaog capture for index #2 */
3305 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3306 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3307 codec->num_pcms = 3;
3308 info = spec->pcm_rec + 2;
3309 info->name = spec->stream_name_analog;
3310 if (spec->alt_dac_nid) {
3311 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3312 *spec->stream_analog_alt_playback;
3313 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3316 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3317 alc_pcm_null_stream;
3318 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3320 if (spec->num_adc_nids > 1) {
3321 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3322 *spec->stream_analog_alt_capture;
3323 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3325 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3326 spec->num_adc_nids - 1;
3328 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3329 alc_pcm_null_stream;
3330 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3337 static void alc_free_kctls(struct hda_codec *codec)
3339 struct alc_spec *spec = codec->spec;
3341 if (spec->kctls.list) {
3342 struct snd_kcontrol_new *kctl = spec->kctls.list;
3344 for (i = 0; i < spec->kctls.used; i++)
3345 kfree(kctl[i].name);
3347 snd_array_free(&spec->kctls);
3350 static void alc_free(struct hda_codec *codec)
3352 struct alc_spec *spec = codec->spec;
3357 alc_free_kctls(codec);
3359 snd_hda_detach_beep_device(codec);
3362 #ifdef SND_HDA_NEEDS_RESUME
3363 static int alc_resume(struct hda_codec *codec)
3365 codec->patch_ops.init(codec);
3366 snd_hda_codec_resume_amp(codec);
3367 snd_hda_codec_resume_cache(codec);
3374 static struct hda_codec_ops alc_patch_ops = {
3375 .build_controls = alc_build_controls,
3376 .build_pcms = alc_build_pcms,
3379 .unsol_event = alc_unsol_event,
3380 #ifdef SND_HDA_NEEDS_RESUME
3381 .resume = alc_resume,
3383 #ifdef CONFIG_SND_HDA_POWER_SAVE
3384 .check_power_status = alc_check_power_status,
3390 * Test configuration for debugging
3392 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3395 #ifdef CONFIG_SND_DEBUG
3396 static hda_nid_t alc880_test_dac_nids[4] = {
3397 0x02, 0x03, 0x04, 0x05
3400 static struct hda_input_mux alc880_test_capture_source = {
3409 { "Surround", 0x6 },
3413 static struct hda_channel_mode alc880_test_modes[4] = {
3420 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3421 struct snd_ctl_elem_info *uinfo)
3423 static char *texts[] = {
3424 "N/A", "Line Out", "HP Out",
3425 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3427 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3429 uinfo->value.enumerated.items = 8;
3430 if (uinfo->value.enumerated.item >= 8)
3431 uinfo->value.enumerated.item = 7;
3432 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3436 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3437 struct snd_ctl_elem_value *ucontrol)
3439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3440 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3441 unsigned int pin_ctl, item = 0;
3443 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3444 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3445 if (pin_ctl & AC_PINCTL_OUT_EN) {
3446 if (pin_ctl & AC_PINCTL_HP_EN)
3450 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3451 switch (pin_ctl & AC_PINCTL_VREFEN) {
3452 case AC_PINCTL_VREF_HIZ: item = 3; break;
3453 case AC_PINCTL_VREF_50: item = 4; break;
3454 case AC_PINCTL_VREF_GRD: item = 5; break;
3455 case AC_PINCTL_VREF_80: item = 6; break;
3456 case AC_PINCTL_VREF_100: item = 7; break;
3459 ucontrol->value.enumerated.item[0] = item;
3463 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3464 struct snd_ctl_elem_value *ucontrol)
3466 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3467 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3468 static unsigned int ctls[] = {
3469 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3470 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3471 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3472 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3473 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3474 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3476 unsigned int old_ctl, new_ctl;
3478 old_ctl = snd_hda_codec_read(codec, nid, 0,
3479 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3480 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3481 if (old_ctl != new_ctl) {
3483 snd_hda_codec_write_cache(codec, nid, 0,
3484 AC_VERB_SET_PIN_WIDGET_CONTROL,
3486 val = ucontrol->value.enumerated.item[0] >= 3 ?
3488 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3495 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3496 struct snd_ctl_elem_info *uinfo)
3498 static char *texts[] = {
3499 "Front", "Surround", "CLFE", "Side"
3501 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3503 uinfo->value.enumerated.items = 4;
3504 if (uinfo->value.enumerated.item >= 4)
3505 uinfo->value.enumerated.item = 3;
3506 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3510 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3511 struct snd_ctl_elem_value *ucontrol)
3513 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3514 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3517 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3518 ucontrol->value.enumerated.item[0] = sel & 3;
3522 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3523 struct snd_ctl_elem_value *ucontrol)
3525 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3526 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3529 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3530 if (ucontrol->value.enumerated.item[0] != sel) {
3531 sel = ucontrol->value.enumerated.item[0] & 3;
3532 snd_hda_codec_write_cache(codec, nid, 0,
3533 AC_VERB_SET_CONNECT_SEL, sel);
3539 #define PIN_CTL_TEST(xname,nid) { \
3540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3542 .info = alc_test_pin_ctl_info, \
3543 .get = alc_test_pin_ctl_get, \
3544 .put = alc_test_pin_ctl_put, \
3545 .private_value = nid \
3548 #define PIN_SRC_TEST(xname,nid) { \
3549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3551 .info = alc_test_pin_src_info, \
3552 .get = alc_test_pin_src_get, \
3553 .put = alc_test_pin_src_put, \
3554 .private_value = nid \
3557 static struct snd_kcontrol_new alc880_test_mixer[] = {
3558 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3559 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3560 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3561 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3562 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3563 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3564 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3565 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3566 PIN_CTL_TEST("Front Pin Mode", 0x14),
3567 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3568 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3569 PIN_CTL_TEST("Side Pin Mode", 0x17),
3570 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3571 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3572 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3573 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3574 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3575 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3576 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3577 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3578 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3579 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3580 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3581 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3582 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3583 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3584 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3585 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3589 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3590 .name = "Channel Mode",
3591 .info = alc_ch_mode_info,
3592 .get = alc_ch_mode_get,
3593 .put = alc_ch_mode_put,
3598 static struct hda_verb alc880_test_init_verbs[] = {
3599 /* Unmute inputs of 0x0c - 0x0f */
3600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3602 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3604 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3606 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3607 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3608 /* Vol output for 0x0c-0x0f */
3609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3612 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3613 /* Set output pins 0x14-0x17 */
3614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3615 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3616 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3617 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3618 /* Unmute output pins 0x14-0x17 */
3619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3621 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3623 /* Set input pins 0x18-0x1c */
3624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3625 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3626 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3628 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3629 /* Mute input pins 0x18-0x1b */
3630 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3636 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3638 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3639 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3640 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3641 /* Analog input/passthru */
3642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3654 static const char *alc880_models[ALC880_MODEL_LAST] = {
3655 [ALC880_3ST] = "3stack",
3656 [ALC880_TCL_S700] = "tcl",
3657 [ALC880_3ST_DIG] = "3stack-digout",
3658 [ALC880_CLEVO] = "clevo",
3659 [ALC880_5ST] = "5stack",
3660 [ALC880_5ST_DIG] = "5stack-digout",
3661 [ALC880_W810] = "w810",
3662 [ALC880_Z71V] = "z71v",
3663 [ALC880_6ST] = "6stack",
3664 [ALC880_6ST_DIG] = "6stack-digout",
3665 [ALC880_ASUS] = "asus",
3666 [ALC880_ASUS_W1V] = "asus-w1v",
3667 [ALC880_ASUS_DIG] = "asus-dig",
3668 [ALC880_ASUS_DIG2] = "asus-dig2",
3669 [ALC880_UNIWILL_DIG] = "uniwill",
3670 [ALC880_UNIWILL_P53] = "uniwill-p53",
3671 [ALC880_FUJITSU] = "fujitsu",
3672 [ALC880_F1734] = "F1734",
3674 [ALC880_LG_LW] = "lg-lw",
3675 [ALC880_MEDION_RIM] = "medion",
3676 #ifdef CONFIG_SND_DEBUG
3677 [ALC880_TEST] = "test",
3679 [ALC880_AUTO] = "auto",
3682 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3683 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3684 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3685 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3686 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3687 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3688 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3689 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3690 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3691 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3692 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3693 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3694 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3695 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3696 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3697 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3698 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3699 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3700 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3701 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3702 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3703 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3704 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3705 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3706 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3707 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3708 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3709 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3710 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3711 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3712 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3713 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3714 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3715 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3716 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3717 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3718 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3719 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3720 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3721 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3722 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3723 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3724 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3725 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3726 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3727 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3728 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3729 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3730 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3731 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3732 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3733 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3734 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3735 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3736 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3737 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3738 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3739 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3740 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3741 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3742 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3743 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3744 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3745 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3746 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3747 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3748 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3749 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3750 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3752 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3753 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3754 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3759 * ALC880 codec presets
3761 static struct alc_config_preset alc880_presets[] = {
3763 .mixers = { alc880_three_stack_mixer },
3764 .init_verbs = { alc880_volume_init_verbs,
3765 alc880_pin_3stack_init_verbs },
3766 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3767 .dac_nids = alc880_dac_nids,
3768 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3769 .channel_mode = alc880_threestack_modes,
3771 .input_mux = &alc880_capture_source,
3773 [ALC880_3ST_DIG] = {
3774 .mixers = { alc880_three_stack_mixer },
3775 .init_verbs = { alc880_volume_init_verbs,
3776 alc880_pin_3stack_init_verbs },
3777 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3778 .dac_nids = alc880_dac_nids,
3779 .dig_out_nid = ALC880_DIGOUT_NID,
3780 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3781 .channel_mode = alc880_threestack_modes,
3783 .input_mux = &alc880_capture_source,
3785 [ALC880_TCL_S700] = {
3786 .mixers = { alc880_tcl_s700_mixer },
3787 .init_verbs = { alc880_volume_init_verbs,
3788 alc880_pin_tcl_S700_init_verbs,
3789 alc880_gpio2_init_verbs },
3790 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3791 .dac_nids = alc880_dac_nids,
3792 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3793 .num_adc_nids = 1, /* single ADC */
3795 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3796 .channel_mode = alc880_2_jack_modes,
3797 .input_mux = &alc880_capture_source,
3800 .mixers = { alc880_three_stack_mixer,
3801 alc880_five_stack_mixer},
3802 .init_verbs = { alc880_volume_init_verbs,
3803 alc880_pin_5stack_init_verbs },
3804 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3805 .dac_nids = alc880_dac_nids,
3806 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3807 .channel_mode = alc880_fivestack_modes,
3808 .input_mux = &alc880_capture_source,
3810 [ALC880_5ST_DIG] = {
3811 .mixers = { alc880_three_stack_mixer,
3812 alc880_five_stack_mixer },
3813 .init_verbs = { alc880_volume_init_verbs,
3814 alc880_pin_5stack_init_verbs },
3815 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3816 .dac_nids = alc880_dac_nids,
3817 .dig_out_nid = ALC880_DIGOUT_NID,
3818 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3819 .channel_mode = alc880_fivestack_modes,
3820 .input_mux = &alc880_capture_source,
3823 .mixers = { alc880_six_stack_mixer },
3824 .init_verbs = { alc880_volume_init_verbs,
3825 alc880_pin_6stack_init_verbs },
3826 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3827 .dac_nids = alc880_6st_dac_nids,
3828 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3829 .channel_mode = alc880_sixstack_modes,
3830 .input_mux = &alc880_6stack_capture_source,
3832 [ALC880_6ST_DIG] = {
3833 .mixers = { alc880_six_stack_mixer },
3834 .init_verbs = { alc880_volume_init_verbs,
3835 alc880_pin_6stack_init_verbs },
3836 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3837 .dac_nids = alc880_6st_dac_nids,
3838 .dig_out_nid = ALC880_DIGOUT_NID,
3839 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3840 .channel_mode = alc880_sixstack_modes,
3841 .input_mux = &alc880_6stack_capture_source,
3844 .mixers = { alc880_w810_base_mixer },
3845 .init_verbs = { alc880_volume_init_verbs,
3846 alc880_pin_w810_init_verbs,
3847 alc880_gpio2_init_verbs },
3848 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3849 .dac_nids = alc880_w810_dac_nids,
3850 .dig_out_nid = ALC880_DIGOUT_NID,
3851 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3852 .channel_mode = alc880_w810_modes,
3853 .input_mux = &alc880_capture_source,
3856 .mixers = { alc880_z71v_mixer },
3857 .init_verbs = { alc880_volume_init_verbs,
3858 alc880_pin_z71v_init_verbs },
3859 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3860 .dac_nids = alc880_z71v_dac_nids,
3861 .dig_out_nid = ALC880_DIGOUT_NID,
3863 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3864 .channel_mode = alc880_2_jack_modes,
3865 .input_mux = &alc880_capture_source,
3868 .mixers = { alc880_f1734_mixer },
3869 .init_verbs = { alc880_volume_init_verbs,
3870 alc880_pin_f1734_init_verbs },
3871 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3872 .dac_nids = alc880_f1734_dac_nids,
3874 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3875 .channel_mode = alc880_2_jack_modes,
3876 .input_mux = &alc880_f1734_capture_source,
3877 .unsol_event = alc880_uniwill_p53_unsol_event,
3878 .init_hook = alc880_uniwill_p53_init_hook,
3881 .mixers = { alc880_asus_mixer },
3882 .init_verbs = { alc880_volume_init_verbs,
3883 alc880_pin_asus_init_verbs,
3884 alc880_gpio1_init_verbs },
3885 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3886 .dac_nids = alc880_asus_dac_nids,
3887 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3888 .channel_mode = alc880_asus_modes,
3890 .input_mux = &alc880_capture_source,
3892 [ALC880_ASUS_DIG] = {
3893 .mixers = { alc880_asus_mixer },
3894 .init_verbs = { alc880_volume_init_verbs,
3895 alc880_pin_asus_init_verbs,
3896 alc880_gpio1_init_verbs },
3897 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3898 .dac_nids = alc880_asus_dac_nids,
3899 .dig_out_nid = ALC880_DIGOUT_NID,
3900 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3901 .channel_mode = alc880_asus_modes,
3903 .input_mux = &alc880_capture_source,
3905 [ALC880_ASUS_DIG2] = {
3906 .mixers = { alc880_asus_mixer },
3907 .init_verbs = { alc880_volume_init_verbs,
3908 alc880_pin_asus_init_verbs,
3909 alc880_gpio2_init_verbs }, /* use GPIO2 */
3910 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3911 .dac_nids = alc880_asus_dac_nids,
3912 .dig_out_nid = ALC880_DIGOUT_NID,
3913 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3914 .channel_mode = alc880_asus_modes,
3916 .input_mux = &alc880_capture_source,
3918 [ALC880_ASUS_W1V] = {
3919 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3920 .init_verbs = { alc880_volume_init_verbs,
3921 alc880_pin_asus_init_verbs,
3922 alc880_gpio1_init_verbs },
3923 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3924 .dac_nids = alc880_asus_dac_nids,
3925 .dig_out_nid = ALC880_DIGOUT_NID,
3926 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3927 .channel_mode = alc880_asus_modes,
3929 .input_mux = &alc880_capture_source,
3931 [ALC880_UNIWILL_DIG] = {
3932 .mixers = { alc880_asus_mixer },
3933 .init_verbs = { alc880_volume_init_verbs,
3934 alc880_pin_asus_init_verbs },
3935 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3936 .dac_nids = alc880_asus_dac_nids,
3937 .dig_out_nid = ALC880_DIGOUT_NID,
3938 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3939 .channel_mode = alc880_asus_modes,
3941 .input_mux = &alc880_capture_source,
3943 [ALC880_UNIWILL] = {
3944 .mixers = { alc880_uniwill_mixer },
3945 .init_verbs = { alc880_volume_init_verbs,
3946 alc880_uniwill_init_verbs },
3947 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3948 .dac_nids = alc880_asus_dac_nids,
3949 .dig_out_nid = ALC880_DIGOUT_NID,
3950 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3951 .channel_mode = alc880_threestack_modes,
3953 .input_mux = &alc880_capture_source,
3954 .unsol_event = alc880_uniwill_unsol_event,
3955 .init_hook = alc880_uniwill_init_hook,
3957 [ALC880_UNIWILL_P53] = {
3958 .mixers = { alc880_uniwill_p53_mixer },
3959 .init_verbs = { alc880_volume_init_verbs,
3960 alc880_uniwill_p53_init_verbs },
3961 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3962 .dac_nids = alc880_asus_dac_nids,
3963 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3964 .channel_mode = alc880_threestack_modes,
3965 .input_mux = &alc880_capture_source,
3966 .unsol_event = alc880_uniwill_p53_unsol_event,
3967 .init_hook = alc880_uniwill_p53_init_hook,
3969 [ALC880_FUJITSU] = {
3970 .mixers = { alc880_fujitsu_mixer },
3971 .init_verbs = { alc880_volume_init_verbs,
3972 alc880_uniwill_p53_init_verbs,
3973 alc880_beep_init_verbs },
3974 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3975 .dac_nids = alc880_dac_nids,
3976 .dig_out_nid = ALC880_DIGOUT_NID,
3977 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3978 .channel_mode = alc880_2_jack_modes,
3979 .input_mux = &alc880_capture_source,
3980 .unsol_event = alc880_uniwill_p53_unsol_event,
3981 .init_hook = alc880_uniwill_p53_init_hook,
3984 .mixers = { alc880_three_stack_mixer },
3985 .init_verbs = { alc880_volume_init_verbs,
3986 alc880_pin_clevo_init_verbs },
3987 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3988 .dac_nids = alc880_dac_nids,
3990 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3991 .channel_mode = alc880_threestack_modes,
3993 .input_mux = &alc880_capture_source,
3996 .mixers = { alc880_lg_mixer },
3997 .init_verbs = { alc880_volume_init_verbs,
3998 alc880_lg_init_verbs },
3999 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4000 .dac_nids = alc880_lg_dac_nids,
4001 .dig_out_nid = ALC880_DIGOUT_NID,
4002 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4003 .channel_mode = alc880_lg_ch_modes,
4005 .input_mux = &alc880_lg_capture_source,
4006 .unsol_event = alc_automute_amp_unsol_event,
4007 .init_hook = alc880_lg_init_hook,
4008 #ifdef CONFIG_SND_HDA_POWER_SAVE
4009 .loopbacks = alc880_lg_loopbacks,
4013 .mixers = { alc880_lg_lw_mixer },
4014 .init_verbs = { alc880_volume_init_verbs,
4015 alc880_lg_lw_init_verbs },
4016 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4017 .dac_nids = alc880_dac_nids,
4018 .dig_out_nid = ALC880_DIGOUT_NID,
4019 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4020 .channel_mode = alc880_lg_lw_modes,
4021 .input_mux = &alc880_lg_lw_capture_source,
4022 .unsol_event = alc_automute_amp_unsol_event,
4023 .init_hook = alc880_lg_lw_init_hook,
4025 [ALC880_MEDION_RIM] = {
4026 .mixers = { alc880_medion_rim_mixer },
4027 .init_verbs = { alc880_volume_init_verbs,
4028 alc880_medion_rim_init_verbs,
4029 alc_gpio2_init_verbs },
4030 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4031 .dac_nids = alc880_dac_nids,
4032 .dig_out_nid = ALC880_DIGOUT_NID,
4033 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4034 .channel_mode = alc880_2_jack_modes,
4035 .input_mux = &alc880_medion_rim_capture_source,
4036 .unsol_event = alc880_medion_rim_unsol_event,
4037 .init_hook = alc880_medion_rim_init_hook,
4039 #ifdef CONFIG_SND_DEBUG
4041 .mixers = { alc880_test_mixer },
4042 .init_verbs = { alc880_test_init_verbs },
4043 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4044 .dac_nids = alc880_test_dac_nids,
4045 .dig_out_nid = ALC880_DIGOUT_NID,
4046 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4047 .channel_mode = alc880_test_modes,
4048 .input_mux = &alc880_test_capture_source,
4054 * Automatic parse of I/O pins from the BIOS configuration
4059 ALC_CTL_WIDGET_MUTE,
4062 static struct snd_kcontrol_new alc880_control_templates[] = {
4063 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4064 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4065 HDA_BIND_MUTE(NULL, 0, 0, 0),
4068 /* add dynamic controls */
4069 static int add_control(struct alc_spec *spec, int type, const char *name,
4072 struct snd_kcontrol_new *knew;
4074 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4075 knew = snd_array_new(&spec->kctls);
4078 *knew = alc880_control_templates[type];
4079 knew->name = kstrdup(name, GFP_KERNEL);
4082 knew->private_value = val;
4086 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4087 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4088 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4089 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4090 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4091 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4092 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4093 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4094 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4095 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4096 #define ALC880_PIN_CD_NID 0x1c
4098 /* fill in the dac_nids table from the parsed pin configuration */
4099 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4100 const struct auto_pin_cfg *cfg)
4106 memset(assigned, 0, sizeof(assigned));
4107 spec->multiout.dac_nids = spec->private_dac_nids;
4109 /* check the pins hardwired to audio widget */
4110 for (i = 0; i < cfg->line_outs; i++) {
4111 nid = cfg->line_out_pins[i];
4112 if (alc880_is_fixed_pin(nid)) {
4113 int idx = alc880_fixed_pin_idx(nid);
4114 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4118 /* left pins can be connect to any audio widget */
4119 for (i = 0; i < cfg->line_outs; i++) {
4120 nid = cfg->line_out_pins[i];
4121 if (alc880_is_fixed_pin(nid))
4123 /* search for an empty channel */
4124 for (j = 0; j < cfg->line_outs; j++) {
4126 spec->multiout.dac_nids[i] =
4127 alc880_idx_to_dac(j);
4133 spec->multiout.num_dacs = cfg->line_outs;
4137 /* add playback controls from the parsed DAC table */
4138 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4139 const struct auto_pin_cfg *cfg)
4142 static const char *chname[4] = {
4143 "Front", "Surround", NULL /*CLFE*/, "Side"
4148 for (i = 0; i < cfg->line_outs; i++) {
4149 if (!spec->multiout.dac_nids[i])
4151 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4154 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4155 "Center Playback Volume",
4156 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4160 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4161 "LFE Playback Volume",
4162 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4166 err = add_control(spec, ALC_CTL_BIND_MUTE,
4167 "Center Playback Switch",
4168 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4172 err = add_control(spec, ALC_CTL_BIND_MUTE,
4173 "LFE Playback Switch",
4174 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4179 sprintf(name, "%s Playback Volume", chname[i]);
4180 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4181 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4185 sprintf(name, "%s Playback Switch", chname[i]);
4186 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4187 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4196 /* add playback controls for speaker and HP outputs */
4197 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4207 if (alc880_is_fixed_pin(pin)) {
4208 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4209 /* specify the DAC as the extra output */
4210 if (!spec->multiout.hp_nid)
4211 spec->multiout.hp_nid = nid;
4213 spec->multiout.extra_out_nid[0] = nid;
4214 /* control HP volume/switch on the output mixer amp */
4215 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4216 sprintf(name, "%s Playback Volume", pfx);
4217 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4218 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4221 sprintf(name, "%s Playback Switch", pfx);
4222 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4223 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4226 } else if (alc880_is_multi_pin(pin)) {
4227 /* set manual connection */
4228 /* we have only a switch on HP-out PIN */
4229 sprintf(name, "%s Playback Switch", pfx);
4230 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4231 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4238 /* create input playback/capture controls for the given pin */
4239 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4240 const char *ctlname,
4241 int idx, hda_nid_t mix_nid)
4246 sprintf(name, "%s Playback Volume", ctlname);
4247 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4248 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4251 sprintf(name, "%s Playback Switch", ctlname);
4252 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4253 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4259 /* create playback/capture controls for input pins */
4260 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4261 const struct auto_pin_cfg *cfg)
4263 struct hda_input_mux *imux = &spec->private_imux[0];
4266 for (i = 0; i < AUTO_PIN_LAST; i++) {
4267 if (alc880_is_input_pin(cfg->input_pins[i])) {
4268 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4269 err = new_analog_input(spec, cfg->input_pins[i],
4270 auto_pin_cfg_labels[i],
4274 imux->items[imux->num_items].label =
4275 auto_pin_cfg_labels[i];
4276 imux->items[imux->num_items].index =
4277 alc880_input_pin_idx(cfg->input_pins[i]);
4284 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4285 unsigned int pin_type)
4287 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4290 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4294 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4295 hda_nid_t nid, int pin_type,
4298 alc_set_pin_output(codec, nid, pin_type);
4299 /* need the manual connection? */
4300 if (alc880_is_multi_pin(nid)) {
4301 struct alc_spec *spec = codec->spec;
4302 int idx = alc880_multi_pin_idx(nid);
4303 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4304 AC_VERB_SET_CONNECT_SEL,
4305 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4309 static int get_pin_type(int line_out_type)
4311 if (line_out_type == AUTO_PIN_HP_OUT)
4317 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4319 struct alc_spec *spec = codec->spec;
4322 for (i = 0; i < spec->autocfg.line_outs; i++) {
4323 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4324 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4325 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4329 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4331 struct alc_spec *spec = codec->spec;
4334 pin = spec->autocfg.speaker_pins[0];
4335 if (pin) /* connect to front */
4336 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4337 pin = spec->autocfg.hp_pins[0];
4338 if (pin) /* connect to front */
4339 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4342 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4344 struct alc_spec *spec = codec->spec;
4347 for (i = 0; i < AUTO_PIN_LAST; i++) {
4348 hda_nid_t nid = spec->autocfg.input_pins[i];
4349 if (alc880_is_input_pin(nid)) {
4350 alc_set_input_pin(codec, nid, i);
4351 if (nid != ALC880_PIN_CD_NID &&
4352 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4353 snd_hda_codec_write(codec, nid, 0,
4354 AC_VERB_SET_AMP_GAIN_MUTE,
4360 /* parse the BIOS configuration and set up the alc_spec */
4361 /* return 1 if successful, 0 if the proper config is not found,
4362 * or a negative error code
4364 static int alc880_parse_auto_config(struct hda_codec *codec)
4366 struct alc_spec *spec = codec->spec;
4368 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4370 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4374 if (!spec->autocfg.line_outs)
4375 return 0; /* can't find valid BIOS pin config */
4377 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4380 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4383 err = alc880_auto_create_extra_out(spec,
4384 spec->autocfg.speaker_pins[0],
4388 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4392 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4396 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4398 /* check multiple SPDIF-out (for recent codecs) */
4399 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4401 err = snd_hda_get_connections(codec,
4402 spec->autocfg.dig_out_pins[i],
4407 spec->multiout.dig_out_nid = dig_nid;
4409 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4410 spec->slave_dig_outs[i - 1] = dig_nid;
4411 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4415 if (spec->autocfg.dig_in_pin)
4416 spec->dig_in_nid = ALC880_DIGIN_NID;
4418 if (spec->kctls.list)
4419 add_mixer(spec, spec->kctls.list);
4421 add_verb(spec, alc880_volume_init_verbs);
4423 spec->num_mux_defs = 1;
4424 spec->input_mux = &spec->private_imux[0];
4426 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4431 /* additional initialization for auto-configuration model */
4432 static void alc880_auto_init(struct hda_codec *codec)
4434 struct alc_spec *spec = codec->spec;
4435 alc880_auto_init_multi_out(codec);
4436 alc880_auto_init_extra_out(codec);
4437 alc880_auto_init_analog_input(codec);
4438 if (spec->unsol_event)
4439 alc_inithook(codec);
4442 static void set_capture_mixer(struct alc_spec *spec)
4444 static struct snd_kcontrol_new *caps[2][3] = {
4445 { alc_capture_mixer_nosrc1,
4446 alc_capture_mixer_nosrc2,
4447 alc_capture_mixer_nosrc3 },
4448 { alc_capture_mixer1,
4450 alc_capture_mixer3 },
4452 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4454 if (spec->input_mux && spec->input_mux->num_items > 1)
4458 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4462 #define set_beep_amp(spec, nid, idx, dir) \
4463 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4466 * OK, here we have finally the patch for ALC880
4469 static int patch_alc880(struct hda_codec *codec)
4471 struct alc_spec *spec;
4475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4481 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4484 if (board_config < 0) {
4485 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4486 "trying auto-probe from BIOS...\n", codec->chip_name);
4487 board_config = ALC880_AUTO;
4490 if (board_config == ALC880_AUTO) {
4491 /* automatic parse from the BIOS config */
4492 err = alc880_parse_auto_config(codec);
4498 "hda_codec: Cannot set up configuration "
4499 "from BIOS. Using 3-stack mode...\n");
4500 board_config = ALC880_3ST;
4504 err = snd_hda_attach_beep_device(codec, 0x1);
4510 if (board_config != ALC880_AUTO)
4511 setup_preset(spec, &alc880_presets[board_config]);
4513 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4514 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4515 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4517 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4518 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4520 if (!spec->adc_nids && spec->input_mux) {
4521 /* check whether NID 0x07 is valid */
4522 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4524 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4525 if (wcap != AC_WID_AUD_IN) {
4526 spec->adc_nids = alc880_adc_nids_alt;
4527 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4529 spec->adc_nids = alc880_adc_nids;
4530 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4533 set_capture_mixer(spec);
4534 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4536 spec->vmaster_nid = 0x0c;
4538 codec->patch_ops = alc_patch_ops;
4539 if (board_config == ALC880_AUTO)
4540 spec->init_hook = alc880_auto_init;
4541 #ifdef CONFIG_SND_HDA_POWER_SAVE
4542 if (!spec->loopback.amplist)
4543 spec->loopback.amplist = alc880_loopbacks;
4545 codec->proc_widget_hook = print_realtek_coef;
4555 static hda_nid_t alc260_dac_nids[1] = {
4560 static hda_nid_t alc260_adc_nids[1] = {
4565 static hda_nid_t alc260_adc_nids_alt[1] = {
4570 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4571 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4573 static hda_nid_t alc260_dual_adc_nids[2] = {
4578 #define ALC260_DIGOUT_NID 0x03
4579 #define ALC260_DIGIN_NID 0x06
4581 static struct hda_input_mux alc260_capture_source = {
4585 { "Front Mic", 0x1 },
4591 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4592 * headphone jack and the internal CD lines since these are the only pins at
4593 * which audio can appear. For flexibility, also allow the option of
4594 * recording the mixer output on the second ADC (ADC0 doesn't have a
4595 * connection to the mixer output).
4597 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4601 { "Mic/Line", 0x0 },
4603 { "Headphone", 0x2 },
4609 { "Mic/Line", 0x0 },
4611 { "Headphone", 0x2 },
4618 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4619 * the Fujitsu S702x, but jacks are marked differently.
4621 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4628 { "Headphone", 0x5 },
4637 { "Headphone", 0x6 },
4643 /* Maxdata Favorit 100XS */
4644 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4648 { "Line/Mic", 0x0 },
4655 { "Line/Mic", 0x0 },
4663 * This is just place-holder, so there's something for alc_build_pcms to look
4664 * at when it calculates the maximum number of channels. ALC260 has no mixer
4665 * element which allows changing the channel mode, so the verb list is
4668 static struct hda_channel_mode alc260_modes[1] = {
4673 /* Mixer combinations
4675 * basic: base_output + input + pc_beep + capture
4676 * HP: base_output + input + capture_alt
4677 * HP_3013: hp_3013 + input + capture
4678 * fujitsu: fujitsu + capture
4679 * acer: acer + capture
4682 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4683 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4684 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4685 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4686 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4687 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4688 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4692 static struct snd_kcontrol_new alc260_input_mixer[] = {
4693 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4694 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4695 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4696 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4697 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4698 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4704 /* update HP, line and mono out pins according to the master switch */
4705 static void alc260_hp_master_update(struct hda_codec *codec,
4706 hda_nid_t hp, hda_nid_t line,
4709 struct alc_spec *spec = codec->spec;
4710 unsigned int val = spec->master_sw ? PIN_HP : 0;
4711 /* change HP and line-out pins */
4712 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4714 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4716 /* mono (speaker) depending on the HP jack sense */
4717 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4718 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4722 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4723 struct snd_ctl_elem_value *ucontrol)
4725 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4726 struct alc_spec *spec = codec->spec;
4727 *ucontrol->value.integer.value = spec->master_sw;
4731 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4732 struct snd_ctl_elem_value *ucontrol)
4734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4735 struct alc_spec *spec = codec->spec;
4736 int val = !!*ucontrol->value.integer.value;
4737 hda_nid_t hp, line, mono;
4739 if (val == spec->master_sw)
4741 spec->master_sw = val;
4742 hp = (kcontrol->private_value >> 16) & 0xff;
4743 line = (kcontrol->private_value >> 8) & 0xff;
4744 mono = kcontrol->private_value & 0xff;
4745 alc260_hp_master_update(codec, hp, line, mono);
4749 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4752 .name = "Master Playback Switch",
4753 .info = snd_ctl_boolean_mono_info,
4754 .get = alc260_hp_master_sw_get,
4755 .put = alc260_hp_master_sw_put,
4756 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4758 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4759 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4760 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4761 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4762 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4764 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4768 static struct hda_verb alc260_hp_unsol_verbs[] = {
4769 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4773 static void alc260_hp_automute(struct hda_codec *codec)
4775 struct alc_spec *spec = codec->spec;
4776 unsigned int present;
4778 present = snd_hda_codec_read(codec, 0x10, 0,
4779 AC_VERB_GET_PIN_SENSE, 0);
4780 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4781 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4784 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4786 if ((res >> 26) == ALC880_HP_EVENT)
4787 alc260_hp_automute(codec);
4790 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4793 .name = "Master Playback Switch",
4794 .info = snd_ctl_boolean_mono_info,
4795 .get = alc260_hp_master_sw_get,
4796 .put = alc260_hp_master_sw_put,
4797 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4799 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4800 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4801 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4802 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4803 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4805 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4806 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4810 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4811 .ops = &snd_hda_bind_vol,
4813 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4814 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4815 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4820 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4821 .ops = &snd_hda_bind_sw,
4823 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4824 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4829 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4830 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4831 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4832 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4837 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4838 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4842 static void alc260_hp_3013_automute(struct hda_codec *codec)
4844 struct alc_spec *spec = codec->spec;
4845 unsigned int present;
4847 present = snd_hda_codec_read(codec, 0x15, 0,
4848 AC_VERB_GET_PIN_SENSE, 0);
4849 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4850 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4853 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4856 if ((res >> 26) == ALC880_HP_EVENT)
4857 alc260_hp_3013_automute(codec);
4860 static void alc260_hp_3012_automute(struct hda_codec *codec)
4862 unsigned int present, bits;
4864 present = snd_hda_codec_read(codec, 0x10, 0,
4865 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4867 bits = present ? 0 : PIN_OUT;
4868 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4870 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4872 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4876 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4879 if ((res >> 26) == ALC880_HP_EVENT)
4880 alc260_hp_3012_automute(codec);
4883 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4884 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4886 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4887 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4888 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4889 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4890 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4891 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4892 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4893 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4894 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4895 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4896 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4900 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4901 * versions of the ALC260 don't act on requests to enable mic bias from NID
4902 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4903 * datasheet doesn't mention this restriction. At this stage it's not clear
4904 * whether this behaviour is intentional or is a hardware bug in chip
4905 * revisions available in early 2006. Therefore for now allow the
4906 * "Headphone Jack Mode" control to span all choices, but if it turns out
4907 * that the lack of mic bias for this NID is intentional we could change the
4908 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4910 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4911 * don't appear to make the mic bias available from the "line" jack, even
4912 * though the NID used for this jack (0x14) can supply it. The theory is
4913 * that perhaps Acer have included blocking capacitors between the ALC260
4914 * and the output jack. If this turns out to be the case for all such
4915 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4916 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4918 * The C20x Tablet series have a mono internal speaker which is controlled
4919 * via the chip's Mono sum widget and pin complex, so include the necessary
4920 * controls for such models. On models without a "mono speaker" the control
4921 * won't do anything.
4923 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4924 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4925 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4926 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4927 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4929 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4931 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4932 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4934 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4935 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4936 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4937 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4938 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4942 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4944 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4945 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4946 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4947 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4948 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4949 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4950 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4954 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4955 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4957 static struct snd_kcontrol_new alc260_will_mixer[] = {
4958 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4959 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4960 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4961 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4962 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4963 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4964 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4965 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4966 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4967 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4971 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4972 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4974 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4975 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4976 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4978 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4979 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4980 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4981 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4982 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4983 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4984 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4989 * initialization verbs
4991 static struct hda_verb alc260_init_verbs[] = {
4992 /* Line In pin widget for input */
4993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4994 /* CD pin widget for input */
4995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4996 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4997 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4998 /* Mic2 (front panel) pin widget for input and vref at 80% */
4999 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5000 /* LINE-2 is used for line-out in rear */
5001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5002 /* select line-out */
5003 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5005 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5007 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5009 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5010 /* mute capture amp left and right */
5011 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5012 /* set connection select to line in (default select for this ADC) */
5013 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5014 /* mute capture amp left and right */
5015 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5016 /* set connection select to line in (default select for this ADC) */
5017 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5018 /* set vol=0 Line-Out mixer amp left and right */
5019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5020 /* unmute pin widget amp left and right (no gain on this amp) */
5021 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5022 /* set vol=0 HP mixer amp left and right */
5023 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5024 /* unmute pin widget amp left and right (no gain on this amp) */
5025 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5026 /* set vol=0 Mono mixer amp left and right */
5027 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5028 /* unmute pin widget amp left and right (no gain on this amp) */
5029 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5030 /* unmute LINE-2 out pin */
5031 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5032 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5035 /* mute analog inputs */
5036 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5038 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5039 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5040 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5041 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5042 /* mute Front out path */
5043 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5044 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5045 /* mute Headphone out path */
5046 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5047 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5048 /* mute Mono out path */
5049 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5050 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5054 #if 0 /* should be identical with alc260_init_verbs? */
5055 static struct hda_verb alc260_hp_init_verbs[] = {
5056 /* Headphone and output */
5057 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5059 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5060 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5061 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5062 /* Mic2 (front panel) pin widget for input and vref at 80% */
5063 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5064 /* Line In pin widget for input */
5065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5066 /* Line-2 pin widget for output */
5067 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5068 /* CD pin widget for input */
5069 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5070 /* unmute amp left and right */
5071 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5072 /* set connection select to line in (default select for this ADC) */
5073 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5074 /* unmute Line-Out mixer amp left and right (volume = 0) */
5075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5076 /* mute pin widget amp left and right (no gain on this amp) */
5077 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5078 /* unmute HP mixer amp left and right (volume = 0) */
5079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5080 /* mute pin widget amp left and right (no gain on this amp) */
5081 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5082 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5085 /* mute analog inputs */
5086 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5088 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5089 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5090 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5091 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5092 /* Unmute Front out path */
5093 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5094 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5095 /* Unmute Headphone out path */
5096 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5097 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5098 /* Unmute Mono out path */
5099 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5100 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5105 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5106 /* Line out and output */
5107 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5109 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5110 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5111 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5112 /* Mic2 (front panel) pin widget for input and vref at 80% */
5113 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5114 /* Line In pin widget for input */
5115 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5116 /* Headphone pin widget for output */
5117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5118 /* CD pin widget for input */
5119 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5120 /* unmute amp left and right */
5121 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5122 /* set connection select to line in (default select for this ADC) */
5123 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5124 /* unmute Line-Out mixer amp left and right (volume = 0) */
5125 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5126 /* mute pin widget amp left and right (no gain on this amp) */
5127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5128 /* unmute HP mixer amp left and right (volume = 0) */
5129 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5130 /* mute pin widget amp left and right (no gain on this amp) */
5131 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5132 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5135 /* mute analog inputs */
5136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5141 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5142 /* Unmute Front out path */
5143 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5145 /* Unmute Headphone out path */
5146 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5147 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5148 /* Unmute Mono out path */
5149 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5150 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5154 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5155 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5156 * audio = 0x16, internal speaker = 0x10.
5158 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5159 /* Disable all GPIOs */
5160 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5161 /* Internal speaker is connected to headphone pin */
5162 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5163 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5164 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5165 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5166 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5167 /* Ensure all other unused pins are disabled and muted. */
5168 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5169 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5170 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5171 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5172 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5173 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5177 /* Disable digital (SPDIF) pins */
5178 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5179 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5181 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5182 * when acting as an output.
5184 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5186 /* Start with output sum widgets muted and their output gains at min */
5187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5191 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5193 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5194 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5195 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5197 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5198 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5199 /* Unmute Line1 pin widget output buffer since it starts as an output.
5200 * If the pin mode is changed by the user the pin mode control will
5201 * take care of enabling the pin's input/output buffers as needed.
5202 * Therefore there's no need to enable the input buffer at this
5205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5206 /* Unmute input buffer of pin widget used for Line-in (no equiv
5209 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5211 /* Mute capture amp left and right */
5212 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5213 /* Set ADC connection select to match default mixer setting - line
5216 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5218 /* Do the same for the second ADC: mute capture input amp and
5219 * set ADC connection to line in (on mic1 pin)
5221 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5222 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5224 /* Mute all inputs to mixer widget (even unconnected ones) */
5225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5237 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5238 * similar laptops (adapted from Fujitsu init verbs).
5240 static struct hda_verb alc260_acer_init_verbs[] = {
5241 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5242 * the headphone jack. Turn this on and rely on the standard mute
5243 * methods whenever the user wants to turn these outputs off.
5245 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5246 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5247 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5248 /* Internal speaker/Headphone jack is connected to Line-out pin */
5249 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5250 /* Internal microphone/Mic jack is connected to Mic1 pin */
5251 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5252 /* Line In jack is connected to Line1 pin */
5253 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5254 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5255 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5256 /* Ensure all other unused pins are disabled and muted. */
5257 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5258 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5259 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5260 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5261 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5262 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5263 /* Disable digital (SPDIF) pins */
5264 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5265 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5267 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5268 * bus when acting as outputs.
5270 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5271 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5273 /* Start with output sum widgets muted and their output gains at min */
5274 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5275 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5276 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5277 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5278 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5280 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5281 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5282 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5284 /* Unmute Line-out pin widget amp left and right
5285 * (no equiv mixer ctrl)
5287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5288 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5289 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5290 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5291 * inputs. If the pin mode is changed by the user the pin mode control
5292 * will take care of enabling the pin's input/output buffers as needed.
5293 * Therefore there's no need to enable the input buffer at this
5296 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5297 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5299 /* Mute capture amp left and right */
5300 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5301 /* Set ADC connection select to match default mixer setting - mic
5304 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5306 /* Do similar with the second ADC: mute capture input amp and
5307 * set ADC connection to mic to match ALSA's default state.
5309 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5310 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5312 /* Mute all inputs to mixer widget (even unconnected ones) */
5313 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5314 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5315 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5316 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5318 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5325 /* Initialisation sequence for Maxdata Favorit 100XS
5326 * (adapted from Acer init verbs).
5328 static struct hda_verb alc260_favorit100_init_verbs[] = {
5329 /* GPIO 0 enables the output jack.
5330 * Turn this on and rely on the standard mute
5331 * methods whenever the user wants to turn these outputs off.
5333 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5334 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5335 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5336 /* Line/Mic input jack is connected to Mic1 pin */
5337 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5338 /* Ensure all other unused pins are disabled and muted. */
5339 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5340 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5341 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5342 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5343 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5344 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5345 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5346 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5348 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5349 /* Disable digital (SPDIF) pins */
5350 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5351 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5353 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5354 * bus when acting as outputs.
5356 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5357 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5359 /* Start with output sum widgets muted and their output gains at min */
5360 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5362 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5366 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5367 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5368 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5370 /* Unmute Line-out pin widget amp left and right
5371 * (no equiv mixer ctrl)
5373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5374 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5375 * inputs. If the pin mode is changed by the user the pin mode control
5376 * will take care of enabling the pin's input/output buffers as needed.
5377 * Therefore there's no need to enable the input buffer at this
5380 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5382 /* Mute capture amp left and right */
5383 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5384 /* Set ADC connection select to match default mixer setting - mic
5387 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5389 /* Do similar with the second ADC: mute capture input amp and
5390 * set ADC connection to mic to match ALSA's default state.
5392 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5393 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5395 /* Mute all inputs to mixer widget (even unconnected ones) */
5396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5408 static struct hda_verb alc260_will_verbs[] = {
5409 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5410 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5411 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5412 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5413 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5414 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5418 static struct hda_verb alc260_replacer_672v_verbs[] = {
5419 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5420 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5421 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5423 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5424 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5425 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5427 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5431 /* toggle speaker-output according to the hp-jack state */
5432 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5434 unsigned int present;
5436 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5437 present = snd_hda_codec_read(codec, 0x0f, 0,
5438 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5440 snd_hda_codec_write_cache(codec, 0x01, 0,
5441 AC_VERB_SET_GPIO_DATA, 1);
5442 snd_hda_codec_write_cache(codec, 0x0f, 0,
5443 AC_VERB_SET_PIN_WIDGET_CONTROL,
5446 snd_hda_codec_write_cache(codec, 0x01, 0,
5447 AC_VERB_SET_GPIO_DATA, 0);
5448 snd_hda_codec_write_cache(codec, 0x0f, 0,
5449 AC_VERB_SET_PIN_WIDGET_CONTROL,
5454 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5457 if ((res >> 26) == ALC880_HP_EVENT)
5458 alc260_replacer_672v_automute(codec);
5461 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5462 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5463 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5464 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5465 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5466 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5467 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5468 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5469 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5470 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5475 /* Test configuration for debugging, modelled after the ALC880 test
5478 #ifdef CONFIG_SND_DEBUG
5479 static hda_nid_t alc260_test_dac_nids[1] = {
5482 static hda_nid_t alc260_test_adc_nids[2] = {
5485 /* For testing the ALC260, each input MUX needs its own definition since
5486 * the signal assignments are different. This assumes that the first ADC
5489 static struct hda_input_mux alc260_test_capture_sources[2] = {
5493 { "MIC1 pin", 0x0 },
5494 { "MIC2 pin", 0x1 },
5495 { "LINE1 pin", 0x2 },
5496 { "LINE2 pin", 0x3 },
5498 { "LINE-OUT pin", 0x5 },
5499 { "HP-OUT pin", 0x6 },
5505 { "MIC1 pin", 0x0 },
5506 { "MIC2 pin", 0x1 },
5507 { "LINE1 pin", 0x2 },
5508 { "LINE2 pin", 0x3 },
5511 { "LINE-OUT pin", 0x6 },
5512 { "HP-OUT pin", 0x7 },
5516 static struct snd_kcontrol_new alc260_test_mixer[] = {
5517 /* Output driver widgets */
5518 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5519 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5520 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5521 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5522 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5523 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5525 /* Modes for retasking pin widgets
5526 * Note: the ALC260 doesn't seem to act on requests to enable mic
5527 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5528 * mention this restriction. At this stage it's not clear whether
5529 * this behaviour is intentional or is a hardware bug in chip
5530 * revisions available at least up until early 2006. Therefore for
5531 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5532 * choices, but if it turns out that the lack of mic bias for these
5533 * NIDs is intentional we could change their modes from
5534 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5536 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5537 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5538 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5539 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5540 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5541 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5543 /* Loopback mixer controls */
5544 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5545 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5546 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5547 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5548 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5549 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5550 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5551 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5552 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5553 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5554 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5555 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5556 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5557 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5559 /* Controls for GPIO pins, assuming they are configured as outputs */
5560 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5561 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5562 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5563 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5565 /* Switches to allow the digital IO pins to be enabled. The datasheet
5566 * is ambigious as to which NID is which; testing on laptops which
5567 * make this output available should provide clarification.
5569 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5570 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5572 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5573 * this output to turn on an external amplifier.
5575 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5576 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5580 static struct hda_verb alc260_test_init_verbs[] = {
5581 /* Enable all GPIOs as outputs with an initial value of 0 */
5582 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5583 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5584 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5586 /* Enable retasking pins as output, initially without power amp */
5587 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5588 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5591 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5592 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5594 /* Disable digital (SPDIF) pins initially, but users can enable
5595 * them via a mixer switch. In the case of SPDIF-out, this initverb
5596 * payload also sets the generation to 0, output to be in "consumer"
5597 * PCM format, copyright asserted, no pre-emphasis and no validity
5600 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5601 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5603 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5604 * OUT1 sum bus when acting as an output.
5606 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5607 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5608 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5609 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5611 /* Start with output sum widgets muted and their output gains at min */
5612 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5613 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5614 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5616 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5618 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5619 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5620 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5622 /* Unmute retasking pin widget output buffers since the default
5623 * state appears to be output. As the pin mode is changed by the
5624 * user the pin mode control will take care of enabling the pin's
5625 * input/output buffers as needed.
5627 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5628 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5629 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5630 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5631 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5632 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5633 /* Also unmute the mono-out pin widget */
5634 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5636 /* Mute capture amp left and right */
5637 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5638 /* Set ADC connection select to match default mixer setting (mic1
5641 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5643 /* Do the same for the second ADC: mute capture input amp and
5644 * set ADC connection to mic1 pin
5646 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5647 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5649 /* Mute all inputs to mixer widget (even unconnected ones) */
5650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5653 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5663 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5664 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5666 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5667 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5670 * for BIOS auto-configuration
5673 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5674 const char *pfx, int *vol_bits)
5677 unsigned long vol_val, sw_val;
5681 if (nid >= 0x0f && nid < 0x11) {
5682 nid_vol = nid - 0x7;
5683 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5684 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5685 } else if (nid == 0x11) {
5686 nid_vol = nid - 0x7;
5687 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5688 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5689 } else if (nid >= 0x12 && nid <= 0x15) {
5691 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5692 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5696 if (!(*vol_bits & (1 << nid_vol))) {
5697 /* first control for the volume widget */
5698 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5699 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5702 *vol_bits |= (1 << nid_vol);
5704 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5705 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5711 /* add playback controls from the parsed DAC table */
5712 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5713 const struct auto_pin_cfg *cfg)
5719 spec->multiout.num_dacs = 1;
5720 spec->multiout.dac_nids = spec->private_dac_nids;
5721 spec->multiout.dac_nids[0] = 0x02;
5723 nid = cfg->line_out_pins[0];
5725 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5730 nid = cfg->speaker_pins[0];
5732 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5737 nid = cfg->hp_pins[0];
5739 err = alc260_add_playback_controls(spec, nid, "Headphone",
5747 /* create playback/capture controls for input pins */
5748 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5749 const struct auto_pin_cfg *cfg)
5751 struct hda_input_mux *imux = &spec->private_imux[0];
5754 for (i = 0; i < AUTO_PIN_LAST; i++) {
5755 if (cfg->input_pins[i] >= 0x12) {
5756 idx = cfg->input_pins[i] - 0x12;
5757 err = new_analog_input(spec, cfg->input_pins[i],
5758 auto_pin_cfg_labels[i], idx,
5762 imux->items[imux->num_items].label =
5763 auto_pin_cfg_labels[i];
5764 imux->items[imux->num_items].index = idx;
5767 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5768 idx = cfg->input_pins[i] - 0x09;
5769 err = new_analog_input(spec, cfg->input_pins[i],
5770 auto_pin_cfg_labels[i], idx,
5774 imux->items[imux->num_items].label =
5775 auto_pin_cfg_labels[i];
5776 imux->items[imux->num_items].index = idx;
5783 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5784 hda_nid_t nid, int pin_type,
5787 alc_set_pin_output(codec, nid, pin_type);
5788 /* need the manual connection? */
5790 int idx = nid - 0x12;
5791 snd_hda_codec_write(codec, idx + 0x0b, 0,
5792 AC_VERB_SET_CONNECT_SEL, sel_idx);
5796 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5798 struct alc_spec *spec = codec->spec;
5801 nid = spec->autocfg.line_out_pins[0];
5803 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5804 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5807 nid = spec->autocfg.speaker_pins[0];
5809 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5811 nid = spec->autocfg.hp_pins[0];
5813 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5816 #define ALC260_PIN_CD_NID 0x16
5817 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5819 struct alc_spec *spec = codec->spec;
5822 for (i = 0; i < AUTO_PIN_LAST; i++) {
5823 hda_nid_t nid = spec->autocfg.input_pins[i];
5825 alc_set_input_pin(codec, nid, i);
5826 if (nid != ALC260_PIN_CD_NID &&
5827 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5828 snd_hda_codec_write(codec, nid, 0,
5829 AC_VERB_SET_AMP_GAIN_MUTE,
5836 * generic initialization of ADC, input mixers and output mixers
5838 static struct hda_verb alc260_volume_init_verbs[] = {
5840 * Unmute ADC0-1 and set the default input to mic-in
5842 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5843 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5844 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5845 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5847 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5849 * Note: PASD motherboards uses the Line In 2 as the input for
5850 * front panel mic (mic 2)
5852 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5853 /* mute analog inputs */
5854 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5855 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5856 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5857 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5861 * Set up output mixers (0x08 - 0x0a)
5863 /* set vol=0 to output mixers */
5864 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5865 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5866 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5867 /* set up input amps for analog loopback */
5868 /* Amp Indices: DAC = 0, mixer = 1 */
5869 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5870 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5872 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5873 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5874 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5879 static int alc260_parse_auto_config(struct hda_codec *codec)
5881 struct alc_spec *spec = codec->spec;
5883 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5885 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5889 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5892 if (!spec->kctls.list)
5893 return 0; /* can't find valid BIOS pin config */
5894 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5898 spec->multiout.max_channels = 2;
5900 if (spec->autocfg.dig_outs)
5901 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5902 if (spec->kctls.list)
5903 add_mixer(spec, spec->kctls.list);
5905 add_verb(spec, alc260_volume_init_verbs);
5907 spec->num_mux_defs = 1;
5908 spec->input_mux = &spec->private_imux[0];
5910 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5915 /* additional initialization for auto-configuration model */
5916 static void alc260_auto_init(struct hda_codec *codec)
5918 struct alc_spec *spec = codec->spec;
5919 alc260_auto_init_multi_out(codec);
5920 alc260_auto_init_analog_input(codec);
5921 if (spec->unsol_event)
5922 alc_inithook(codec);
5925 #ifdef CONFIG_SND_HDA_POWER_SAVE
5926 static struct hda_amp_list alc260_loopbacks[] = {
5927 { 0x07, HDA_INPUT, 0 },
5928 { 0x07, HDA_INPUT, 1 },
5929 { 0x07, HDA_INPUT, 2 },
5930 { 0x07, HDA_INPUT, 3 },
5931 { 0x07, HDA_INPUT, 4 },
5937 * ALC260 configurations
5939 static const char *alc260_models[ALC260_MODEL_LAST] = {
5940 [ALC260_BASIC] = "basic",
5942 [ALC260_HP_3013] = "hp-3013",
5943 [ALC260_HP_DC7600] = "hp-dc7600",
5944 [ALC260_FUJITSU_S702X] = "fujitsu",
5945 [ALC260_ACER] = "acer",
5946 [ALC260_WILL] = "will",
5947 [ALC260_REPLACER_672V] = "replacer",
5948 [ALC260_FAVORIT100] = "favorit100",
5949 #ifdef CONFIG_SND_DEBUG
5950 [ALC260_TEST] = "test",
5952 [ALC260_AUTO] = "auto",
5955 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5956 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5957 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5958 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5959 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5960 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5961 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5962 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5963 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5964 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5965 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5966 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5967 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5968 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5969 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5970 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5971 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5972 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5973 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5974 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5978 static struct alc_config_preset alc260_presets[] = {
5980 .mixers = { alc260_base_output_mixer,
5981 alc260_input_mixer },
5982 .init_verbs = { alc260_init_verbs },
5983 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5984 .dac_nids = alc260_dac_nids,
5985 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5986 .adc_nids = alc260_adc_nids,
5987 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5988 .channel_mode = alc260_modes,
5989 .input_mux = &alc260_capture_source,
5992 .mixers = { alc260_hp_output_mixer,
5993 alc260_input_mixer },
5994 .init_verbs = { alc260_init_verbs,
5995 alc260_hp_unsol_verbs },
5996 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5997 .dac_nids = alc260_dac_nids,
5998 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5999 .adc_nids = alc260_adc_nids_alt,
6000 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6001 .channel_mode = alc260_modes,
6002 .input_mux = &alc260_capture_source,
6003 .unsol_event = alc260_hp_unsol_event,
6004 .init_hook = alc260_hp_automute,
6006 [ALC260_HP_DC7600] = {
6007 .mixers = { alc260_hp_dc7600_mixer,
6008 alc260_input_mixer },
6009 .init_verbs = { alc260_init_verbs,
6010 alc260_hp_dc7600_verbs },
6011 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6012 .dac_nids = alc260_dac_nids,
6013 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6014 .adc_nids = alc260_adc_nids_alt,
6015 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6016 .channel_mode = alc260_modes,
6017 .input_mux = &alc260_capture_source,
6018 .unsol_event = alc260_hp_3012_unsol_event,
6019 .init_hook = alc260_hp_3012_automute,
6021 [ALC260_HP_3013] = {
6022 .mixers = { alc260_hp_3013_mixer,
6023 alc260_input_mixer },
6024 .init_verbs = { alc260_hp_3013_init_verbs,
6025 alc260_hp_3013_unsol_verbs },
6026 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6027 .dac_nids = alc260_dac_nids,
6028 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6029 .adc_nids = alc260_adc_nids_alt,
6030 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6031 .channel_mode = alc260_modes,
6032 .input_mux = &alc260_capture_source,
6033 .unsol_event = alc260_hp_3013_unsol_event,
6034 .init_hook = alc260_hp_3013_automute,
6036 [ALC260_FUJITSU_S702X] = {
6037 .mixers = { alc260_fujitsu_mixer },
6038 .init_verbs = { alc260_fujitsu_init_verbs },
6039 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6040 .dac_nids = alc260_dac_nids,
6041 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6042 .adc_nids = alc260_dual_adc_nids,
6043 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6044 .channel_mode = alc260_modes,
6045 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6046 .input_mux = alc260_fujitsu_capture_sources,
6049 .mixers = { alc260_acer_mixer },
6050 .init_verbs = { alc260_acer_init_verbs },
6051 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6052 .dac_nids = alc260_dac_nids,
6053 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6054 .adc_nids = alc260_dual_adc_nids,
6055 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6056 .channel_mode = alc260_modes,
6057 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6058 .input_mux = alc260_acer_capture_sources,
6060 [ALC260_FAVORIT100] = {
6061 .mixers = { alc260_favorit100_mixer },
6062 .init_verbs = { alc260_favorit100_init_verbs },
6063 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6064 .dac_nids = alc260_dac_nids,
6065 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6066 .adc_nids = alc260_dual_adc_nids,
6067 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6068 .channel_mode = alc260_modes,
6069 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6070 .input_mux = alc260_favorit100_capture_sources,
6073 .mixers = { alc260_will_mixer },
6074 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6075 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6076 .dac_nids = alc260_dac_nids,
6077 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6078 .adc_nids = alc260_adc_nids,
6079 .dig_out_nid = ALC260_DIGOUT_NID,
6080 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6081 .channel_mode = alc260_modes,
6082 .input_mux = &alc260_capture_source,
6084 [ALC260_REPLACER_672V] = {
6085 .mixers = { alc260_replacer_672v_mixer },
6086 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6087 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6088 .dac_nids = alc260_dac_nids,
6089 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6090 .adc_nids = alc260_adc_nids,
6091 .dig_out_nid = ALC260_DIGOUT_NID,
6092 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6093 .channel_mode = alc260_modes,
6094 .input_mux = &alc260_capture_source,
6095 .unsol_event = alc260_replacer_672v_unsol_event,
6096 .init_hook = alc260_replacer_672v_automute,
6098 #ifdef CONFIG_SND_DEBUG
6100 .mixers = { alc260_test_mixer },
6101 .init_verbs = { alc260_test_init_verbs },
6102 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6103 .dac_nids = alc260_test_dac_nids,
6104 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6105 .adc_nids = alc260_test_adc_nids,
6106 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6107 .channel_mode = alc260_modes,
6108 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6109 .input_mux = alc260_test_capture_sources,
6114 static int patch_alc260(struct hda_codec *codec)
6116 struct alc_spec *spec;
6117 int err, board_config;
6119 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6125 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6128 if (board_config < 0) {
6129 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6130 "trying auto-probe from BIOS...\n",
6132 board_config = ALC260_AUTO;
6135 if (board_config == ALC260_AUTO) {
6136 /* automatic parse from the BIOS config */
6137 err = alc260_parse_auto_config(codec);
6143 "hda_codec: Cannot set up configuration "
6144 "from BIOS. Using base mode...\n");
6145 board_config = ALC260_BASIC;
6149 err = snd_hda_attach_beep_device(codec, 0x1);
6155 if (board_config != ALC260_AUTO)
6156 setup_preset(spec, &alc260_presets[board_config]);
6158 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6159 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6161 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6162 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6164 if (!spec->adc_nids && spec->input_mux) {
6165 /* check whether NID 0x04 is valid */
6166 unsigned int wcap = get_wcaps(codec, 0x04);
6167 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6169 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6170 spec->adc_nids = alc260_adc_nids_alt;
6171 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6173 spec->adc_nids = alc260_adc_nids;
6174 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6177 set_capture_mixer(spec);
6178 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6180 spec->vmaster_nid = 0x08;
6182 codec->patch_ops = alc_patch_ops;
6183 if (board_config == ALC260_AUTO)
6184 spec->init_hook = alc260_auto_init;
6185 #ifdef CONFIG_SND_HDA_POWER_SAVE
6186 if (!spec->loopback.amplist)
6187 spec->loopback.amplist = alc260_loopbacks;
6189 codec->proc_widget_hook = print_realtek_coef;
6198 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6199 * configuration. Each pin widget can choose any input DACs and a mixer.
6200 * Each ADC is connected from a mixer of all inputs. This makes possible
6201 * 6-channel independent captures.
6203 * In addition, an independent DAC for the multi-playback (not used in this
6206 #define ALC882_DIGOUT_NID 0x06
6207 #define ALC882_DIGIN_NID 0x0a
6209 static struct hda_channel_mode alc882_ch_modes[1] = {
6213 static hda_nid_t alc882_dac_nids[4] = {
6214 /* front, rear, clfe, rear_surr */
6215 0x02, 0x03, 0x04, 0x05
6218 /* identical with ALC880 */
6219 #define alc882_adc_nids alc880_adc_nids
6220 #define alc882_adc_nids_alt alc880_adc_nids_alt
6222 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6223 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6226 /* FIXME: should be a matrix-type input source selection */
6228 static struct hda_input_mux alc882_capture_source = {
6232 { "Front Mic", 0x1 },
6238 static struct hda_input_mux mb5_capture_source = {
6250 static struct hda_verb alc882_3ST_ch2_init[] = {
6251 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6252 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6253 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6254 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6261 static struct hda_verb alc882_3ST_ch6_init[] = {
6262 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6263 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6264 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6265 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6266 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6267 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6271 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6272 { 2, alc882_3ST_ch2_init },
6273 { 6, alc882_3ST_ch6_init },
6279 static struct hda_verb alc882_sixstack_ch6_init[] = {
6280 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6281 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6282 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6283 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6290 static struct hda_verb alc882_sixstack_ch8_init[] = {
6291 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6292 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6293 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6294 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6298 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6299 { 6, alc882_sixstack_ch6_init },
6300 { 8, alc882_sixstack_ch8_init },
6304 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6310 static struct hda_verb alc885_mbp_ch2_init[] = {
6311 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6312 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6313 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6320 static struct hda_verb alc885_mbp_ch6_init[] = {
6321 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6322 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6323 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6324 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6325 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6329 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6330 { 2, alc885_mbp_ch2_init },
6331 { 6, alc885_mbp_ch6_init },
6336 * Speakers/Woofer/HP = Front
6339 static struct hda_verb alc885_mb5_ch2_init[] = {
6340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6341 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6347 * Speakers/HP = Front
6351 static struct hda_verb alc885_mb5_ch6_init[] = {
6352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6353 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6354 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6358 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6359 { 2, alc885_mb5_ch2_init },
6360 { 6, alc885_mb5_ch6_init },
6363 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6364 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6366 static struct snd_kcontrol_new alc882_base_mixer[] = {
6367 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6368 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6369 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6370 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6371 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6372 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6373 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6374 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6375 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6376 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6377 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6391 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6392 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6393 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6394 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6395 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6396 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6397 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6399 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6400 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6401 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6405 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6406 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6407 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6408 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6409 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6410 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6411 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6412 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6413 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
6414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6415 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6417 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6418 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6419 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6423 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6424 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6425 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6426 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6427 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6436 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6437 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6438 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6439 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6440 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6441 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6442 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6443 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6444 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6445 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6446 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6447 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6448 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6449 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6453 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6454 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6456 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6457 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6458 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6459 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6460 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6461 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6462 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6463 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6464 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6465 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6466 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6469 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6473 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6475 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6476 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6477 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6478 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6479 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6480 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6481 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6482 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6483 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6487 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6490 .name = "Channel Mode",
6491 .info = alc_ch_mode_info,
6492 .get = alc_ch_mode_get,
6493 .put = alc_ch_mode_put,
6498 static struct hda_verb alc882_init_verbs[] = {
6499 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6500 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6513 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6516 /* Front Pin: output 0 (0x0c) */
6517 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6518 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6519 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6520 /* Rear Pin: output 1 (0x0d) */
6521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6522 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6523 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6524 /* CLFE Pin: output 2 (0x0e) */
6525 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6526 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6527 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6528 /* Side Pin: output 3 (0x0f) */
6529 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6530 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6531 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6532 /* Mic (rear) pin: input vref at 80% */
6533 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6535 /* Front Mic pin: input vref at 80% */
6536 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6537 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6538 /* Line In pin: input */
6539 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6540 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6541 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6542 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6543 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6544 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6545 /* CD pin widget for input */
6546 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6548 /* FIXME: use matrix-type input source selection */
6549 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6550 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6556 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6557 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6561 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6562 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6565 /* ADC1: mute amp left and right */
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6568 /* ADC2: mute amp left and right */
6569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6570 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6571 /* ADC3: mute amp left and right */
6572 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6573 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6578 static struct hda_verb alc882_eapd_verbs[] = {
6579 /* change to EAPD mode */
6580 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6581 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6586 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6587 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6588 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6589 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6592 /* FIXME: this looks suspicious...
6593 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6594 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6599 static struct hda_verb alc882_macpro_init_verbs[] = {
6600 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6604 /* Front Pin: output 0 (0x0c) */
6605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6606 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6607 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6608 /* Front Mic pin: input vref at 80% */
6609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6611 /* Speaker: output */
6612 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6613 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6614 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6615 /* Headphone output (output 0 - 0x0c) */
6616 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6617 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6618 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6620 /* FIXME: use matrix-type input source selection */
6621 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6622 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6623 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6624 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6625 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6626 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6629 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6630 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6631 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6634 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6635 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6636 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6637 /* ADC1: mute amp left and right */
6638 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6640 /* ADC2: mute amp left and right */
6641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6642 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6643 /* ADC3: mute amp left and right */
6644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6645 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6651 static struct hda_verb alc885_mb5_init_verbs[] = {
6653 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6654 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6655 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6656 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6661 /* Surround mixer */
6662 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6663 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6666 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6670 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6671 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6673 /* Front Pin (0x0c) */
6674 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6675 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6676 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6677 /* LFE Pin (0x0e) */
6678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6680 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
6682 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6683 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6684 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
6685 /* Front Mic pin: input vref at 80% */
6686 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6687 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6699 /* Macbook Pro rev3 */
6700 static struct hda_verb alc885_mbp3_init_verbs[] = {
6701 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6706 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6707 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6709 /* Front Pin: output 0 (0x0c) */
6710 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6713 /* HP Pin: output 0 (0x0d) */
6714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6715 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6716 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6717 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6718 /* Mic (rear) pin: input vref at 80% */
6719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6721 /* Front Mic pin: input vref at 80% */
6722 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6723 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6724 /* Line In pin: use output 1 when in LineOut mode */
6725 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6726 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6727 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6729 /* FIXME: use matrix-type input source selection */
6730 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6731 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6732 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6733 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6737 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6738 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6739 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6740 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6742 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6743 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6744 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6745 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6746 /* ADC1: mute amp left and right */
6747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6748 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6749 /* ADC2: mute amp left and right */
6750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6751 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6752 /* ADC3: mute amp left and right */
6753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6754 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6759 /* iMac 24 mixer. */
6760 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6761 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6762 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6766 /* iMac 24 init verbs. */
6767 static struct hda_verb alc885_imac24_init_verbs[] = {
6768 /* Internal speakers: output 0 (0x0c) */
6769 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6771 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6772 /* Internal speakers: output 0 (0x0c) */
6773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6774 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6775 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6776 /* Headphone: output 0 (0x0c) */
6777 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6779 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6780 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6781 /* Front Mic: input vref at 80% */
6782 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6783 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6787 /* Toggle speaker-output according to the hp-jack state */
6788 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6790 struct alc_spec *spec = codec->spec;
6792 spec->autocfg.hp_pins[0] = 0x14;
6793 spec->autocfg.speaker_pins[0] = 0x18;
6794 spec->autocfg.speaker_pins[1] = 0x1a;
6795 alc_automute_amp(codec);
6798 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6800 struct alc_spec *spec = codec->spec;
6802 spec->autocfg.hp_pins[0] = 0x15;
6803 spec->autocfg.speaker_pins[0] = 0x14;
6804 alc_automute_amp(codec);
6808 static struct hda_verb alc882_targa_verbs[] = {
6809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6813 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6815 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6816 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6817 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6819 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6820 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6821 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6822 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6826 /* toggle speaker-output according to the hp-jack state */
6827 static void alc882_targa_automute(struct hda_codec *codec)
6829 struct alc_spec *spec = codec->spec;
6830 alc_automute_amp(codec);
6831 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6832 spec->jack_present ? 1 : 3);
6835 static void alc882_targa_init_hook(struct hda_codec *codec)
6837 struct alc_spec *spec = codec->spec;
6839 spec->autocfg.hp_pins[0] = 0x14;
6840 spec->autocfg.speaker_pins[0] = 0x1b;
6841 alc882_targa_automute(codec);
6844 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6846 if ((res >> 26) == ALC880_HP_EVENT)
6847 alc882_targa_automute(codec);
6850 static struct hda_verb alc882_asus_a7j_verbs[] = {
6851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6856 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6858 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6860 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6862 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6863 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6864 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6868 static struct hda_verb alc882_asus_a7m_verbs[] = {
6869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6870 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6874 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6876 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6878 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6880 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6881 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6882 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6886 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6888 unsigned int gpiostate, gpiomask, gpiodir;
6890 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6891 AC_VERB_GET_GPIO_DATA, 0);
6894 gpiostate |= (1 << pin);
6896 gpiostate &= ~(1 << pin);
6898 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6899 AC_VERB_GET_GPIO_MASK, 0);
6900 gpiomask |= (1 << pin);
6902 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6903 AC_VERB_GET_GPIO_DIRECTION, 0);
6904 gpiodir |= (1 << pin);
6907 snd_hda_codec_write(codec, codec->afg, 0,
6908 AC_VERB_SET_GPIO_MASK, gpiomask);
6909 snd_hda_codec_write(codec, codec->afg, 0,
6910 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6914 snd_hda_codec_write(codec, codec->afg, 0,
6915 AC_VERB_SET_GPIO_DATA, gpiostate);
6918 /* set up GPIO at initialization */
6919 static void alc885_macpro_init_hook(struct hda_codec *codec)
6921 alc882_gpio_mute(codec, 0, 0);
6922 alc882_gpio_mute(codec, 1, 0);
6925 /* set up GPIO and update auto-muting at initialization */
6926 static void alc885_imac24_init_hook(struct hda_codec *codec)
6928 alc885_macpro_init_hook(codec);
6929 alc885_imac24_automute_init_hook(codec);
6933 * generic initialization of ADC, input mixers and output mixers
6935 static struct hda_verb alc882_auto_init_verbs[] = {
6937 * Unmute ADC0-2 and set the default input to mic-in
6939 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6941 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6942 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6943 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6944 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6946 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6948 * Note: PASD motherboards uses the Line In 2 as the input for
6949 * front panel mic (mic 2)
6951 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6952 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6959 * Set up output mixers (0x0c - 0x0f)
6961 /* set vol=0 to output mixers */
6962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6963 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6965 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6966 /* set up input amps for analog loopback */
6967 /* Amp Indices: DAC = 0, mixer = 1 */
6968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6969 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6970 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6971 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6972 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6973 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6974 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6975 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6976 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6977 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6979 /* FIXME: use matrix-type input source selection */
6980 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6981 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6982 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6983 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6987 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6988 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6989 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6990 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7000 #ifdef CONFIG_SND_HDA_POWER_SAVE
7001 #define alc882_loopbacks alc880_loopbacks
7004 /* pcm configuration: identiacal with ALC880 */
7005 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
7006 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
7007 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
7008 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
7011 * configuration and preset
7013 static const char *alc882_models[ALC882_MODEL_LAST] = {
7014 [ALC882_3ST_DIG] = "3stack-dig",
7015 [ALC882_6ST_DIG] = "6stack-dig",
7016 [ALC882_ARIMA] = "arima",
7017 [ALC882_W2JC] = "w2jc",
7018 [ALC882_TARGA] = "targa",
7019 [ALC882_ASUS_A7J] = "asus-a7j",
7020 [ALC882_ASUS_A7M] = "asus-a7m",
7021 [ALC885_MACPRO] = "macpro",
7022 [ALC885_MB5] = "mb5",
7023 [ALC885_MBP3] = "mbp3",
7024 [ALC885_IMAC24] = "imac24",
7025 [ALC882_AUTO] = "auto",
7028 static struct snd_pci_quirk alc882_cfg_tbl[] = {
7029 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
7030 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
7031 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
7032 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
7033 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
7034 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7035 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
7036 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
7037 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
7038 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
7039 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
7040 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
7044 static struct alc_config_preset alc882_presets[] = {
7045 [ALC882_3ST_DIG] = {
7046 .mixers = { alc882_base_mixer },
7047 .init_verbs = { alc882_init_verbs },
7048 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7049 .dac_nids = alc882_dac_nids,
7050 .dig_out_nid = ALC882_DIGOUT_NID,
7051 .dig_in_nid = ALC882_DIGIN_NID,
7052 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7053 .channel_mode = alc882_ch_modes,
7055 .input_mux = &alc882_capture_source,
7057 [ALC882_6ST_DIG] = {
7058 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7059 .init_verbs = { alc882_init_verbs },
7060 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7061 .dac_nids = alc882_dac_nids,
7062 .dig_out_nid = ALC882_DIGOUT_NID,
7063 .dig_in_nid = ALC882_DIGIN_NID,
7064 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7065 .channel_mode = alc882_sixstack_modes,
7066 .input_mux = &alc882_capture_source,
7069 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7070 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7071 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7072 .dac_nids = alc882_dac_nids,
7073 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7074 .channel_mode = alc882_sixstack_modes,
7075 .input_mux = &alc882_capture_source,
7078 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7079 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7080 alc880_gpio1_init_verbs },
7081 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7082 .dac_nids = alc882_dac_nids,
7083 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7084 .channel_mode = alc880_threestack_modes,
7086 .input_mux = &alc882_capture_source,
7087 .dig_out_nid = ALC882_DIGOUT_NID,
7090 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7091 .init_verbs = { alc885_mbp3_init_verbs,
7092 alc880_gpio1_init_verbs },
7093 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7094 .dac_nids = alc882_dac_nids,
7095 .channel_mode = alc885_mbp_6ch_modes,
7096 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7097 .input_mux = &alc882_capture_source,
7098 .dig_out_nid = ALC882_DIGOUT_NID,
7099 .dig_in_nid = ALC882_DIGIN_NID,
7100 .unsol_event = alc_automute_amp_unsol_event,
7101 .init_hook = alc885_mbp3_init_hook,
7104 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7105 .init_verbs = { alc885_mb5_init_verbs,
7106 alc880_gpio1_init_verbs },
7107 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7108 .dac_nids = alc882_dac_nids,
7109 .channel_mode = alc885_mb5_6ch_modes,
7110 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7111 .input_mux = &mb5_capture_source,
7112 .dig_out_nid = ALC882_DIGOUT_NID,
7113 .dig_in_nid = ALC882_DIGIN_NID,
7116 .mixers = { alc882_macpro_mixer },
7117 .init_verbs = { alc882_macpro_init_verbs },
7118 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7119 .dac_nids = alc882_dac_nids,
7120 .dig_out_nid = ALC882_DIGOUT_NID,
7121 .dig_in_nid = ALC882_DIGIN_NID,
7122 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7123 .channel_mode = alc882_ch_modes,
7124 .input_mux = &alc882_capture_source,
7125 .init_hook = alc885_macpro_init_hook,
7128 .mixers = { alc885_imac24_mixer },
7129 .init_verbs = { alc885_imac24_init_verbs },
7130 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7131 .dac_nids = alc882_dac_nids,
7132 .dig_out_nid = ALC882_DIGOUT_NID,
7133 .dig_in_nid = ALC882_DIGIN_NID,
7134 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7135 .channel_mode = alc882_ch_modes,
7136 .input_mux = &alc882_capture_source,
7137 .unsol_event = alc_automute_amp_unsol_event,
7138 .init_hook = alc885_imac24_init_hook,
7141 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7142 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7143 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7144 .dac_nids = alc882_dac_nids,
7145 .dig_out_nid = ALC882_DIGOUT_NID,
7146 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7147 .adc_nids = alc882_adc_nids,
7148 .capsrc_nids = alc882_capsrc_nids,
7149 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7150 .channel_mode = alc882_3ST_6ch_modes,
7152 .input_mux = &alc882_capture_source,
7153 .unsol_event = alc882_targa_unsol_event,
7154 .init_hook = alc882_targa_init_hook,
7156 [ALC882_ASUS_A7J] = {
7157 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7158 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7159 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7160 .dac_nids = alc882_dac_nids,
7161 .dig_out_nid = ALC882_DIGOUT_NID,
7162 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7163 .adc_nids = alc882_adc_nids,
7164 .capsrc_nids = alc882_capsrc_nids,
7165 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7166 .channel_mode = alc882_3ST_6ch_modes,
7168 .input_mux = &alc882_capture_source,
7170 [ALC882_ASUS_A7M] = {
7171 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7172 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7173 alc880_gpio1_init_verbs,
7174 alc882_asus_a7m_verbs },
7175 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7176 .dac_nids = alc882_dac_nids,
7177 .dig_out_nid = ALC882_DIGOUT_NID,
7178 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7179 .channel_mode = alc880_threestack_modes,
7181 .input_mux = &alc882_capture_source,
7190 PINFIX_ABIT_AW9D_MAX
7193 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7194 { 0x15, 0x01080104 }, /* side */
7195 { 0x16, 0x01011012 }, /* rear */
7196 { 0x17, 0x01016011 }, /* clfe */
7200 static const struct alc_pincfg *alc882_pin_fixes[] = {
7201 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7204 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7205 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7210 * BIOS auto configuration
7212 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7213 hda_nid_t nid, int pin_type,
7217 struct alc_spec *spec = codec->spec;
7220 alc_set_pin_output(codec, nid, pin_type);
7221 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7224 idx = spec->multiout.dac_nids[dac_idx] - 2;
7225 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7229 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7231 struct alc_spec *spec = codec->spec;
7234 for (i = 0; i <= HDA_SIDE; i++) {
7235 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7236 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7238 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7243 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7245 struct alc_spec *spec = codec->spec;
7248 pin = spec->autocfg.hp_pins[0];
7249 if (pin) /* connect to front */
7251 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7252 pin = spec->autocfg.speaker_pins[0];
7254 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7257 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7258 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7260 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7262 struct alc_spec *spec = codec->spec;
7265 for (i = 0; i < AUTO_PIN_LAST; i++) {
7266 hda_nid_t nid = spec->autocfg.input_pins[i];
7269 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7270 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7271 snd_hda_codec_write(codec, nid, 0,
7272 AC_VERB_SET_AMP_GAIN_MUTE,
7277 static void alc882_auto_init_input_src(struct hda_codec *codec)
7279 struct alc_spec *spec = codec->spec;
7282 for (c = 0; c < spec->num_adc_nids; c++) {
7283 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7284 hda_nid_t nid = spec->capsrc_nids[c];
7285 unsigned int mux_idx;
7286 const struct hda_input_mux *imux;
7287 int conns, mute, idx, item;
7289 conns = snd_hda_get_connections(codec, nid, conn_list,
7290 ARRAY_SIZE(conn_list));
7293 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7294 imux = &spec->input_mux[mux_idx];
7295 for (idx = 0; idx < conns; idx++) {
7296 /* if the current connection is the selected one,
7297 * unmute it as default - otherwise mute it
7299 mute = AMP_IN_MUTE(idx);
7300 for (item = 0; item < imux->num_items; item++) {
7301 if (imux->items[item].index == idx) {
7302 if (spec->cur_mux[c] == item)
7303 mute = AMP_IN_UNMUTE(idx);
7307 /* check if we have a selector or mixer
7308 * we could check for the widget type instead, but
7309 * just check for Amp-In presence (in case of mixer
7310 * without amp-in there is something wrong, this
7311 * function shouldn't be used or capsrc nid is wrong)
7313 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7314 snd_hda_codec_write(codec, nid, 0,
7315 AC_VERB_SET_AMP_GAIN_MUTE,
7317 else if (mute != AMP_IN_MUTE(idx))
7318 snd_hda_codec_write(codec, nid, 0,
7319 AC_VERB_SET_CONNECT_SEL,
7325 /* add mic boosts if needed */
7326 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7328 struct alc_spec *spec = codec->spec;
7332 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7333 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7334 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7336 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7340 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7341 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7342 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7344 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7351 /* almost identical with ALC880 parser... */
7352 static int alc882_parse_auto_config(struct hda_codec *codec)
7354 struct alc_spec *spec = codec->spec;
7355 int err = alc880_parse_auto_config(codec);
7360 return 0; /* no config found */
7362 err = alc_auto_add_mic_boost(codec);
7366 /* hack - override the init verbs */
7367 spec->init_verbs[0] = alc882_auto_init_verbs;
7369 return 1; /* config found */
7372 /* additional initialization for auto-configuration model */
7373 static void alc882_auto_init(struct hda_codec *codec)
7375 struct alc_spec *spec = codec->spec;
7376 alc882_auto_init_multi_out(codec);
7377 alc882_auto_init_hp_out(codec);
7378 alc882_auto_init_analog_input(codec);
7379 alc882_auto_init_input_src(codec);
7380 if (spec->unsol_event)
7381 alc_inithook(codec);
7384 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7386 static int patch_alc882(struct hda_codec *codec)
7388 struct alc_spec *spec;
7389 int err, board_config;
7391 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7397 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7401 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7402 /* Pick up systems that don't supply PCI SSID */
7403 switch (codec->subsystem_id) {
7404 case 0x106b0c00: /* Mac Pro */
7405 board_config = ALC885_MACPRO;
7407 case 0x106b1000: /* iMac 24 */
7408 case 0x106b2800: /* AppleTV */
7409 case 0x106b3e00: /* iMac 24 Aluminium */
7410 board_config = ALC885_IMAC24;
7412 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7413 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7414 case 0x106b00a4: /* MacbookPro4,1 */
7415 case 0x106b2c00: /* Macbook Pro rev3 */
7416 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7417 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7418 board_config = ALC885_MBP3;
7420 case 0x106b3f00: /* Macbook 5,1 */
7421 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7422 * seems not working, so apparently
7423 * no perfect solution yet
7425 board_config = ALC885_MB5;
7428 /* ALC889A is handled better as ALC888-compatible */
7429 if (codec->revision_id == 0x100101 ||
7430 codec->revision_id == 0x100103) {
7432 return patch_alc883(codec);
7434 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7435 "trying auto-probe from BIOS...\n",
7437 board_config = ALC882_AUTO;
7441 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7443 if (board_config == ALC882_AUTO) {
7444 /* automatic parse from the BIOS config */
7445 err = alc882_parse_auto_config(codec);
7451 "hda_codec: Cannot set up configuration "
7452 "from BIOS. Using base mode...\n");
7453 board_config = ALC882_3ST_DIG;
7457 err = snd_hda_attach_beep_device(codec, 0x1);
7463 if (board_config != ALC882_AUTO)
7464 setup_preset(spec, &alc882_presets[board_config]);
7466 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7467 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7468 /* FIXME: setup DAC5 */
7469 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7470 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7472 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7473 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7475 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7476 if (!spec->adc_nids && spec->input_mux) {
7477 /* check whether NID 0x07 is valid */
7478 unsigned int wcap = get_wcaps(codec, 0x07);
7480 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7481 if (wcap != AC_WID_AUD_IN) {
7482 spec->adc_nids = alc882_adc_nids_alt;
7483 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7484 spec->capsrc_nids = alc882_capsrc_nids_alt;
7486 spec->adc_nids = alc882_adc_nids;
7487 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7488 spec->capsrc_nids = alc882_capsrc_nids;
7491 set_capture_mixer(spec);
7492 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7494 spec->vmaster_nid = 0x0c;
7496 codec->patch_ops = alc_patch_ops;
7497 if (board_config == ALC882_AUTO)
7498 spec->init_hook = alc882_auto_init;
7499 #ifdef CONFIG_SND_HDA_POWER_SAVE
7500 if (!spec->loopback.amplist)
7501 spec->loopback.amplist = alc882_loopbacks;
7503 codec->proc_widget_hook = print_realtek_coef;
7511 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7512 * configuration. Each pin widget can choose any input DACs and a mixer.
7513 * Each ADC is connected from a mixer of all inputs. This makes possible
7514 * 6-channel independent captures.
7516 * In addition, an independent DAC for the multi-playback (not used in this
7519 #define ALC883_DIGOUT_NID 0x06
7520 #define ALC883_DIGIN_NID 0x0a
7522 #define ALC1200_DIGOUT_NID 0x10
7524 static hda_nid_t alc883_dac_nids[4] = {
7525 /* front, rear, clfe, rear_surr */
7526 0x02, 0x03, 0x04, 0x05
7529 static hda_nid_t alc883_adc_nids[2] = {
7534 static hda_nid_t alc883_adc_nids_alt[1] = {
7539 static hda_nid_t alc883_adc_nids_rev[2] = {
7544 #define alc889_adc_nids alc880_adc_nids
7546 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7548 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7550 #define alc889_capsrc_nids alc882_capsrc_nids
7553 /* FIXME: should be a matrix-type input source selection */
7555 static struct hda_input_mux alc883_capture_source = {
7559 { "Front Mic", 0x1 },
7565 static struct hda_input_mux alc883_3stack_6ch_intel = {
7569 { "Front Mic", 0x0 },
7575 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7583 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7593 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7601 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7605 { "Front Mic", 0x1 },
7610 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7618 static struct hda_input_mux alc889A_mb31_capture_source = {
7622 /* Front Mic (0x01) unused */
7624 /* Line 2 (0x03) unused */
7625 /* CD (0x04) unsused? */
7632 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7639 static struct hda_verb alc883_3ST_ch2_init[] = {
7640 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7641 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7642 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7643 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7650 static struct hda_verb alc883_3ST_ch4_init[] = {
7651 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7652 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7653 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7654 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7655 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7662 static struct hda_verb alc883_3ST_ch6_init[] = {
7663 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7664 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7665 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7666 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7667 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7668 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7672 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7673 { 2, alc883_3ST_ch2_init },
7674 { 4, alc883_3ST_ch4_init },
7675 { 6, alc883_3ST_ch6_init },
7681 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7682 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7683 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7684 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7685 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7692 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7693 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7694 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7695 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7696 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7697 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7704 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7705 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7706 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7707 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7710 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7714 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7715 { 2, alc883_3ST_ch2_intel_init },
7716 { 4, alc883_3ST_ch4_intel_init },
7717 { 6, alc883_3ST_ch6_intel_init },
7723 static struct hda_verb alc883_sixstack_ch6_init[] = {
7724 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7725 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7726 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7727 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7734 static struct hda_verb alc883_sixstack_ch8_init[] = {
7735 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7736 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7737 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7738 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7743 { 6, alc883_sixstack_ch6_init },
7744 { 8, alc883_sixstack_ch8_init },
7747 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7748 static struct hda_verb alc889A_mb31_ch2_init[] = {
7749 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7750 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7756 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7757 static struct hda_verb alc889A_mb31_ch4_init[] = {
7758 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7759 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7760 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7765 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7766 static struct hda_verb alc889A_mb31_ch5_init[] = {
7767 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7769 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7770 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7774 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7775 static struct hda_verb alc889A_mb31_ch6_init[] = {
7776 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7777 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7778 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7779 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7783 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7784 { 2, alc889A_mb31_ch2_init },
7785 { 4, alc889A_mb31_ch4_init },
7786 { 5, alc889A_mb31_ch5_init },
7787 { 6, alc889A_mb31_ch6_init },
7790 static struct hda_verb alc883_medion_eapd_verbs[] = {
7791 /* eanable EAPD on medion laptop */
7792 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7793 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7797 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7798 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7801 static struct snd_kcontrol_new alc883_base_mixer[] = {
7802 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7803 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7804 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7805 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7806 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7807 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7808 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7809 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7810 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7811 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7812 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7820 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7821 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7822 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7826 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7829 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7830 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7831 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7832 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7838 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7839 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7843 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7844 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7845 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7846 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7847 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7850 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7851 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7853 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7857 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7858 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7859 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7860 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7861 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7863 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7864 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7865 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7866 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7867 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7871 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7872 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7873 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7874 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7875 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7876 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7877 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7878 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7880 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7882 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7883 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7884 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7888 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7889 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7890 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7891 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7892 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7893 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7894 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7895 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7896 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7903 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7905 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7906 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7911 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7912 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7913 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7914 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7915 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7916 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7918 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7919 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7920 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7921 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7922 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7923 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7924 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7925 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7926 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7927 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7928 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7929 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7930 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7931 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7935 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7936 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7937 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7939 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7940 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7941 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7942 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7943 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7944 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7945 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7946 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7947 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7948 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7950 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7952 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7953 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7954 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7958 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7961 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7965 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7966 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7967 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7968 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7969 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7970 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7971 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7973 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7974 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7978 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7981 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7982 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7983 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7985 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7987 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7989 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7993 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7994 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7995 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7996 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7997 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7998 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7999 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8000 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8005 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8007 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8008 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8009 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8010 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8013 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8014 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8018 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8019 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8020 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8021 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8022 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8023 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8027 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8031 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8032 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8033 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8035 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8036 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8038 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8043 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8044 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8045 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8046 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8047 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8048 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8049 0x0d, 1, 0x0, HDA_OUTPUT),
8050 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8051 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8052 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8053 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8054 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8055 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8056 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8057 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8058 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8060 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8062 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8063 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8064 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8068 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8070 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8071 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8072 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8073 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8074 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8076 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8077 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8078 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8079 /* Output switches */
8080 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8081 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8082 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8085 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8087 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8088 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8090 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8094 static struct hda_bind_ctls alc883_bind_cap_vol = {
8095 .ops = &snd_hda_bind_vol,
8097 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8098 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8103 static struct hda_bind_ctls alc883_bind_cap_switch = {
8104 .ops = &snd_hda_bind_sw,
8106 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8107 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8112 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8113 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8114 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8116 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8117 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8118 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8119 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8124 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8125 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8126 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8129 /* .name = "Capture Source", */
8130 .name = "Input Source",
8132 .info = alc_mux_enum_info,
8133 .get = alc_mux_enum_get,
8134 .put = alc_mux_enum_put,
8139 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8142 .name = "Channel Mode",
8143 .info = alc_ch_mode_info,
8144 .get = alc_ch_mode_get,
8145 .put = alc_ch_mode_put,
8150 static struct hda_verb alc883_init_verbs[] = {
8151 /* ADC1: mute amp left and right */
8152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8153 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8154 /* ADC2: mute amp left and right */
8155 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8157 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8158 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8159 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8160 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8162 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8164 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8166 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8167 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8168 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8170 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8171 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8172 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8174 /* mute analog input loopbacks */
8175 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8176 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8177 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8178 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8179 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8181 /* Front Pin: output 0 (0x0c) */
8182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8183 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8184 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8185 /* Rear Pin: output 1 (0x0d) */
8186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8188 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8189 /* CLFE Pin: output 2 (0x0e) */
8190 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8191 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8192 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8193 /* Side Pin: output 3 (0x0f) */
8194 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8195 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8196 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8197 /* Mic (rear) pin: input vref at 80% */
8198 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8200 /* Front Mic pin: input vref at 80% */
8201 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8202 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8203 /* Line In pin: input */
8204 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8206 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8207 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8208 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8209 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8210 /* CD pin widget for input */
8211 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8213 /* FIXME: use matrix-type input source selection */
8214 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8228 /* toggle speaker-output according to the hp-jack state */
8229 static void alc883_mitac_init_hook(struct hda_codec *codec)
8231 struct alc_spec *spec = codec->spec;
8233 spec->autocfg.hp_pins[0] = 0x15;
8234 spec->autocfg.speaker_pins[0] = 0x14;
8235 spec->autocfg.speaker_pins[1] = 0x17;
8236 alc_automute_amp(codec);
8239 /* auto-toggle front mic */
8241 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8243 unsigned int present;
8246 present = snd_hda_codec_read(codec, 0x18, 0,
8247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8248 bits = present ? HDA_AMP_MUTE : 0;
8249 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8253 static struct hda_verb alc883_mitac_verbs[] = {
8255 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8258 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8259 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8261 /* enable unsolicited event */
8262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8263 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8268 static struct hda_verb alc883_clevo_m720_verbs[] = {
8270 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8276 /* enable unsolicited event */
8277 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8278 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8283 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8285 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8291 /* enable unsolicited event */
8292 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8297 static struct hda_verb alc883_tagra_verbs[] = {
8298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8299 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8302 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8304 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8305 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8306 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8308 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8309 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8310 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8311 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8316 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8318 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8319 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8323 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8324 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8326 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8331 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8334 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8335 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8336 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8340 static struct hda_verb alc883_haier_w66_verbs[] = {
8341 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8346 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8348 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8349 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8353 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8356 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8359 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8360 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8361 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8365 static struct hda_verb alc888_6st_dell_verbs[] = {
8366 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8370 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8372 struct alc_spec *spec = codec->spec;
8374 spec->autocfg.hp_pins[0] = 0x1b;
8375 spec->autocfg.speaker_pins[0] = 0x14;
8376 spec->autocfg.speaker_pins[1] = 0x16;
8377 spec->autocfg.speaker_pins[2] = 0x18;
8378 alc_automute_amp(codec);
8381 static struct hda_verb alc888_3st_hp_verbs[] = {
8382 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8383 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8384 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8385 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8392 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8393 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8394 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8395 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8396 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8403 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8404 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8405 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8406 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8407 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8408 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8415 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8416 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8417 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8418 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8419 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8420 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8421 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8425 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8426 { 2, alc888_3st_hp_2ch_init },
8427 { 4, alc888_3st_hp_4ch_init },
8428 { 6, alc888_3st_hp_6ch_init },
8431 /* toggle front-jack and RCA according to the hp-jack state */
8432 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8434 unsigned int present;
8436 present = snd_hda_codec_read(codec, 0x1b, 0,
8437 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8438 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8439 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8440 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8441 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8444 /* toggle RCA according to the front-jack state */
8445 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8447 unsigned int present;
8449 present = snd_hda_codec_read(codec, 0x14, 0,
8450 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8451 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8452 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8455 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8458 if ((res >> 26) == ALC880_HP_EVENT)
8459 alc888_lenovo_ms7195_front_automute(codec);
8460 if ((res >> 26) == ALC880_FRONT_EVENT)
8461 alc888_lenovo_ms7195_rca_automute(codec);
8464 static struct hda_verb alc883_medion_md2_verbs[] = {
8465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8470 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8474 /* toggle speaker-output according to the hp-jack state */
8475 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8477 struct alc_spec *spec = codec->spec;
8479 spec->autocfg.hp_pins[0] = 0x14;
8480 spec->autocfg.speaker_pins[0] = 0x15;
8481 alc_automute_amp(codec);
8484 /* toggle speaker-output according to the hp-jack state */
8485 #define alc883_tagra_init_hook alc882_targa_init_hook
8486 #define alc883_tagra_unsol_event alc882_targa_unsol_event
8488 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8490 unsigned int present;
8492 present = snd_hda_codec_read(codec, 0x18, 0,
8493 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8494 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8495 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8498 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8500 struct alc_spec *spec = codec->spec;
8502 spec->autocfg.hp_pins[0] = 0x15;
8503 spec->autocfg.speaker_pins[0] = 0x14;
8504 alc_automute_amp(codec);
8505 alc883_clevo_m720_mic_automute(codec);
8508 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8511 switch (res >> 26) {
8512 case ALC880_MIC_EVENT:
8513 alc883_clevo_m720_mic_automute(codec);
8516 alc_automute_amp_unsol_event(codec, res);
8521 /* toggle speaker-output according to the hp-jack state */
8522 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8524 struct alc_spec *spec = codec->spec;
8526 spec->autocfg.hp_pins[0] = 0x14;
8527 spec->autocfg.speaker_pins[0] = 0x15;
8528 alc_automute_amp(codec);
8531 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8533 struct alc_spec *spec = codec->spec;
8535 spec->autocfg.hp_pins[0] = 0x1b;
8536 spec->autocfg.speaker_pins[0] = 0x14;
8537 alc_automute_amp(codec);
8540 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8542 unsigned int present;
8545 present = snd_hda_codec_read(codec, 0x14, 0,
8546 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8547 bits = present ? HDA_AMP_MUTE : 0;
8548 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8549 HDA_AMP_MUTE, bits);
8552 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8554 unsigned int present;
8557 present = snd_hda_codec_read(codec, 0x1b, 0,
8558 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8559 bits = present ? HDA_AMP_MUTE : 0;
8560 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8561 HDA_AMP_MUTE, bits);
8562 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8563 HDA_AMP_MUTE, bits);
8566 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8569 if ((res >> 26) == ALC880_HP_EVENT)
8570 alc883_lenovo_101e_all_automute(codec);
8571 if ((res >> 26) == ALC880_FRONT_EVENT)
8572 alc883_lenovo_101e_ispeaker_automute(codec);
8575 /* toggle speaker-output according to the hp-jack state */
8576 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8578 struct alc_spec *spec = codec->spec;
8580 spec->autocfg.hp_pins[0] = 0x14;
8581 spec->autocfg.speaker_pins[0] = 0x15;
8582 spec->autocfg.speaker_pins[1] = 0x16;
8583 alc_automute_amp(codec);
8586 static struct hda_verb alc883_acer_eapd_verbs[] = {
8587 /* HP Pin: output 0 (0x0c) */
8588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8590 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8591 /* Front Pin: output 0 (0x0c) */
8592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8593 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8595 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8596 /* eanable EAPD on medion laptop */
8597 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8598 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8599 /* enable unsolicited event */
8600 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8604 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8606 struct alc_spec *spec = codec->spec;
8608 spec->autocfg.hp_pins[0] = 0x1b;
8609 spec->autocfg.speaker_pins[0] = 0x14;
8610 spec->autocfg.speaker_pins[1] = 0x15;
8611 spec->autocfg.speaker_pins[2] = 0x16;
8612 spec->autocfg.speaker_pins[3] = 0x17;
8613 alc_automute_amp(codec);
8616 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8618 struct alc_spec *spec = codec->spec;
8620 spec->autocfg.hp_pins[0] = 0x1b;
8621 spec->autocfg.speaker_pins[0] = 0x14;
8622 spec->autocfg.speaker_pins[1] = 0x15;
8623 spec->autocfg.speaker_pins[2] = 0x16;
8624 spec->autocfg.speaker_pins[3] = 0x17;
8625 spec->autocfg.speaker_pins[4] = 0x1a;
8626 alc_automute_amp(codec);
8630 * generic initialization of ADC, input mixers and output mixers
8632 static struct hda_verb alc883_auto_init_verbs[] = {
8634 * Unmute ADC0-2 and set the default input to mic-in
8636 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8638 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8639 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8641 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8643 * Note: PASD motherboards uses the Line In 2 as the input for
8644 * front panel mic (mic 2)
8646 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8651 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8654 * Set up output mixers (0x0c - 0x0f)
8656 /* set vol=0 to output mixers */
8657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8658 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8659 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 /* set up input amps for analog loopback */
8662 /* Amp Indices: DAC = 0, mixer = 1 */
8663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8669 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8670 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8671 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8672 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8674 /* FIXME: use matrix-type input source selection */
8675 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8677 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8680 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8681 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8683 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8684 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8685 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8686 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8692 static struct hda_verb alc888_asus_m90v_verbs[] = {
8693 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8694 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8695 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8696 /* enable unsolicited event */
8697 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8698 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8702 static void alc883_nb_mic_automute(struct hda_codec *codec)
8704 unsigned int present;
8706 present = snd_hda_codec_read(codec, 0x18, 0,
8707 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8708 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8709 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8710 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8711 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8714 static void alc883_M90V_init_hook(struct hda_codec *codec)
8716 struct alc_spec *spec = codec->spec;
8718 spec->autocfg.hp_pins[0] = 0x1b;
8719 spec->autocfg.speaker_pins[0] = 0x14;
8720 spec->autocfg.speaker_pins[1] = 0x15;
8721 spec->autocfg.speaker_pins[2] = 0x16;
8722 alc_automute_pin(codec);
8725 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8728 switch (res >> 26) {
8729 case ALC880_MIC_EVENT:
8730 alc883_nb_mic_automute(codec);
8733 alc_sku_unsol_event(codec, res);
8738 static void alc883_mode2_inithook(struct hda_codec *codec)
8740 alc883_M90V_init_hook(codec);
8741 alc883_nb_mic_automute(codec);
8744 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8745 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8746 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8747 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8749 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8750 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8751 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8752 /* enable unsolicited event */
8753 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8757 static void alc883_eee1601_inithook(struct hda_codec *codec)
8759 struct alc_spec *spec = codec->spec;
8761 spec->autocfg.hp_pins[0] = 0x14;
8762 spec->autocfg.speaker_pins[0] = 0x1b;
8763 alc_automute_pin(codec);
8766 static struct hda_verb alc889A_mb31_verbs[] = {
8767 /* Init rear pin (used as headphone output) */
8768 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8769 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8770 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8771 /* Init line pin (used as output in 4ch and 6ch mode) */
8772 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8773 /* Init line 2 pin (used as headphone out by default) */
8774 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8775 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8779 /* Mute speakers according to the headphone jack state */
8780 static void alc889A_mb31_automute(struct hda_codec *codec)
8782 unsigned int present;
8784 /* Mute only in 2ch or 4ch mode */
8785 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8787 present = snd_hda_codec_read(codec, 0x15, 0,
8788 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8789 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8790 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8791 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8792 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8796 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8798 if ((res >> 26) == ALC880_HP_EVENT)
8799 alc889A_mb31_automute(codec);
8802 #ifdef CONFIG_SND_HDA_POWER_SAVE
8803 #define alc883_loopbacks alc880_loopbacks
8806 /* pcm configuration: identiacal with ALC880 */
8807 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8808 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8809 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8810 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8811 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8814 * configuration and preset
8816 static const char *alc883_models[ALC883_MODEL_LAST] = {
8817 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8818 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8819 [ALC883_3ST_6ch] = "3stack-6ch",
8820 [ALC883_6ST_DIG] = "6stack-dig",
8821 [ALC883_TARGA_DIG] = "targa-dig",
8822 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8823 [ALC883_ACER] = "acer",
8824 [ALC883_ACER_ASPIRE] = "acer-aspire",
8825 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8826 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8827 [ALC883_MEDION] = "medion",
8828 [ALC883_MEDION_MD2] = "medion-md2",
8829 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8830 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8831 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8832 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8833 [ALC888_LENOVO_SKY] = "lenovo-sky",
8834 [ALC883_HAIER_W66] = "haier-w66",
8835 [ALC888_3ST_HP] = "3stack-hp",
8836 [ALC888_6ST_DELL] = "6stack-dell",
8837 [ALC883_MITAC] = "mitac",
8838 [ALC883_CLEVO_M720] = "clevo-m720",
8839 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8840 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8841 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8842 [ALC1200_ASUS_P5Q] = "asus-p5q",
8843 [ALC889A_MB31] = "mb31",
8844 [ALC883_AUTO] = "auto",
8847 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8848 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8849 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8850 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8851 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8852 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8853 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8854 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8855 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8856 ALC888_ACER_ASPIRE_4930G),
8857 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8858 ALC888_ACER_ASPIRE_4930G),
8859 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8860 ALC888_ACER_ASPIRE_8930G),
8861 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8862 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8863 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8864 ALC888_ACER_ASPIRE_4930G),
8865 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8866 ALC888_ACER_ASPIRE_4930G),
8867 /* default Acer -- disabled as it causes more problems.
8868 * model=auto should work fine now
8870 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8871 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8872 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8873 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8874 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8875 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8876 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8877 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8878 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8879 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8880 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8881 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8882 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8883 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8884 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8885 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8886 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8887 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8888 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8889 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8890 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8891 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8892 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8893 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8894 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8895 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8896 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8897 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8898 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8899 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8900 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8901 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8902 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8903 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8904 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8905 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8906 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8907 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8908 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8909 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8910 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8911 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8912 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8913 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8914 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8915 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8916 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8917 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8918 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8919 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8920 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8921 ALC883_FUJITSU_PI2515),
8922 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8923 ALC888_FUJITSU_XA3530),
8924 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8925 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8926 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8927 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8928 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8929 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8930 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8931 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8932 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8933 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8934 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8935 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8936 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8937 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8941 static hda_nid_t alc883_slave_dig_outs[] = {
8942 ALC1200_DIGOUT_NID, 0,
8945 static hda_nid_t alc1200_slave_dig_outs[] = {
8946 ALC883_DIGOUT_NID, 0,
8949 static struct alc_config_preset alc883_presets[] = {
8950 [ALC883_3ST_2ch_DIG] = {
8951 .mixers = { alc883_3ST_2ch_mixer },
8952 .init_verbs = { alc883_init_verbs },
8953 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8954 .dac_nids = alc883_dac_nids,
8955 .dig_out_nid = ALC883_DIGOUT_NID,
8956 .dig_in_nid = ALC883_DIGIN_NID,
8957 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8958 .channel_mode = alc883_3ST_2ch_modes,
8959 .input_mux = &alc883_capture_source,
8961 [ALC883_3ST_6ch_DIG] = {
8962 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8963 .init_verbs = { alc883_init_verbs },
8964 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8965 .dac_nids = alc883_dac_nids,
8966 .dig_out_nid = ALC883_DIGOUT_NID,
8967 .dig_in_nid = ALC883_DIGIN_NID,
8968 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8969 .channel_mode = alc883_3ST_6ch_modes,
8971 .input_mux = &alc883_capture_source,
8973 [ALC883_3ST_6ch] = {
8974 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8975 .init_verbs = { alc883_init_verbs },
8976 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8977 .dac_nids = alc883_dac_nids,
8978 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8979 .channel_mode = alc883_3ST_6ch_modes,
8981 .input_mux = &alc883_capture_source,
8983 [ALC883_3ST_6ch_INTEL] = {
8984 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8985 .init_verbs = { alc883_init_verbs },
8986 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8987 .dac_nids = alc883_dac_nids,
8988 .dig_out_nid = ALC883_DIGOUT_NID,
8989 .dig_in_nid = ALC883_DIGIN_NID,
8990 .slave_dig_outs = alc883_slave_dig_outs,
8991 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8992 .channel_mode = alc883_3ST_6ch_intel_modes,
8994 .input_mux = &alc883_3stack_6ch_intel,
8996 [ALC883_6ST_DIG] = {
8997 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8998 .init_verbs = { alc883_init_verbs },
8999 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9000 .dac_nids = alc883_dac_nids,
9001 .dig_out_nid = ALC883_DIGOUT_NID,
9002 .dig_in_nid = ALC883_DIGIN_NID,
9003 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9004 .channel_mode = alc883_sixstack_modes,
9005 .input_mux = &alc883_capture_source,
9007 [ALC883_TARGA_DIG] = {
9008 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
9009 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
9010 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9011 .dac_nids = alc883_dac_nids,
9012 .dig_out_nid = ALC883_DIGOUT_NID,
9013 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9014 .channel_mode = alc883_3ST_6ch_modes,
9016 .input_mux = &alc883_capture_source,
9017 .unsol_event = alc883_tagra_unsol_event,
9018 .init_hook = alc883_tagra_init_hook,
9020 [ALC883_TARGA_2ch_DIG] = {
9021 .mixers = { alc883_tagra_2ch_mixer},
9022 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
9023 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9024 .dac_nids = alc883_dac_nids,
9025 .adc_nids = alc883_adc_nids_alt,
9026 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9027 .dig_out_nid = ALC883_DIGOUT_NID,
9028 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9029 .channel_mode = alc883_3ST_2ch_modes,
9030 .input_mux = &alc883_capture_source,
9031 .unsol_event = alc883_tagra_unsol_event,
9032 .init_hook = alc883_tagra_init_hook,
9035 .mixers = { alc883_base_mixer },
9036 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9037 * and the headphone jack. Turn this on and rely on the
9038 * standard mute methods whenever the user wants to turn
9039 * these outputs off.
9041 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9042 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9043 .dac_nids = alc883_dac_nids,
9044 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9045 .channel_mode = alc883_3ST_2ch_modes,
9046 .input_mux = &alc883_capture_source,
9048 [ALC883_ACER_ASPIRE] = {
9049 .mixers = { alc883_acer_aspire_mixer },
9050 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9051 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9052 .dac_nids = alc883_dac_nids,
9053 .dig_out_nid = ALC883_DIGOUT_NID,
9054 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9055 .channel_mode = alc883_3ST_2ch_modes,
9056 .input_mux = &alc883_capture_source,
9057 .unsol_event = alc_automute_amp_unsol_event,
9058 .init_hook = alc883_acer_aspire_init_hook,
9060 [ALC888_ACER_ASPIRE_4930G] = {
9061 .mixers = { alc888_base_mixer,
9062 alc883_chmode_mixer },
9063 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9064 alc888_acer_aspire_4930g_verbs },
9065 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9066 .dac_nids = alc883_dac_nids,
9067 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9068 .adc_nids = alc883_adc_nids_rev,
9069 .capsrc_nids = alc883_capsrc_nids_rev,
9070 .dig_out_nid = ALC883_DIGOUT_NID,
9071 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9072 .channel_mode = alc883_3ST_6ch_modes,
9075 ARRAY_SIZE(alc888_2_capture_sources),
9076 .input_mux = alc888_2_capture_sources,
9077 .unsol_event = alc_automute_amp_unsol_event,
9078 .init_hook = alc888_acer_aspire_4930g_init_hook,
9080 [ALC888_ACER_ASPIRE_8930G] = {
9081 .mixers = { alc888_base_mixer,
9082 alc883_chmode_mixer },
9083 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9084 alc888_acer_aspire_8930g_verbs },
9085 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9086 .dac_nids = alc883_dac_nids,
9087 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9088 .adc_nids = alc883_adc_nids_rev,
9089 .capsrc_nids = alc883_capsrc_nids_rev,
9090 .dig_out_nid = ALC883_DIGOUT_NID,
9091 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9092 .channel_mode = alc883_3ST_6ch_modes,
9094 .const_channel_count = 6,
9096 ARRAY_SIZE(alc888_2_capture_sources),
9097 .input_mux = alc888_2_capture_sources,
9098 .unsol_event = alc_automute_amp_unsol_event,
9099 .init_hook = alc888_acer_aspire_8930g_init_hook,
9102 .mixers = { alc883_fivestack_mixer,
9103 alc883_chmode_mixer },
9104 .init_verbs = { alc883_init_verbs,
9105 alc883_medion_eapd_verbs },
9106 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9107 .dac_nids = alc883_dac_nids,
9108 .adc_nids = alc883_adc_nids_alt,
9109 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9110 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9111 .channel_mode = alc883_sixstack_modes,
9112 .input_mux = &alc883_capture_source,
9114 [ALC883_MEDION_MD2] = {
9115 .mixers = { alc883_medion_md2_mixer},
9116 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9117 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9118 .dac_nids = alc883_dac_nids,
9119 .dig_out_nid = ALC883_DIGOUT_NID,
9120 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9121 .channel_mode = alc883_3ST_2ch_modes,
9122 .input_mux = &alc883_capture_source,
9123 .unsol_event = alc_automute_amp_unsol_event,
9124 .init_hook = alc883_medion_md2_init_hook,
9126 [ALC883_LAPTOP_EAPD] = {
9127 .mixers = { alc883_base_mixer },
9128 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9129 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9130 .dac_nids = alc883_dac_nids,
9131 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9132 .channel_mode = alc883_3ST_2ch_modes,
9133 .input_mux = &alc883_capture_source,
9135 [ALC883_CLEVO_M720] = {
9136 .mixers = { alc883_clevo_m720_mixer },
9137 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9138 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9139 .dac_nids = alc883_dac_nids,
9140 .dig_out_nid = ALC883_DIGOUT_NID,
9141 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9142 .channel_mode = alc883_3ST_2ch_modes,
9143 .input_mux = &alc883_capture_source,
9144 .unsol_event = alc883_clevo_m720_unsol_event,
9145 .init_hook = alc883_clevo_m720_init_hook,
9147 [ALC883_LENOVO_101E_2ch] = {
9148 .mixers = { alc883_lenovo_101e_2ch_mixer},
9149 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9150 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9151 .dac_nids = alc883_dac_nids,
9152 .adc_nids = alc883_adc_nids_alt,
9153 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9155 .channel_mode = alc883_3ST_2ch_modes,
9156 .input_mux = &alc883_lenovo_101e_capture_source,
9157 .unsol_event = alc883_lenovo_101e_unsol_event,
9158 .init_hook = alc883_lenovo_101e_all_automute,
9160 [ALC883_LENOVO_NB0763] = {
9161 .mixers = { alc883_lenovo_nb0763_mixer },
9162 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9163 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9164 .dac_nids = alc883_dac_nids,
9165 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9166 .channel_mode = alc883_3ST_2ch_modes,
9168 .input_mux = &alc883_lenovo_nb0763_capture_source,
9169 .unsol_event = alc_automute_amp_unsol_event,
9170 .init_hook = alc883_medion_md2_init_hook,
9172 [ALC888_LENOVO_MS7195_DIG] = {
9173 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9174 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9175 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9176 .dac_nids = alc883_dac_nids,
9177 .dig_out_nid = ALC883_DIGOUT_NID,
9178 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9179 .channel_mode = alc883_3ST_6ch_modes,
9181 .input_mux = &alc883_capture_source,
9182 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9183 .init_hook = alc888_lenovo_ms7195_front_automute,
9185 [ALC883_HAIER_W66] = {
9186 .mixers = { alc883_tagra_2ch_mixer},
9187 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9188 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9189 .dac_nids = alc883_dac_nids,
9190 .dig_out_nid = ALC883_DIGOUT_NID,
9191 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9192 .channel_mode = alc883_3ST_2ch_modes,
9193 .input_mux = &alc883_capture_source,
9194 .unsol_event = alc_automute_amp_unsol_event,
9195 .init_hook = alc883_haier_w66_init_hook,
9198 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9199 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9200 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9201 .dac_nids = alc883_dac_nids,
9202 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9203 .channel_mode = alc888_3st_hp_modes,
9205 .input_mux = &alc883_capture_source,
9206 .unsol_event = alc_automute_amp_unsol_event,
9207 .init_hook = alc888_3st_hp_init_hook,
9209 [ALC888_6ST_DELL] = {
9210 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9211 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9212 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9213 .dac_nids = alc883_dac_nids,
9214 .dig_out_nid = ALC883_DIGOUT_NID,
9215 .dig_in_nid = ALC883_DIGIN_NID,
9216 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9217 .channel_mode = alc883_sixstack_modes,
9218 .input_mux = &alc883_capture_source,
9219 .unsol_event = alc_automute_amp_unsol_event,
9220 .init_hook = alc888_6st_dell_init_hook,
9223 .mixers = { alc883_mitac_mixer },
9224 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9225 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9226 .dac_nids = alc883_dac_nids,
9227 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9228 .channel_mode = alc883_3ST_2ch_modes,
9229 .input_mux = &alc883_capture_source,
9230 .unsol_event = alc_automute_amp_unsol_event,
9231 .init_hook = alc883_mitac_init_hook,
9233 [ALC883_FUJITSU_PI2515] = {
9234 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9235 .init_verbs = { alc883_init_verbs,
9236 alc883_2ch_fujitsu_pi2515_verbs},
9237 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9238 .dac_nids = alc883_dac_nids,
9239 .dig_out_nid = ALC883_DIGOUT_NID,
9240 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9241 .channel_mode = alc883_3ST_2ch_modes,
9242 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9243 .unsol_event = alc_automute_amp_unsol_event,
9244 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
9246 [ALC888_FUJITSU_XA3530] = {
9247 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9248 .init_verbs = { alc883_init_verbs,
9249 alc888_fujitsu_xa3530_verbs },
9250 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9251 .dac_nids = alc883_dac_nids,
9252 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9253 .adc_nids = alc883_adc_nids_rev,
9254 .capsrc_nids = alc883_capsrc_nids_rev,
9255 .dig_out_nid = ALC883_DIGOUT_NID,
9256 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9257 .channel_mode = alc888_4ST_8ch_intel_modes,
9259 ARRAY_SIZE(alc888_2_capture_sources),
9260 .input_mux = alc888_2_capture_sources,
9261 .unsol_event = alc_automute_amp_unsol_event,
9262 .init_hook = alc888_fujitsu_xa3530_init_hook,
9264 [ALC888_LENOVO_SKY] = {
9265 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9266 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9267 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9268 .dac_nids = alc883_dac_nids,
9269 .dig_out_nid = ALC883_DIGOUT_NID,
9270 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9271 .channel_mode = alc883_sixstack_modes,
9273 .input_mux = &alc883_lenovo_sky_capture_source,
9274 .unsol_event = alc_automute_amp_unsol_event,
9275 .init_hook = alc888_lenovo_sky_init_hook,
9277 [ALC888_ASUS_M90V] = {
9278 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9279 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9281 .dac_nids = alc883_dac_nids,
9282 .dig_out_nid = ALC883_DIGOUT_NID,
9283 .dig_in_nid = ALC883_DIGIN_NID,
9284 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9285 .channel_mode = alc883_3ST_6ch_modes,
9287 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9288 .unsol_event = alc883_mode2_unsol_event,
9289 .init_hook = alc883_mode2_inithook,
9291 [ALC888_ASUS_EEE1601] = {
9292 .mixers = { alc883_asus_eee1601_mixer },
9293 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9294 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9295 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9296 .dac_nids = alc883_dac_nids,
9297 .dig_out_nid = ALC883_DIGOUT_NID,
9298 .dig_in_nid = ALC883_DIGIN_NID,
9299 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9300 .channel_mode = alc883_3ST_2ch_modes,
9302 .input_mux = &alc883_asus_eee1601_capture_source,
9303 .unsol_event = alc_sku_unsol_event,
9304 .init_hook = alc883_eee1601_inithook,
9306 [ALC1200_ASUS_P5Q] = {
9307 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9308 .init_verbs = { alc883_init_verbs },
9309 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9310 .dac_nids = alc883_dac_nids,
9311 .dig_out_nid = ALC1200_DIGOUT_NID,
9312 .dig_in_nid = ALC883_DIGIN_NID,
9313 .slave_dig_outs = alc1200_slave_dig_outs,
9314 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9315 .channel_mode = alc883_sixstack_modes,
9316 .input_mux = &alc883_capture_source,
9319 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9320 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9321 alc880_gpio1_init_verbs },
9322 .adc_nids = alc883_adc_nids,
9323 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9324 .dac_nids = alc883_dac_nids,
9325 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9326 .channel_mode = alc889A_mb31_6ch_modes,
9327 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9328 .input_mux = &alc889A_mb31_capture_source,
9329 .dig_out_nid = ALC883_DIGOUT_NID,
9330 .unsol_event = alc889A_mb31_unsol_event,
9331 .init_hook = alc889A_mb31_automute,
9337 * BIOS auto configuration
9339 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9340 hda_nid_t nid, int pin_type,
9344 struct alc_spec *spec = codec->spec;
9347 alc_set_pin_output(codec, nid, pin_type);
9348 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9351 idx = spec->multiout.dac_nids[dac_idx] - 2;
9352 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9356 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9358 struct alc_spec *spec = codec->spec;
9361 for (i = 0; i <= HDA_SIDE; i++) {
9362 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9363 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9365 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9370 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9372 struct alc_spec *spec = codec->spec;
9375 pin = spec->autocfg.hp_pins[0];
9376 if (pin) /* connect to front */
9378 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9379 pin = spec->autocfg.speaker_pins[0];
9381 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9384 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9385 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9387 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9389 struct alc_spec *spec = codec->spec;
9392 for (i = 0; i < AUTO_PIN_LAST; i++) {
9393 hda_nid_t nid = spec->autocfg.input_pins[i];
9394 if (alc883_is_input_pin(nid)) {
9395 alc_set_input_pin(codec, nid, i);
9396 if (nid != ALC883_PIN_CD_NID &&
9397 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9398 snd_hda_codec_write(codec, nid, 0,
9399 AC_VERB_SET_AMP_GAIN_MUTE,
9405 #define alc883_auto_init_input_src alc882_auto_init_input_src
9407 /* almost identical with ALC880 parser... */
9408 static int alc883_parse_auto_config(struct hda_codec *codec)
9410 struct alc_spec *spec = codec->spec;
9411 int err = alc880_parse_auto_config(codec);
9412 struct auto_pin_cfg *cfg = &spec->autocfg;
9418 return 0; /* no config found */
9420 err = alc_auto_add_mic_boost(codec);
9424 /* hack - override the init verbs */
9425 spec->init_verbs[0] = alc883_auto_init_verbs;
9427 /* setup input_mux for ALC889 */
9428 if (codec->vendor_id == 0x10ec0889) {
9429 /* digital-mic input pin is excluded in alc880_auto_create..()
9430 * because it's under 0x18
9432 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9433 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9434 struct hda_input_mux *imux = &spec->private_imux[0];
9435 for (i = 1; i < 3; i++)
9436 memcpy(&spec->private_imux[i],
9437 &spec->private_imux[0],
9438 sizeof(spec->private_imux[0]));
9439 imux->items[imux->num_items].label = "Int DMic";
9440 imux->items[imux->num_items].index = 0x0b;
9442 spec->num_mux_defs = 3;
9443 spec->input_mux = spec->private_imux;
9447 return 1; /* config found */
9450 /* additional initialization for auto-configuration model */
9451 static void alc883_auto_init(struct hda_codec *codec)
9453 struct alc_spec *spec = codec->spec;
9454 alc883_auto_init_multi_out(codec);
9455 alc883_auto_init_hp_out(codec);
9456 alc883_auto_init_analog_input(codec);
9457 alc883_auto_init_input_src(codec);
9458 if (spec->unsol_event)
9459 alc_inithook(codec);
9462 static int patch_alc883(struct hda_codec *codec)
9464 struct alc_spec *spec;
9465 int err, board_config;
9467 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9473 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9475 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9478 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9479 /* Pick up systems that don't supply PCI SSID */
9480 switch (codec->subsystem_id) {
9481 case 0x106b3600: /* Macbook 3.1 */
9482 board_config = ALC889A_MB31;
9486 "hda_codec: Unknown model for %s, trying "
9487 "auto-probe from BIOS...\n", codec->chip_name);
9488 board_config = ALC883_AUTO;
9492 if (board_config == ALC883_AUTO) {
9493 /* automatic parse from the BIOS config */
9494 err = alc883_parse_auto_config(codec);
9500 "hda_codec: Cannot set up configuration "
9501 "from BIOS. Using base mode...\n");
9502 board_config = ALC883_3ST_2ch_DIG;
9506 err = snd_hda_attach_beep_device(codec, 0x1);
9512 if (board_config != ALC883_AUTO)
9513 setup_preset(spec, &alc883_presets[board_config]);
9515 switch (codec->vendor_id) {
9517 if (!spec->num_adc_nids) {
9518 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9519 spec->adc_nids = alc883_adc_nids;
9521 if (!spec->capsrc_nids)
9522 spec->capsrc_nids = alc883_capsrc_nids;
9523 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9524 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9527 if (!spec->num_adc_nids) {
9528 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9529 spec->adc_nids = alc889_adc_nids;
9531 if (!spec->capsrc_nids)
9532 spec->capsrc_nids = alc889_capsrc_nids;
9533 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9537 if (!spec->num_adc_nids) {
9538 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9539 spec->adc_nids = alc883_adc_nids;
9541 if (!spec->capsrc_nids)
9542 spec->capsrc_nids = alc883_capsrc_nids;
9543 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9547 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9548 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9549 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9551 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9552 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9554 if (!spec->cap_mixer)
9555 set_capture_mixer(spec);
9556 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9558 spec->vmaster_nid = 0x0c;
9560 codec->patch_ops = alc_patch_ops;
9561 if (board_config == ALC883_AUTO)
9562 spec->init_hook = alc883_auto_init;
9564 #ifdef CONFIG_SND_HDA_POWER_SAVE
9565 if (!spec->loopback.amplist)
9566 spec->loopback.amplist = alc883_loopbacks;
9568 codec->proc_widget_hook = print_realtek_coef;
9577 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9578 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9580 #define alc262_dac_nids alc260_dac_nids
9581 #define alc262_adc_nids alc882_adc_nids
9582 #define alc262_adc_nids_alt alc882_adc_nids_alt
9583 #define alc262_capsrc_nids alc882_capsrc_nids
9584 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9586 #define alc262_modes alc260_modes
9587 #define alc262_capture_source alc882_capture_source
9589 static hda_nid_t alc262_dmic_adc_nids[1] = {
9594 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9596 static struct snd_kcontrol_new alc262_base_mixer[] = {
9597 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9598 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9605 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9606 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9607 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9608 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9609 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9610 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9611 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9612 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9616 /* update HP, line and mono-out pins according to the master switch */
9617 static void alc262_hp_master_update(struct hda_codec *codec)
9619 struct alc_spec *spec = codec->spec;
9620 int val = spec->master_sw;
9623 snd_hda_codec_write_cache(codec, 0x1b, 0,
9624 AC_VERB_SET_PIN_WIDGET_CONTROL,
9626 snd_hda_codec_write_cache(codec, 0x15, 0,
9627 AC_VERB_SET_PIN_WIDGET_CONTROL,
9629 /* mono (speaker) depending on the HP jack sense */
9630 val = val && !spec->jack_present;
9631 snd_hda_codec_write_cache(codec, 0x16, 0,
9632 AC_VERB_SET_PIN_WIDGET_CONTROL,
9636 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9638 struct alc_spec *spec = codec->spec;
9639 unsigned int presence;
9640 presence = snd_hda_codec_read(codec, 0x1b, 0,
9641 AC_VERB_GET_PIN_SENSE, 0);
9642 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9643 alc262_hp_master_update(codec);
9646 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9648 if ((res >> 26) != ALC880_HP_EVENT)
9650 alc262_hp_bpc_automute(codec);
9653 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9655 struct alc_spec *spec = codec->spec;
9656 unsigned int presence;
9657 presence = snd_hda_codec_read(codec, 0x15, 0,
9658 AC_VERB_GET_PIN_SENSE, 0);
9659 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9660 alc262_hp_master_update(codec);
9663 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9666 if ((res >> 26) != ALC880_HP_EVENT)
9668 alc262_hp_wildwest_automute(codec);
9671 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9673 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9674 struct snd_ctl_elem_value *ucontrol)
9676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9677 struct alc_spec *spec = codec->spec;
9678 int val = !!*ucontrol->value.integer.value;
9680 if (val == spec->master_sw)
9682 spec->master_sw = val;
9683 alc262_hp_master_update(codec);
9687 #define ALC262_HP_MASTER_SWITCH \
9689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9690 .name = "Master Playback Switch", \
9691 .info = snd_ctl_boolean_mono_info, \
9692 .get = alc262_hp_master_sw_get, \
9693 .put = alc262_hp_master_sw_put, \
9696 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9697 ALC262_HP_MASTER_SWITCH,
9698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9699 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9701 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9703 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9708 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9709 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9710 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9711 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9712 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9713 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9714 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9715 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9716 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9720 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9721 ALC262_HP_MASTER_SWITCH,
9722 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9723 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9726 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9728 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9730 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9731 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9732 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9733 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9734 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9735 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9736 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9740 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9741 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9742 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9743 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9747 /* mute/unmute internal speaker according to the hp jack and mute state */
9748 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9750 struct alc_spec *spec = codec->spec;
9752 spec->autocfg.hp_pins[0] = 0x15;
9753 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9754 alc_automute_amp(codec);
9757 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9758 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9759 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9760 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9761 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9764 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9768 static struct hda_verb alc262_hp_t5735_verbs[] = {
9769 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9772 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9776 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9777 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9779 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9780 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9781 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9782 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9786 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9787 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9788 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9789 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9791 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9792 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9793 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9794 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9795 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9796 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9800 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9807 /* bind hp and internal speaker mute (with plug check) as master switch */
9808 static void alc262_hippo_master_update(struct hda_codec *codec)
9810 struct alc_spec *spec = codec->spec;
9811 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9812 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9813 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9817 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9818 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9819 HDA_AMP_MUTE, mute);
9820 /* mute internal speaker per jack sense */
9821 if (spec->jack_present)
9822 mute = HDA_AMP_MUTE;
9824 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9825 HDA_AMP_MUTE, mute);
9826 if (speaker_nid && speaker_nid != line_nid)
9827 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9828 HDA_AMP_MUTE, mute);
9831 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9833 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9834 struct snd_ctl_elem_value *ucontrol)
9836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9837 struct alc_spec *spec = codec->spec;
9838 int val = !!*ucontrol->value.integer.value;
9840 if (val == spec->master_sw)
9842 spec->master_sw = val;
9843 alc262_hippo_master_update(codec);
9847 #define ALC262_HIPPO_MASTER_SWITCH \
9849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9850 .name = "Master Playback Switch", \
9851 .info = snd_ctl_boolean_mono_info, \
9852 .get = alc262_hippo_master_sw_get, \
9853 .put = alc262_hippo_master_sw_put, \
9856 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9857 ALC262_HIPPO_MASTER_SWITCH,
9858 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9859 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9860 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9861 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9862 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9863 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9864 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9865 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9866 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9867 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9868 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9869 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9873 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9874 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9875 ALC262_HIPPO_MASTER_SWITCH,
9876 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9877 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9878 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9879 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9882 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9883 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9884 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9885 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9889 /* mute/unmute internal speaker according to the hp jack and mute state */
9890 static void alc262_hippo_automute(struct hda_codec *codec)
9892 struct alc_spec *spec = codec->spec;
9893 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9894 unsigned int present;
9896 /* need to execute and sync at first */
9897 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9898 present = snd_hda_codec_read(codec, hp_nid, 0,
9899 AC_VERB_GET_PIN_SENSE, 0);
9900 spec->jack_present = (present & 0x80000000) != 0;
9901 alc262_hippo_master_update(codec);
9904 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9906 if ((res >> 26) != ALC880_HP_EVENT)
9908 alc262_hippo_automute(codec);
9911 static void alc262_hippo_init_hook(struct hda_codec *codec)
9913 struct alc_spec *spec = codec->spec;
9915 spec->autocfg.hp_pins[0] = 0x15;
9916 spec->autocfg.speaker_pins[0] = 0x14;
9917 alc262_hippo_automute(codec);
9920 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9922 struct alc_spec *spec = codec->spec;
9924 spec->autocfg.hp_pins[0] = 0x1b;
9925 spec->autocfg.speaker_pins[0] = 0x14;
9926 alc262_hippo_automute(codec);
9930 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9931 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9932 ALC262_HIPPO_MASTER_SWITCH,
9933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9935 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9936 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9940 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9941 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9942 ALC262_HIPPO_MASTER_SWITCH,
9943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9946 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9947 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9951 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9952 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9953 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9954 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9955 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9956 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9957 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9959 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9960 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9961 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9962 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9963 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9967 static struct hda_verb alc262_tyan_verbs[] = {
9968 /* Headphone automute */
9969 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9970 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9971 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9973 /* P11 AUX_IN, white 4-pin connector */
9974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9975 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9976 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9977 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9982 /* unsolicited event for HP jack sensing */
9983 static void alc262_tyan_init_hook(struct hda_codec *codec)
9985 struct alc_spec *spec = codec->spec;
9987 spec->autocfg.hp_pins[0] = 0x1b;
9988 spec->autocfg.speaker_pins[0] = 0x15;
9989 alc_automute_amp(codec);
9993 #define alc262_capture_mixer alc882_capture_mixer
9994 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9997 * generic initialization of ADC, input mixers and output mixers
9999 static struct hda_verb alc262_init_verbs[] = {
10001 * Unmute ADC0-2 and set the default input to mic-in
10003 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10005 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10007 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10010 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10012 * Note: PASD motherboards uses the Line In 2 as the input for
10013 * front panel mic (mic 2)
10015 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10017 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10018 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10023 * Set up output mixers (0x0c - 0x0e)
10025 /* set vol=0 to output mixers */
10026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10029 /* set up input amps for analog loopback */
10030 /* Amp Indices: DAC = 0, mixer = 1 */
10031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10033 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10034 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10035 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10036 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10038 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10039 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10040 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10041 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10042 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10043 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10045 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10047 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10048 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10051 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10052 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10054 /* FIXME: use matrix-type input source selection */
10055 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10056 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10069 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10075 static struct hda_verb alc262_eapd_verbs[] = {
10076 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10077 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10081 static struct hda_verb alc262_hippo_unsol_verbs[] = {
10082 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10087 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10089 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10090 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10092 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10093 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10097 static struct hda_verb alc262_sony_unsol_verbs[] = {
10098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10099 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10100 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10102 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10103 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10107 static struct hda_input_mux alc262_dmic_capture_source = {
10110 { "Int DMic", 0x9 },
10115 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10116 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10117 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10124 static struct hda_verb alc262_toshiba_s06_verbs[] = {
10125 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10128 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10129 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10130 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10131 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10132 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10136 static void alc262_dmic_automute(struct hda_codec *codec)
10138 unsigned int present;
10140 present = snd_hda_codec_read(codec, 0x18, 0,
10141 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10142 snd_hda_codec_write(codec, 0x22, 0,
10143 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10147 /* unsolicited event for HP jack sensing */
10148 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10151 if ((res >> 26) == ALC880_MIC_EVENT)
10152 alc262_dmic_automute(codec);
10154 alc_sku_unsol_event(codec, res);
10157 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10159 struct alc_spec *spec = codec->spec;
10161 spec->autocfg.hp_pins[0] = 0x15;
10162 spec->autocfg.speaker_pins[0] = 0x14;
10163 alc_automute_pin(codec);
10164 alc262_dmic_automute(codec);
10170 * 0x16 = internal speaker
10171 * 0x18 = external mic
10174 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10175 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10176 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10180 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10182 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10187 static struct hda_verb alc262_nec_verbs[] = {
10188 /* Unmute Speaker */
10189 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10192 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10195 /* External mic to headphone */
10196 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10197 /* External mic to speaker */
10198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10204 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10205 * 0x1b = port replicator headphone out
10208 #define ALC_HP_EVENT 0x37
10210 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10211 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10213 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10214 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10218 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10219 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10220 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10224 static struct hda_input_mux alc262_fujitsu_capture_source = {
10228 { "Int Mic", 0x1 },
10233 static struct hda_input_mux alc262_HP_capture_source = {
10237 { "Front Mic", 0x1 },
10244 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10248 { "Front Mic", 0x2 },
10254 /* mute/unmute internal speaker according to the hp jacks and mute state */
10255 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10257 struct alc_spec *spec = codec->spec;
10260 if (force || !spec->sense_updated) {
10261 unsigned int present;
10262 /* need to execute and sync at first */
10263 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10264 /* check laptop HP jack */
10265 present = snd_hda_codec_read(codec, 0x14, 0,
10266 AC_VERB_GET_PIN_SENSE, 0);
10267 /* need to execute and sync at first */
10268 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10269 /* check docking HP jack */
10270 present |= snd_hda_codec_read(codec, 0x1b, 0,
10271 AC_VERB_GET_PIN_SENSE, 0);
10272 if (present & AC_PINSENSE_PRESENCE)
10273 spec->jack_present = 1;
10275 spec->jack_present = 0;
10276 spec->sense_updated = 1;
10278 /* unmute internal speaker only if both HPs are unplugged and
10279 * master switch is on
10281 if (spec->jack_present)
10282 mute = HDA_AMP_MUTE;
10284 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10285 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10286 HDA_AMP_MUTE, mute);
10289 /* unsolicited event for HP jack sensing */
10290 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10293 if ((res >> 26) != ALC_HP_EVENT)
10295 alc262_fujitsu_automute(codec, 1);
10298 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10300 alc262_fujitsu_automute(codec, 1);
10303 /* bind volumes of both NID 0x0c and 0x0d */
10304 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10305 .ops = &snd_hda_bind_vol,
10307 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10308 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10313 /* mute/unmute internal speaker according to the hp jack and mute state */
10314 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10316 struct alc_spec *spec = codec->spec;
10319 if (force || !spec->sense_updated) {
10320 unsigned int present_int_hp;
10321 /* need to execute and sync at first */
10322 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10323 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10324 AC_VERB_GET_PIN_SENSE, 0);
10325 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10326 spec->sense_updated = 1;
10328 if (spec->jack_present) {
10329 /* mute internal speaker */
10330 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10331 HDA_AMP_MUTE, HDA_AMP_MUTE);
10332 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10333 HDA_AMP_MUTE, HDA_AMP_MUTE);
10335 /* unmute internal speaker if necessary */
10336 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10337 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10338 HDA_AMP_MUTE, mute);
10339 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10340 HDA_AMP_MUTE, mute);
10344 /* unsolicited event for HP jack sensing */
10345 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10348 if ((res >> 26) != ALC_HP_EVENT)
10350 alc262_lenovo_3000_automute(codec, 1);
10353 /* bind hp and internal speaker mute (with plug check) */
10354 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10355 struct snd_ctl_elem_value *ucontrol)
10357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10358 long *valp = ucontrol->value.integer.value;
10361 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10363 valp ? 0 : HDA_AMP_MUTE);
10364 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10366 valp ? 0 : HDA_AMP_MUTE);
10369 alc262_fujitsu_automute(codec, 0);
10373 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10374 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10376 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10377 .name = "Master Playback Switch",
10378 .info = snd_hda_mixer_amp_switch_info,
10379 .get = snd_hda_mixer_amp_switch_get,
10380 .put = alc262_fujitsu_master_sw_put,
10381 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10385 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10386 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10387 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10388 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10389 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10390 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10394 /* bind hp and internal speaker mute (with plug check) */
10395 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10396 struct snd_ctl_elem_value *ucontrol)
10398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10399 long *valp = ucontrol->value.integer.value;
10402 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10404 valp ? 0 : HDA_AMP_MUTE);
10407 alc262_lenovo_3000_automute(codec, 0);
10411 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10412 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10415 .name = "Master Playback Switch",
10416 .info = snd_hda_mixer_amp_switch_info,
10417 .get = snd_hda_mixer_amp_switch_get,
10418 .put = alc262_lenovo_3000_master_sw_put,
10419 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10423 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10426 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10427 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10428 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10432 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10433 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10434 ALC262_HIPPO_MASTER_SWITCH,
10435 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10436 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10437 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10438 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10439 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10440 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10444 /* additional init verbs for Benq laptops */
10445 static struct hda_verb alc262_EAPD_verbs[] = {
10446 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10447 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10451 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10455 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10456 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10460 /* Samsung Q1 Ultra Vista model setup */
10461 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10462 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10463 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10466 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10467 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10471 static struct hda_verb alc262_ultra_verbs[] = {
10473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10479 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10480 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10488 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10490 /* ADC, choose mic */
10491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10497 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10498 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10499 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10500 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10504 /* mute/unmute internal speaker according to the hp jack and mute state */
10505 static void alc262_ultra_automute(struct hda_codec *codec)
10507 struct alc_spec *spec = codec->spec;
10511 /* auto-mute only when HP is used as HP */
10512 if (!spec->cur_mux[0]) {
10513 unsigned int present;
10514 /* need to execute and sync at first */
10515 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10516 present = snd_hda_codec_read(codec, 0x15, 0,
10517 AC_VERB_GET_PIN_SENSE, 0);
10518 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10519 if (spec->jack_present)
10520 mute = HDA_AMP_MUTE;
10522 /* mute/unmute internal speaker */
10523 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10524 HDA_AMP_MUTE, mute);
10525 /* mute/unmute HP */
10526 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10527 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10530 /* unsolicited event for HP jack sensing */
10531 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10534 if ((res >> 26) != ALC880_HP_EVENT)
10536 alc262_ultra_automute(codec);
10539 static struct hda_input_mux alc262_ultra_capture_source = {
10543 { "Headphone", 0x7 },
10547 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10548 struct snd_ctl_elem_value *ucontrol)
10550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10551 struct alc_spec *spec = codec->spec;
10554 ret = alc_mux_enum_put(kcontrol, ucontrol);
10557 /* reprogram the HP pin as mic or HP according to the input source */
10558 snd_hda_codec_write_cache(codec, 0x15, 0,
10559 AC_VERB_SET_PIN_WIDGET_CONTROL,
10560 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10561 alc262_ultra_automute(codec); /* mute/unmute HP */
10565 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10566 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10567 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10570 .name = "Capture Source",
10571 .info = alc_mux_enum_info,
10572 .get = alc_mux_enum_get,
10573 .put = alc262_ultra_mux_enum_put,
10578 /* add playback controls from the parsed DAC table */
10579 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10580 const struct auto_pin_cfg *cfg)
10585 spec->multiout.num_dacs = 1; /* only use one dac */
10586 spec->multiout.dac_nids = spec->private_dac_nids;
10587 spec->multiout.dac_nids[0] = 2;
10589 nid = cfg->line_out_pins[0];
10591 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10592 "Front Playback Volume",
10593 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10596 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10597 "Front Playback Switch",
10598 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10603 nid = cfg->speaker_pins[0];
10606 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10607 "Speaker Playback Volume",
10608 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10612 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10613 "Speaker Playback Switch",
10614 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10619 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10620 "Speaker Playback Switch",
10621 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10627 nid = cfg->hp_pins[0];
10629 /* spec->multiout.hp_nid = 2; */
10631 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10632 "Headphone Playback Volume",
10633 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10637 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10638 "Headphone Playback Switch",
10639 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10644 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10645 "Headphone Playback Switch",
10646 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10655 /* identical with ALC880 */
10656 #define alc262_auto_create_analog_input_ctls \
10657 alc880_auto_create_analog_input_ctls
10660 * generic initialization of ADC, input mixers and output mixers
10662 static struct hda_verb alc262_volume_init_verbs[] = {
10664 * Unmute ADC0-2 and set the default input to mic-in
10666 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10668 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10669 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10670 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10671 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10673 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10675 * Note: PASD motherboards uses the Line In 2 as the input for
10676 * front panel mic (mic 2)
10678 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10679 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10680 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10686 * Set up output mixers (0x0c - 0x0f)
10688 /* set vol=0 to output mixers */
10689 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10690 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10691 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10693 /* set up input amps for analog loopback */
10694 /* Amp Indices: DAC = 0, mixer = 1 */
10695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10697 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10698 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10699 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10700 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10702 /* FIXME: use matrix-type input source selection */
10703 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10704 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10710 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10711 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10712 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10713 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10723 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10725 * Unmute ADC0-2 and set the default input to mic-in
10727 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10728 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10729 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10730 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10731 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10734 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10736 * Note: PASD motherboards uses the Line In 2 as the input for
10737 * front panel mic (mic 2)
10739 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10743 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10744 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10745 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10746 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10749 * Set up output mixers (0x0c - 0x0e)
10751 /* set vol=0 to output mixers */
10752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10754 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10756 /* set up input amps for analog loopback */
10757 /* Amp Indices: DAC = 0, mixer = 1 */
10758 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10759 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10760 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10761 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10762 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10763 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10765 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10769 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10772 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10773 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10775 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10776 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10778 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10779 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10781 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10783 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10785 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10786 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10789 /* FIXME: use matrix-type input source selection */
10790 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10791 /* Input mixer1: only unmute Mic */
10792 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10793 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10794 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10795 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10796 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10797 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10798 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10799 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10800 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10802 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10803 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10804 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10805 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10806 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10807 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10808 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10809 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10810 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10813 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10822 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10827 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10829 * Unmute ADC0-2 and set the default input to mic-in
10831 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10833 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10834 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10835 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10838 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10840 * Note: PASD motherboards uses the Line In 2 as the input for front
10841 * panel mic (mic 2)
10843 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10844 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10845 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10853 * Set up output mixers (0x0c - 0x0e)
10855 /* set vol=0 to output mixers */
10856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10858 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10860 /* set up input amps for analog loopback */
10861 /* Amp Indices: DAC = 0, mixer = 1 */
10862 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10864 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10866 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10871 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10873 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10874 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10875 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10878 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10881 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10882 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10884 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10885 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10886 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10887 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10888 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10889 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10891 /* FIXME: use matrix-type input source selection */
10892 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10893 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10899 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10900 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10907 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10908 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10915 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10918 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10923 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10925 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10927 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10929 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10930 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10931 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10932 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10936 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10941 #ifdef CONFIG_SND_HDA_POWER_SAVE
10942 #define alc262_loopbacks alc880_loopbacks
10945 /* pcm configuration: identiacal with ALC880 */
10946 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10947 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10948 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10949 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10952 * BIOS auto configuration
10954 static int alc262_parse_auto_config(struct hda_codec *codec)
10956 struct alc_spec *spec = codec->spec;
10958 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10960 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10964 if (!spec->autocfg.line_outs) {
10965 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10966 spec->multiout.max_channels = 2;
10967 spec->no_analog = 1;
10970 return 0; /* can't find valid BIOS pin config */
10972 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10975 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10979 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10982 if (spec->autocfg.dig_outs) {
10983 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10984 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10986 if (spec->autocfg.dig_in_pin)
10987 spec->dig_in_nid = ALC262_DIGIN_NID;
10989 if (spec->kctls.list)
10990 add_mixer(spec, spec->kctls.list);
10992 add_verb(spec, alc262_volume_init_verbs);
10993 spec->num_mux_defs = 1;
10994 spec->input_mux = &spec->private_imux[0];
10996 err = alc_auto_add_mic_boost(codec);
11000 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11005 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
11006 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
11007 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
11008 #define alc262_auto_init_input_src alc882_auto_init_input_src
11011 /* init callback for auto-configuration model -- overriding the default init */
11012 static void alc262_auto_init(struct hda_codec *codec)
11014 struct alc_spec *spec = codec->spec;
11015 alc262_auto_init_multi_out(codec);
11016 alc262_auto_init_hp_out(codec);
11017 alc262_auto_init_analog_input(codec);
11018 alc262_auto_init_input_src(codec);
11019 if (spec->unsol_event)
11020 alc_inithook(codec);
11024 * configuration and preset
11026 static const char *alc262_models[ALC262_MODEL_LAST] = {
11027 [ALC262_BASIC] = "basic",
11028 [ALC262_HIPPO] = "hippo",
11029 [ALC262_HIPPO_1] = "hippo_1",
11030 [ALC262_FUJITSU] = "fujitsu",
11031 [ALC262_HP_BPC] = "hp-bpc",
11032 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11033 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
11034 [ALC262_HP_RP5700] = "hp-rp5700",
11035 [ALC262_BENQ_ED8] = "benq",
11036 [ALC262_BENQ_T31] = "benq-t31",
11037 [ALC262_SONY_ASSAMD] = "sony-assamd",
11038 [ALC262_TOSHIBA_S06] = "toshiba-s06",
11039 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
11040 [ALC262_ULTRA] = "ultra",
11041 [ALC262_LENOVO_3000] = "lenovo-3000",
11042 [ALC262_NEC] = "nec",
11043 [ALC262_TYAN] = "tyan",
11044 [ALC262_AUTO] = "auto",
11047 static struct snd_pci_quirk alc262_cfg_tbl[] = {
11048 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11049 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11050 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11052 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11054 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11056 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11057 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11058 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11059 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11060 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11061 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11062 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11063 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11064 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11065 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11066 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11067 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11068 ALC262_HP_TC_T5735),
11069 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11070 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11071 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11072 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11073 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11074 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11075 ALC262_SONY_ASSAMD),
11076 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11077 ALC262_TOSHIBA_RX1),
11078 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11079 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11080 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11081 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11082 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11084 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11085 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11086 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11087 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11088 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11092 static struct alc_config_preset alc262_presets[] = {
11094 .mixers = { alc262_base_mixer },
11095 .init_verbs = { alc262_init_verbs },
11096 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11097 .dac_nids = alc262_dac_nids,
11099 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11100 .channel_mode = alc262_modes,
11101 .input_mux = &alc262_capture_source,
11104 .mixers = { alc262_hippo_mixer },
11105 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
11106 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11107 .dac_nids = alc262_dac_nids,
11109 .dig_out_nid = ALC262_DIGOUT_NID,
11110 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11111 .channel_mode = alc262_modes,
11112 .input_mux = &alc262_capture_source,
11113 .unsol_event = alc262_hippo_unsol_event,
11114 .init_hook = alc262_hippo_init_hook,
11116 [ALC262_HIPPO_1] = {
11117 .mixers = { alc262_hippo1_mixer },
11118 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11119 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11120 .dac_nids = alc262_dac_nids,
11122 .dig_out_nid = ALC262_DIGOUT_NID,
11123 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11124 .channel_mode = alc262_modes,
11125 .input_mux = &alc262_capture_source,
11126 .unsol_event = alc262_hippo_unsol_event,
11127 .init_hook = alc262_hippo1_init_hook,
11129 [ALC262_FUJITSU] = {
11130 .mixers = { alc262_fujitsu_mixer },
11131 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11132 alc262_fujitsu_unsol_verbs },
11133 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11134 .dac_nids = alc262_dac_nids,
11136 .dig_out_nid = ALC262_DIGOUT_NID,
11137 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11138 .channel_mode = alc262_modes,
11139 .input_mux = &alc262_fujitsu_capture_source,
11140 .unsol_event = alc262_fujitsu_unsol_event,
11141 .init_hook = alc262_fujitsu_init_hook,
11143 [ALC262_HP_BPC] = {
11144 .mixers = { alc262_HP_BPC_mixer },
11145 .init_verbs = { alc262_HP_BPC_init_verbs },
11146 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11147 .dac_nids = alc262_dac_nids,
11149 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11150 .channel_mode = alc262_modes,
11151 .input_mux = &alc262_HP_capture_source,
11152 .unsol_event = alc262_hp_bpc_unsol_event,
11153 .init_hook = alc262_hp_bpc_automute,
11155 [ALC262_HP_BPC_D7000_WF] = {
11156 .mixers = { alc262_HP_BPC_WildWest_mixer },
11157 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11158 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11159 .dac_nids = alc262_dac_nids,
11161 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11162 .channel_mode = alc262_modes,
11163 .input_mux = &alc262_HP_D7000_capture_source,
11164 .unsol_event = alc262_hp_wildwest_unsol_event,
11165 .init_hook = alc262_hp_wildwest_automute,
11167 [ALC262_HP_BPC_D7000_WL] = {
11168 .mixers = { alc262_HP_BPC_WildWest_mixer,
11169 alc262_HP_BPC_WildWest_option_mixer },
11170 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11171 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11172 .dac_nids = alc262_dac_nids,
11174 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11175 .channel_mode = alc262_modes,
11176 .input_mux = &alc262_HP_D7000_capture_source,
11177 .unsol_event = alc262_hp_wildwest_unsol_event,
11178 .init_hook = alc262_hp_wildwest_automute,
11180 [ALC262_HP_TC_T5735] = {
11181 .mixers = { alc262_hp_t5735_mixer },
11182 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11183 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11184 .dac_nids = alc262_dac_nids,
11186 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11187 .channel_mode = alc262_modes,
11188 .input_mux = &alc262_capture_source,
11189 .unsol_event = alc_automute_amp_unsol_event,
11190 .init_hook = alc262_hp_t5735_init_hook,
11192 [ALC262_HP_RP5700] = {
11193 .mixers = { alc262_hp_rp5700_mixer },
11194 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11195 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11196 .dac_nids = alc262_dac_nids,
11197 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11198 .channel_mode = alc262_modes,
11199 .input_mux = &alc262_hp_rp5700_capture_source,
11201 [ALC262_BENQ_ED8] = {
11202 .mixers = { alc262_base_mixer },
11203 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11204 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11205 .dac_nids = alc262_dac_nids,
11207 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11208 .channel_mode = alc262_modes,
11209 .input_mux = &alc262_capture_source,
11211 [ALC262_SONY_ASSAMD] = {
11212 .mixers = { alc262_sony_mixer },
11213 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11214 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11215 .dac_nids = alc262_dac_nids,
11217 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11218 .channel_mode = alc262_modes,
11219 .input_mux = &alc262_capture_source,
11220 .unsol_event = alc262_hippo_unsol_event,
11221 .init_hook = alc262_hippo_init_hook,
11223 [ALC262_BENQ_T31] = {
11224 .mixers = { alc262_benq_t31_mixer },
11225 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11226 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11227 .dac_nids = alc262_dac_nids,
11229 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11230 .channel_mode = alc262_modes,
11231 .input_mux = &alc262_capture_source,
11232 .unsol_event = alc262_hippo_unsol_event,
11233 .init_hook = alc262_hippo_init_hook,
11236 .mixers = { alc262_ultra_mixer },
11237 .cap_mixer = alc262_ultra_capture_mixer,
11238 .init_verbs = { alc262_ultra_verbs },
11239 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11240 .dac_nids = alc262_dac_nids,
11241 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11242 .channel_mode = alc262_modes,
11243 .input_mux = &alc262_ultra_capture_source,
11244 .adc_nids = alc262_adc_nids, /* ADC0 */
11245 .capsrc_nids = alc262_capsrc_nids,
11246 .num_adc_nids = 1, /* single ADC */
11247 .unsol_event = alc262_ultra_unsol_event,
11248 .init_hook = alc262_ultra_automute,
11250 [ALC262_LENOVO_3000] = {
11251 .mixers = { alc262_lenovo_3000_mixer },
11252 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11253 alc262_lenovo_3000_unsol_verbs },
11254 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11255 .dac_nids = alc262_dac_nids,
11257 .dig_out_nid = ALC262_DIGOUT_NID,
11258 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11259 .channel_mode = alc262_modes,
11260 .input_mux = &alc262_fujitsu_capture_source,
11261 .unsol_event = alc262_lenovo_3000_unsol_event,
11264 .mixers = { alc262_nec_mixer },
11265 .init_verbs = { alc262_nec_verbs },
11266 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11267 .dac_nids = alc262_dac_nids,
11269 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11270 .channel_mode = alc262_modes,
11271 .input_mux = &alc262_capture_source,
11273 [ALC262_TOSHIBA_S06] = {
11274 .mixers = { alc262_toshiba_s06_mixer },
11275 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11276 alc262_eapd_verbs },
11277 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11278 .capsrc_nids = alc262_dmic_capsrc_nids,
11279 .dac_nids = alc262_dac_nids,
11280 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11281 .dig_out_nid = ALC262_DIGOUT_NID,
11282 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11283 .channel_mode = alc262_modes,
11284 .input_mux = &alc262_dmic_capture_source,
11285 .unsol_event = alc262_toshiba_s06_unsol_event,
11286 .init_hook = alc262_toshiba_s06_init_hook,
11288 [ALC262_TOSHIBA_RX1] = {
11289 .mixers = { alc262_toshiba_rx1_mixer },
11290 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11291 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11292 .dac_nids = alc262_dac_nids,
11294 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11295 .channel_mode = alc262_modes,
11296 .input_mux = &alc262_capture_source,
11297 .unsol_event = alc262_hippo_unsol_event,
11298 .init_hook = alc262_hippo_init_hook,
11301 .mixers = { alc262_tyan_mixer },
11302 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11303 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11304 .dac_nids = alc262_dac_nids,
11306 .dig_out_nid = ALC262_DIGOUT_NID,
11307 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11308 .channel_mode = alc262_modes,
11309 .input_mux = &alc262_capture_source,
11310 .unsol_event = alc_automute_amp_unsol_event,
11311 .init_hook = alc262_tyan_init_hook,
11315 static int patch_alc262(struct hda_codec *codec)
11317 struct alc_spec *spec;
11321 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11325 codec->spec = spec;
11327 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11332 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11333 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11334 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11335 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11339 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11341 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11345 if (board_config < 0) {
11346 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11347 "trying auto-probe from BIOS...\n", codec->chip_name);
11348 board_config = ALC262_AUTO;
11351 if (board_config == ALC262_AUTO) {
11352 /* automatic parse from the BIOS config */
11353 err = alc262_parse_auto_config(codec);
11359 "hda_codec: Cannot set up configuration "
11360 "from BIOS. Using base mode...\n");
11361 board_config = ALC262_BASIC;
11365 if (!spec->no_analog) {
11366 err = snd_hda_attach_beep_device(codec, 0x1);
11373 if (board_config != ALC262_AUTO)
11374 setup_preset(spec, &alc262_presets[board_config]);
11376 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11377 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11379 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11380 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11382 spec->capture_style = CAPT_MIX;
11383 if (!spec->adc_nids && spec->input_mux) {
11384 /* check whether NID 0x07 is valid */
11385 unsigned int wcap = get_wcaps(codec, 0x07);
11388 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11389 if (wcap != AC_WID_AUD_IN) {
11390 spec->adc_nids = alc262_adc_nids_alt;
11391 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11392 spec->capsrc_nids = alc262_capsrc_nids_alt;
11394 spec->adc_nids = alc262_adc_nids;
11395 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11396 spec->capsrc_nids = alc262_capsrc_nids;
11399 if (!spec->cap_mixer && !spec->no_analog)
11400 set_capture_mixer(spec);
11401 if (!spec->no_analog)
11402 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11404 spec->vmaster_nid = 0x0c;
11406 codec->patch_ops = alc_patch_ops;
11407 if (board_config == ALC262_AUTO)
11408 spec->init_hook = alc262_auto_init;
11409 #ifdef CONFIG_SND_HDA_POWER_SAVE
11410 if (!spec->loopback.amplist)
11411 spec->loopback.amplist = alc262_loopbacks;
11413 codec->proc_widget_hook = print_realtek_coef;
11419 * ALC268 channel source setting (2 channel)
11421 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11422 #define alc268_modes alc260_modes
11424 static hda_nid_t alc268_dac_nids[2] = {
11429 static hda_nid_t alc268_adc_nids[2] = {
11434 static hda_nid_t alc268_adc_nids_alt[1] = {
11439 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11441 static struct snd_kcontrol_new alc268_base_mixer[] = {
11442 /* output mixer control */
11443 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11444 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11448 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11449 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11453 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11454 /* output mixer control */
11455 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11456 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11457 ALC262_HIPPO_MASTER_SWITCH,
11458 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11459 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11460 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11464 /* bind Beep switches of both NID 0x0f and 0x10 */
11465 static struct hda_bind_ctls alc268_bind_beep_sw = {
11466 .ops = &snd_hda_bind_sw,
11468 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11469 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11474 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11475 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11476 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11480 static struct hda_verb alc268_eapd_verbs[] = {
11481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11482 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11486 /* Toshiba specific */
11487 static struct hda_verb alc268_toshiba_verbs[] = {
11488 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11492 static struct hda_input_mux alc268_acer_lc_capture_source = {
11500 /* Acer specific */
11501 /* bind volumes of both NID 0x02 and 0x03 */
11502 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11503 .ops = &snd_hda_bind_vol,
11505 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11506 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11511 /* mute/unmute internal speaker according to the hp jack and mute state */
11512 static void alc268_acer_automute(struct hda_codec *codec, int force)
11514 struct alc_spec *spec = codec->spec;
11517 if (force || !spec->sense_updated) {
11518 unsigned int present;
11519 present = snd_hda_codec_read(codec, 0x14, 0,
11520 AC_VERB_GET_PIN_SENSE, 0);
11521 spec->jack_present = (present & 0x80000000) != 0;
11522 spec->sense_updated = 1;
11524 if (spec->jack_present)
11525 mute = HDA_AMP_MUTE; /* mute internal speaker */
11526 else /* unmute internal speaker if necessary */
11527 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11528 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11529 HDA_AMP_MUTE, mute);
11533 /* bind hp and internal speaker mute (with plug check) */
11534 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11535 struct snd_ctl_elem_value *ucontrol)
11537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11538 long *valp = ucontrol->value.integer.value;
11541 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11543 valp[0] ? 0 : HDA_AMP_MUTE);
11544 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11546 valp[1] ? 0 : HDA_AMP_MUTE);
11548 alc268_acer_automute(codec, 0);
11552 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11553 /* output mixer control */
11554 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11557 .name = "Master Playback Switch",
11558 .info = snd_hda_mixer_amp_switch_info,
11559 .get = snd_hda_mixer_amp_switch_get,
11560 .put = alc268_acer_master_sw_put,
11561 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11563 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11567 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11568 /* output mixer control */
11569 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11572 .name = "Master Playback Switch",
11573 .info = snd_hda_mixer_amp_switch_info,
11574 .get = snd_hda_mixer_amp_switch_get,
11575 .put = alc268_acer_master_sw_put,
11576 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11578 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11579 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11580 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11584 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11585 /* output mixer control */
11586 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11588 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11589 .name = "Master Playback Switch",
11590 .info = snd_hda_mixer_amp_switch_info,
11591 .get = snd_hda_mixer_amp_switch_get,
11592 .put = alc268_acer_master_sw_put,
11593 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11595 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11596 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11600 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11601 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11603 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11604 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11605 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11606 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11610 static struct hda_verb alc268_acer_verbs[] = {
11611 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11612 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11614 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11615 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11617 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11621 /* unsolicited event for HP jack sensing */
11622 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11623 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11625 static void alc268_acer_unsol_event(struct hda_codec *codec,
11628 if ((res >> 26) != ALC880_HP_EVENT)
11630 alc268_acer_automute(codec, 1);
11633 static void alc268_acer_init_hook(struct hda_codec *codec)
11635 alc268_acer_automute(codec, 1);
11638 /* toggle speaker-output according to the hp-jack state */
11639 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11641 unsigned int present;
11642 unsigned char bits;
11644 present = snd_hda_codec_read(codec, 0x15, 0,
11645 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11646 bits = present ? AMP_IN_MUTE(0) : 0;
11647 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11648 AMP_IN_MUTE(0), bits);
11649 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11650 AMP_IN_MUTE(0), bits);
11654 static void alc268_acer_mic_automute(struct hda_codec *codec)
11656 unsigned int present;
11658 present = snd_hda_codec_read(codec, 0x18, 0,
11659 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11660 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11661 present ? 0x0 : 0x6);
11664 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11667 if ((res >> 26) == ALC880_HP_EVENT)
11668 alc268_aspire_one_speaker_automute(codec);
11669 if ((res >> 26) == ALC880_MIC_EVENT)
11670 alc268_acer_mic_automute(codec);
11673 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11675 alc268_aspire_one_speaker_automute(codec);
11676 alc268_acer_mic_automute(codec);
11679 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11680 /* output mixer control */
11681 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11682 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11685 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11686 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11690 static struct hda_verb alc268_dell_verbs[] = {
11691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11693 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11697 /* mute/unmute internal speaker according to the hp jack and mute state */
11698 static void alc268_dell_init_hook(struct hda_codec *codec)
11700 struct alc_spec *spec = codec->spec;
11702 spec->autocfg.hp_pins[0] = 0x15;
11703 spec->autocfg.speaker_pins[0] = 0x14;
11704 alc_automute_pin(codec);
11707 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11708 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11709 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11710 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11711 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11712 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11713 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11714 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11715 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11719 static struct hda_verb alc267_quanta_il1_verbs[] = {
11720 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11721 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11725 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11727 unsigned int present;
11729 present = snd_hda_codec_read(codec, 0x18, 0,
11730 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11731 snd_hda_codec_write(codec, 0x23, 0,
11732 AC_VERB_SET_CONNECT_SEL,
11733 present ? 0x00 : 0x01);
11736 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11738 struct alc_spec *spec = codec->spec;
11740 spec->autocfg.hp_pins[0] = 0x15;
11741 spec->autocfg.speaker_pins[0] = 0x14;
11742 alc_automute_pin(codec);
11743 alc267_quanta_il1_mic_automute(codec);
11746 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11749 switch (res >> 26) {
11750 case ALC880_MIC_EVENT:
11751 alc267_quanta_il1_mic_automute(codec);
11754 alc_sku_unsol_event(codec, res);
11760 * generic initialization of ADC, input mixers and output mixers
11762 static struct hda_verb alc268_base_init_verbs[] = {
11763 /* Unmute DAC0-1 and set vol = 0 */
11764 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11765 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11768 * Set up output mixers (0x0c - 0x0e)
11770 /* set vol=0 to output mixers */
11771 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11772 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11774 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11775 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11777 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11779 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11780 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11782 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11784 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11787 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11788 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11789 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11790 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11792 /* set PCBEEP vol = 0, mute connections */
11793 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11795 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11797 /* Unmute Selector 23h,24h and set the default input to mic-in */
11799 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11800 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11801 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11802 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11808 * generic initialization of ADC, input mixers and output mixers
11810 static struct hda_verb alc268_volume_init_verbs[] = {
11811 /* set output DAC */
11812 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11813 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11815 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11817 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11818 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11819 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11821 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11822 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11823 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11825 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11828 /* set PCBEEP vol = 0, mute connections */
11829 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11830 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11831 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11836 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11837 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11838 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11841 /* The multiple "Capture Source" controls confuse alsamixer
11842 * So call somewhat different..
11844 /* .name = "Capture Source", */
11845 .name = "Input Source",
11847 .info = alc_mux_enum_info,
11848 .get = alc_mux_enum_get,
11849 .put = alc_mux_enum_put,
11854 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11855 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11856 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11857 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11858 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11861 /* The multiple "Capture Source" controls confuse alsamixer
11862 * So call somewhat different..
11864 /* .name = "Capture Source", */
11865 .name = "Input Source",
11867 .info = alc_mux_enum_info,
11868 .get = alc_mux_enum_get,
11869 .put = alc_mux_enum_put,
11874 static struct hda_input_mux alc268_capture_source = {
11878 { "Front Mic", 0x1 },
11884 static struct hda_input_mux alc268_acer_capture_source = {
11888 { "Internal Mic", 0x1 },
11893 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11897 { "Internal Mic", 0x6 },
11902 #ifdef CONFIG_SND_DEBUG
11903 static struct snd_kcontrol_new alc268_test_mixer[] = {
11904 /* Volume widgets */
11905 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11906 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11907 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11908 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11909 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11910 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11911 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11912 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11913 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11914 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11915 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11916 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11917 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11918 /* The below appears problematic on some hardwares */
11919 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11920 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11921 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11922 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11923 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11925 /* Modes for retasking pin widgets */
11926 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11927 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11928 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11929 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11931 /* Controls for GPIO pins, assuming they are configured as outputs */
11932 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11933 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11934 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11935 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11937 /* Switches to allow the digital SPDIF output pin to be enabled.
11938 * The ALC268 does not have an SPDIF input.
11940 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11942 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11943 * this output to turn on an external amplifier.
11945 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11946 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11952 /* create input playback/capture controls for the given pin */
11953 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11954 const char *ctlname, int idx)
11959 sprintf(name, "%s Playback Volume", ctlname);
11961 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11962 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11966 } else if (nid == 0x15) {
11967 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11968 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11974 sprintf(name, "%s Playback Switch", ctlname);
11975 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11976 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11982 /* add playback controls from the parsed DAC table */
11983 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11984 const struct auto_pin_cfg *cfg)
11989 spec->multiout.num_dacs = 2; /* only use one dac */
11990 spec->multiout.dac_nids = spec->private_dac_nids;
11991 spec->multiout.dac_nids[0] = 2;
11992 spec->multiout.dac_nids[1] = 3;
11994 nid = cfg->line_out_pins[0];
11996 alc268_new_analog_output(spec, nid, "Front", 0);
11998 nid = cfg->speaker_pins[0];
12000 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12001 "Speaker Playback Volume",
12002 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12006 nid = cfg->hp_pins[0];
12008 alc268_new_analog_output(spec, nid, "Headphone", 0);
12010 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12012 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12013 "Mono Playback Switch",
12014 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
12021 /* create playback/capture controls for input pins */
12022 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
12023 const struct auto_pin_cfg *cfg)
12025 struct hda_input_mux *imux = &spec->private_imux[0];
12028 for (i = 0; i < AUTO_PIN_LAST; i++) {
12029 switch(cfg->input_pins[i]) {
12031 idx1 = 0; /* Mic 1 */
12034 idx1 = 1; /* Mic 2 */
12037 idx1 = 2; /* Line In */
12044 idx1 = 6; /* digital mics */
12049 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12050 imux->items[imux->num_items].index = idx1;
12056 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12058 struct alc_spec *spec = codec->spec;
12059 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12060 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12061 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12062 unsigned int dac_vol1, dac_vol2;
12065 snd_hda_codec_write(codec, speaker_nid, 0,
12066 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12067 snd_hda_codec_write(codec, 0x0f, 0,
12068 AC_VERB_SET_AMP_GAIN_MUTE,
12070 snd_hda_codec_write(codec, 0x10, 0,
12071 AC_VERB_SET_AMP_GAIN_MUTE,
12074 snd_hda_codec_write(codec, 0x0f, 0,
12075 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12076 snd_hda_codec_write(codec, 0x10, 0,
12077 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12080 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
12081 if (line_nid == 0x14)
12082 dac_vol2 = AMP_OUT_ZERO;
12083 else if (line_nid == 0x15)
12084 dac_vol1 = AMP_OUT_ZERO;
12085 if (hp_nid == 0x14)
12086 dac_vol2 = AMP_OUT_ZERO;
12087 else if (hp_nid == 0x15)
12088 dac_vol1 = AMP_OUT_ZERO;
12089 if (line_nid != 0x16 || hp_nid != 0x16 ||
12090 spec->autocfg.line_out_pins[1] != 0x16 ||
12091 spec->autocfg.line_out_pins[2] != 0x16)
12092 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12094 snd_hda_codec_write(codec, 0x02, 0,
12095 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12096 snd_hda_codec_write(codec, 0x03, 0,
12097 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12100 /* pcm configuration: identiacal with ALC880 */
12101 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12102 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12103 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12104 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12107 * BIOS auto configuration
12109 static int alc268_parse_auto_config(struct hda_codec *codec)
12111 struct alc_spec *spec = codec->spec;
12113 static hda_nid_t alc268_ignore[] = { 0 };
12115 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12119 if (!spec->autocfg.line_outs) {
12120 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12121 spec->multiout.max_channels = 2;
12122 spec->no_analog = 1;
12125 return 0; /* can't find valid BIOS pin config */
12127 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12130 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
12134 spec->multiout.max_channels = 2;
12137 /* digital only support output */
12138 if (spec->autocfg.dig_outs) {
12139 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12140 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12142 if (spec->kctls.list)
12143 add_mixer(spec, spec->kctls.list);
12145 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12146 add_mixer(spec, alc268_beep_mixer);
12148 add_verb(spec, alc268_volume_init_verbs);
12149 spec->num_mux_defs = 1;
12150 spec->input_mux = &spec->private_imux[0];
12152 err = alc_auto_add_mic_boost(codec);
12159 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12160 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12161 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12163 /* init callback for auto-configuration model -- overriding the default init */
12164 static void alc268_auto_init(struct hda_codec *codec)
12166 struct alc_spec *spec = codec->spec;
12167 alc268_auto_init_multi_out(codec);
12168 alc268_auto_init_hp_out(codec);
12169 alc268_auto_init_mono_speaker_out(codec);
12170 alc268_auto_init_analog_input(codec);
12171 if (spec->unsol_event)
12172 alc_inithook(codec);
12176 * configuration and preset
12178 static const char *alc268_models[ALC268_MODEL_LAST] = {
12179 [ALC267_QUANTA_IL1] = "quanta-il1",
12180 [ALC268_3ST] = "3stack",
12181 [ALC268_TOSHIBA] = "toshiba",
12182 [ALC268_ACER] = "acer",
12183 [ALC268_ACER_DMIC] = "acer-dmic",
12184 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12185 [ALC268_DELL] = "dell",
12186 [ALC268_ZEPTO] = "zepto",
12187 #ifdef CONFIG_SND_DEBUG
12188 [ALC268_TEST] = "test",
12190 [ALC268_AUTO] = "auto",
12193 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12194 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12195 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12196 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12197 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12198 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12199 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12200 ALC268_ACER_ASPIRE_ONE),
12201 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12202 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12203 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12205 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12206 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12207 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12209 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12210 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12211 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12212 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12216 static struct alc_config_preset alc268_presets[] = {
12217 [ALC267_QUANTA_IL1] = {
12218 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12219 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12220 alc267_quanta_il1_verbs },
12221 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12222 .dac_nids = alc268_dac_nids,
12223 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12224 .adc_nids = alc268_adc_nids_alt,
12226 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12227 .channel_mode = alc268_modes,
12228 .input_mux = &alc268_capture_source,
12229 .unsol_event = alc267_quanta_il1_unsol_event,
12230 .init_hook = alc267_quanta_il1_init_hook,
12233 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12234 alc268_beep_mixer },
12235 .init_verbs = { alc268_base_init_verbs },
12236 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12237 .dac_nids = alc268_dac_nids,
12238 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12239 .adc_nids = alc268_adc_nids_alt,
12240 .capsrc_nids = alc268_capsrc_nids,
12242 .dig_out_nid = ALC268_DIGOUT_NID,
12243 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12244 .channel_mode = alc268_modes,
12245 .input_mux = &alc268_capture_source,
12247 [ALC268_TOSHIBA] = {
12248 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12249 alc268_beep_mixer },
12250 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12251 alc268_toshiba_verbs },
12252 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12253 .dac_nids = alc268_dac_nids,
12254 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12255 .adc_nids = alc268_adc_nids_alt,
12256 .capsrc_nids = alc268_capsrc_nids,
12258 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12259 .channel_mode = alc268_modes,
12260 .input_mux = &alc268_capture_source,
12261 .unsol_event = alc268_toshiba_unsol_event,
12262 .init_hook = alc268_toshiba_init_hook,
12265 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12266 alc268_beep_mixer },
12267 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12268 alc268_acer_verbs },
12269 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12270 .dac_nids = alc268_dac_nids,
12271 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12272 .adc_nids = alc268_adc_nids_alt,
12273 .capsrc_nids = alc268_capsrc_nids,
12275 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12276 .channel_mode = alc268_modes,
12277 .input_mux = &alc268_acer_capture_source,
12278 .unsol_event = alc268_acer_unsol_event,
12279 .init_hook = alc268_acer_init_hook,
12281 [ALC268_ACER_DMIC] = {
12282 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12283 alc268_beep_mixer },
12284 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12285 alc268_acer_verbs },
12286 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12287 .dac_nids = alc268_dac_nids,
12288 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12289 .adc_nids = alc268_adc_nids_alt,
12290 .capsrc_nids = alc268_capsrc_nids,
12292 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12293 .channel_mode = alc268_modes,
12294 .input_mux = &alc268_acer_dmic_capture_source,
12295 .unsol_event = alc268_acer_unsol_event,
12296 .init_hook = alc268_acer_init_hook,
12298 [ALC268_ACER_ASPIRE_ONE] = {
12299 .mixers = { alc268_acer_aspire_one_mixer,
12301 alc268_capture_alt_mixer },
12302 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12303 alc268_acer_aspire_one_verbs },
12304 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12305 .dac_nids = alc268_dac_nids,
12306 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12307 .adc_nids = alc268_adc_nids_alt,
12308 .capsrc_nids = alc268_capsrc_nids,
12310 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12311 .channel_mode = alc268_modes,
12312 .input_mux = &alc268_acer_lc_capture_source,
12313 .unsol_event = alc268_acer_lc_unsol_event,
12314 .init_hook = alc268_acer_lc_init_hook,
12317 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12318 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12319 alc268_dell_verbs },
12320 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12321 .dac_nids = alc268_dac_nids,
12323 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12324 .channel_mode = alc268_modes,
12325 .unsol_event = alc_sku_unsol_event,
12326 .init_hook = alc268_dell_init_hook,
12327 .input_mux = &alc268_capture_source,
12330 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12331 alc268_beep_mixer },
12332 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12333 alc268_toshiba_verbs },
12334 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12335 .dac_nids = alc268_dac_nids,
12336 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12337 .adc_nids = alc268_adc_nids_alt,
12338 .capsrc_nids = alc268_capsrc_nids,
12340 .dig_out_nid = ALC268_DIGOUT_NID,
12341 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12342 .channel_mode = alc268_modes,
12343 .input_mux = &alc268_capture_source,
12344 .unsol_event = alc268_toshiba_unsol_event,
12345 .init_hook = alc268_toshiba_init_hook
12347 #ifdef CONFIG_SND_DEBUG
12349 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12350 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12351 alc268_volume_init_verbs },
12352 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12353 .dac_nids = alc268_dac_nids,
12354 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12355 .adc_nids = alc268_adc_nids_alt,
12356 .capsrc_nids = alc268_capsrc_nids,
12358 .dig_out_nid = ALC268_DIGOUT_NID,
12359 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12360 .channel_mode = alc268_modes,
12361 .input_mux = &alc268_capture_source,
12366 static int patch_alc268(struct hda_codec *codec)
12368 struct alc_spec *spec;
12370 int i, has_beep, err;
12372 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12376 codec->spec = spec;
12378 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12382 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12383 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12384 "trying auto-probe from BIOS...\n", codec->chip_name);
12385 board_config = ALC268_AUTO;
12388 if (board_config == ALC268_AUTO) {
12389 /* automatic parse from the BIOS config */
12390 err = alc268_parse_auto_config(codec);
12396 "hda_codec: Cannot set up configuration "
12397 "from BIOS. Using base mode...\n");
12398 board_config = ALC268_3ST;
12402 if (board_config != ALC268_AUTO)
12403 setup_preset(spec, &alc268_presets[board_config]);
12405 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12406 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12407 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12409 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12412 for (i = 0; i < spec->num_mixers; i++) {
12413 if (spec->mixers[i] == alc268_beep_mixer) {
12420 err = snd_hda_attach_beep_device(codec, 0x1);
12425 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12426 /* override the amp caps for beep generator */
12427 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12428 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12429 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12430 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12431 (0 << AC_AMPCAP_MUTE_SHIFT));
12434 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12435 /* check whether NID 0x07 is valid */
12436 unsigned int wcap = get_wcaps(codec, 0x07);
12440 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12441 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12442 spec->adc_nids = alc268_adc_nids_alt;
12443 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12444 add_mixer(spec, alc268_capture_alt_mixer);
12446 spec->adc_nids = alc268_adc_nids;
12447 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12448 add_mixer(spec, alc268_capture_mixer);
12450 spec->capsrc_nids = alc268_capsrc_nids;
12451 /* set default input source */
12452 for (i = 0; i < spec->num_adc_nids; i++)
12453 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12454 0, AC_VERB_SET_CONNECT_SEL,
12455 spec->input_mux->items[0].index);
12458 spec->vmaster_nid = 0x02;
12460 codec->patch_ops = alc_patch_ops;
12461 if (board_config == ALC268_AUTO)
12462 spec->init_hook = alc268_auto_init;
12464 codec->proc_widget_hook = print_realtek_coef;
12470 * ALC269 channel source setting (2 channel)
12472 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12474 #define alc269_dac_nids alc260_dac_nids
12476 static hda_nid_t alc269_adc_nids[1] = {
12481 static hda_nid_t alc269_capsrc_nids[1] = {
12485 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12489 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12497 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12505 #define alc269_modes alc260_modes
12506 #define alc269_capture_source alc880_lg_lw_capture_source
12508 static struct snd_kcontrol_new alc269_base_mixer[] = {
12509 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12510 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12511 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12512 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12516 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12517 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12518 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12520 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12524 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12525 /* output mixer control */
12526 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12529 .name = "Master Playback Switch",
12530 .info = snd_hda_mixer_amp_switch_info,
12531 .get = snd_hda_mixer_amp_switch_get,
12532 .put = alc268_acer_master_sw_put,
12533 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12537 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12538 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12539 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12540 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12544 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12545 /* output mixer control */
12546 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12549 .name = "Master Playback Switch",
12550 .info = snd_hda_mixer_amp_switch_info,
12551 .get = snd_hda_mixer_amp_switch_get,
12552 .put = alc268_acer_master_sw_put,
12553 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12555 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12556 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12557 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12558 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12559 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12560 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12561 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12562 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12563 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12567 /* bind volumes of both NID 0x0c and 0x0d */
12568 static struct hda_bind_ctls alc269_epc_bind_vol = {
12569 .ops = &snd_hda_bind_vol,
12571 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12572 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12577 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12578 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12579 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12580 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12584 /* capture mixer elements */
12585 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12586 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12587 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12588 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12593 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12594 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12596 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12600 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12602 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12604 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12605 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12606 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12610 static struct hda_verb alc269_lifebook_verbs[] = {
12611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12613 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12614 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12615 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12616 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12618 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12619 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12620 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12624 /* toggle speaker-output according to the hp-jack state */
12625 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12627 unsigned int present;
12628 unsigned char bits;
12630 present = snd_hda_codec_read(codec, 0x15, 0,
12631 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12632 bits = present ? AMP_IN_MUTE(0) : 0;
12633 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12634 AMP_IN_MUTE(0), bits);
12635 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12636 AMP_IN_MUTE(0), bits);
12638 snd_hda_codec_write(codec, 0x20, 0,
12639 AC_VERB_SET_COEF_INDEX, 0x0c);
12640 snd_hda_codec_write(codec, 0x20, 0,
12641 AC_VERB_SET_PROC_COEF, 0x680);
12643 snd_hda_codec_write(codec, 0x20, 0,
12644 AC_VERB_SET_COEF_INDEX, 0x0c);
12645 snd_hda_codec_write(codec, 0x20, 0,
12646 AC_VERB_SET_PROC_COEF, 0x480);
12649 /* toggle speaker-output according to the hp-jacks state */
12650 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12652 unsigned int present;
12653 unsigned char bits;
12655 /* Check laptop headphone socket */
12656 present = snd_hda_codec_read(codec, 0x15, 0,
12657 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12659 /* Check port replicator headphone socket */
12660 present |= snd_hda_codec_read(codec, 0x1a, 0,
12661 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12663 bits = present ? AMP_IN_MUTE(0) : 0;
12664 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12665 AMP_IN_MUTE(0), bits);
12666 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12667 AMP_IN_MUTE(0), bits);
12669 snd_hda_codec_write(codec, 0x20, 0,
12670 AC_VERB_SET_COEF_INDEX, 0x0c);
12671 snd_hda_codec_write(codec, 0x20, 0,
12672 AC_VERB_SET_PROC_COEF, 0x680);
12674 snd_hda_codec_write(codec, 0x20, 0,
12675 AC_VERB_SET_COEF_INDEX, 0x0c);
12676 snd_hda_codec_write(codec, 0x20, 0,
12677 AC_VERB_SET_PROC_COEF, 0x480);
12680 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12682 unsigned int present;
12684 present = snd_hda_codec_read(codec, 0x18, 0,
12685 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12686 snd_hda_codec_write(codec, 0x23, 0,
12687 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12690 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12692 unsigned int present_laptop;
12693 unsigned int present_dock;
12695 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12696 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12698 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12699 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12701 /* Laptop mic port overrides dock mic port, design decision */
12703 snd_hda_codec_write(codec, 0x23, 0,
12704 AC_VERB_SET_CONNECT_SEL, 0x3);
12705 if (present_laptop)
12706 snd_hda_codec_write(codec, 0x23, 0,
12707 AC_VERB_SET_CONNECT_SEL, 0x0);
12708 if (!present_dock && !present_laptop)
12709 snd_hda_codec_write(codec, 0x23, 0,
12710 AC_VERB_SET_CONNECT_SEL, 0x1);
12713 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12716 if ((res >> 26) == ALC880_HP_EVENT)
12717 alc269_quanta_fl1_speaker_automute(codec);
12718 if ((res >> 26) == ALC880_MIC_EVENT)
12719 alc269_quanta_fl1_mic_automute(codec);
12722 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12725 if ((res >> 26) == ALC880_HP_EVENT)
12726 alc269_lifebook_speaker_automute(codec);
12727 if ((res >> 26) == ALC880_MIC_EVENT)
12728 alc269_lifebook_mic_autoswitch(codec);
12731 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12733 alc269_quanta_fl1_speaker_automute(codec);
12734 alc269_quanta_fl1_mic_automute(codec);
12737 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12739 alc269_lifebook_speaker_automute(codec);
12740 alc269_lifebook_mic_autoswitch(codec);
12743 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12744 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12745 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12746 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12748 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12749 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12750 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12754 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12756 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12757 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12758 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12759 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12760 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12764 /* toggle speaker-output according to the hp-jack state */
12765 static void alc269_speaker_automute(struct hda_codec *codec)
12767 unsigned int present;
12768 unsigned char bits;
12770 present = snd_hda_codec_read(codec, 0x15, 0,
12771 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12772 bits = present ? AMP_IN_MUTE(0) : 0;
12773 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12774 AMP_IN_MUTE(0), bits);
12775 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12776 AMP_IN_MUTE(0), bits);
12779 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12781 unsigned int present;
12783 present = snd_hda_codec_read(codec, 0x18, 0,
12784 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12785 snd_hda_codec_write(codec, 0x23, 0,
12786 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12789 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12791 unsigned int present;
12793 present = snd_hda_codec_read(codec, 0x18, 0,
12794 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12795 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12796 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12797 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12798 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12801 /* unsolicited event for HP jack sensing */
12802 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12805 if ((res >> 26) == ALC880_HP_EVENT)
12806 alc269_speaker_automute(codec);
12808 if ((res >> 26) == ALC880_MIC_EVENT)
12809 alc269_eeepc_dmic_automute(codec);
12812 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12814 alc269_speaker_automute(codec);
12815 alc269_eeepc_dmic_automute(codec);
12818 /* unsolicited event for HP jack sensing */
12819 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12822 if ((res >> 26) == ALC880_HP_EVENT)
12823 alc269_speaker_automute(codec);
12825 if ((res >> 26) == ALC880_MIC_EVENT)
12826 alc269_eeepc_amic_automute(codec);
12829 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12831 alc269_speaker_automute(codec);
12832 alc269_eeepc_amic_automute(codec);
12836 * generic initialization of ADC, input mixers and output mixers
12838 static struct hda_verb alc269_init_verbs[] = {
12840 * Unmute ADC0 and set the default input to mic-in
12842 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12844 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12845 * analog-loopback mixer widget
12846 * Note: PASD motherboards uses the Line In 2 as the input for
12847 * front panel mic (mic 2)
12849 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12853 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12854 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12857 * Set up output mixers (0x0c - 0x0e)
12859 /* set vol=0 to output mixers */
12860 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12861 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12863 /* set up input amps for analog loopback */
12864 /* Amp Indices: DAC = 0, mixer = 1 */
12865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12866 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12869 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12870 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12873 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12874 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12877 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12880 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12881 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12883 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12884 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12886 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12888 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12889 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12891 /* FIXME: use matrix-type input source selection */
12892 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12893 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12900 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12901 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12905 /* add playback controls from the parsed DAC table */
12906 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12907 const struct auto_pin_cfg *cfg)
12912 spec->multiout.num_dacs = 1; /* only use one dac */
12913 spec->multiout.dac_nids = spec->private_dac_nids;
12914 spec->multiout.dac_nids[0] = 2;
12916 nid = cfg->line_out_pins[0];
12918 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12919 "Front Playback Volume",
12920 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12923 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12924 "Front Playback Switch",
12925 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12930 nid = cfg->speaker_pins[0];
12932 if (!cfg->line_out_pins[0]) {
12933 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12934 "Speaker Playback Volume",
12935 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12941 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12942 "Speaker Playback Switch",
12943 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12948 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12949 "Speaker Playback Switch",
12950 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12956 nid = cfg->hp_pins[0];
12958 /* spec->multiout.hp_nid = 2; */
12959 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12960 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12961 "Headphone Playback Volume",
12962 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12968 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12969 "Headphone Playback Switch",
12970 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12975 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12976 "Headphone Playback Switch",
12977 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12986 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12987 const struct auto_pin_cfg *cfg)
12991 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12994 /* digital-mic input pin is excluded in alc880_auto_create..()
12995 * because it's under 0x18
12997 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12998 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12999 struct hda_input_mux *imux = &spec->private_imux[0];
13000 imux->items[imux->num_items].label = "Int Mic";
13001 imux->items[imux->num_items].index = 0x05;
13007 #ifdef CONFIG_SND_HDA_POWER_SAVE
13008 #define alc269_loopbacks alc880_loopbacks
13011 /* pcm configuration: identiacal with ALC880 */
13012 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
13013 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
13014 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
13015 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
13017 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13021 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13022 /* NID is set in alc_build_pcms */
13024 .open = alc880_playback_pcm_open,
13025 .prepare = alc880_playback_pcm_prepare,
13026 .cleanup = alc880_playback_pcm_cleanup
13030 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13034 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13035 /* NID is set in alc_build_pcms */
13039 * BIOS auto configuration
13041 static int alc269_parse_auto_config(struct hda_codec *codec)
13043 struct alc_spec *spec = codec->spec;
13045 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13047 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13052 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13055 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
13059 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13061 if (spec->autocfg.dig_outs)
13062 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13064 if (spec->kctls.list)
13065 add_mixer(spec, spec->kctls.list);
13067 add_verb(spec, alc269_init_verbs);
13068 spec->num_mux_defs = 1;
13069 spec->input_mux = &spec->private_imux[0];
13070 /* set default input source */
13071 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13072 0, AC_VERB_SET_CONNECT_SEL,
13073 spec->input_mux->items[0].index);
13075 err = alc_auto_add_mic_boost(codec);
13079 if (!spec->cap_mixer && !spec->no_analog)
13080 set_capture_mixer(spec);
13085 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
13086 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
13087 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13090 /* init callback for auto-configuration model -- overriding the default init */
13091 static void alc269_auto_init(struct hda_codec *codec)
13093 struct alc_spec *spec = codec->spec;
13094 alc269_auto_init_multi_out(codec);
13095 alc269_auto_init_hp_out(codec);
13096 alc269_auto_init_analog_input(codec);
13097 if (spec->unsol_event)
13098 alc_inithook(codec);
13102 * configuration and preset
13104 static const char *alc269_models[ALC269_MODEL_LAST] = {
13105 [ALC269_BASIC] = "basic",
13106 [ALC269_QUANTA_FL1] = "quanta",
13107 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13108 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13109 [ALC269_FUJITSU] = "fujitsu",
13110 [ALC269_LIFEBOOK] = "lifebook"
13113 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13114 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13115 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13116 ALC269_ASUS_EEEPC_P703),
13117 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13118 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13119 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13120 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13121 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13122 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13123 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13124 ALC269_ASUS_EEEPC_P901),
13125 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13126 ALC269_ASUS_EEEPC_P901),
13127 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13128 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13129 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13133 static struct alc_config_preset alc269_presets[] = {
13135 .mixers = { alc269_base_mixer },
13136 .init_verbs = { alc269_init_verbs },
13137 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13138 .dac_nids = alc269_dac_nids,
13140 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13141 .channel_mode = alc269_modes,
13142 .input_mux = &alc269_capture_source,
13144 [ALC269_QUANTA_FL1] = {
13145 .mixers = { alc269_quanta_fl1_mixer },
13146 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13147 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13148 .dac_nids = alc269_dac_nids,
13150 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13151 .channel_mode = alc269_modes,
13152 .input_mux = &alc269_capture_source,
13153 .unsol_event = alc269_quanta_fl1_unsol_event,
13154 .init_hook = alc269_quanta_fl1_init_hook,
13156 [ALC269_ASUS_EEEPC_P703] = {
13157 .mixers = { alc269_eeepc_mixer },
13158 .cap_mixer = alc269_epc_capture_mixer,
13159 .init_verbs = { alc269_init_verbs,
13160 alc269_eeepc_amic_init_verbs },
13161 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13162 .dac_nids = alc269_dac_nids,
13164 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13165 .channel_mode = alc269_modes,
13166 .input_mux = &alc269_eeepc_amic_capture_source,
13167 .unsol_event = alc269_eeepc_amic_unsol_event,
13168 .init_hook = alc269_eeepc_amic_inithook,
13170 [ALC269_ASUS_EEEPC_P901] = {
13171 .mixers = { alc269_eeepc_mixer },
13172 .cap_mixer = alc269_epc_capture_mixer,
13173 .init_verbs = { alc269_init_verbs,
13174 alc269_eeepc_dmic_init_verbs },
13175 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13176 .dac_nids = alc269_dac_nids,
13178 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13179 .channel_mode = alc269_modes,
13180 .input_mux = &alc269_eeepc_dmic_capture_source,
13181 .unsol_event = alc269_eeepc_dmic_unsol_event,
13182 .init_hook = alc269_eeepc_dmic_inithook,
13184 [ALC269_FUJITSU] = {
13185 .mixers = { alc269_fujitsu_mixer },
13186 .cap_mixer = alc269_epc_capture_mixer,
13187 .init_verbs = { alc269_init_verbs,
13188 alc269_eeepc_dmic_init_verbs },
13189 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13190 .dac_nids = alc269_dac_nids,
13192 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13193 .channel_mode = alc269_modes,
13194 .input_mux = &alc269_eeepc_dmic_capture_source,
13195 .unsol_event = alc269_eeepc_dmic_unsol_event,
13196 .init_hook = alc269_eeepc_dmic_inithook,
13198 [ALC269_LIFEBOOK] = {
13199 .mixers = { alc269_lifebook_mixer },
13200 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13201 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13202 .dac_nids = alc269_dac_nids,
13204 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13205 .channel_mode = alc269_modes,
13206 .input_mux = &alc269_capture_source,
13207 .unsol_event = alc269_lifebook_unsol_event,
13208 .init_hook = alc269_lifebook_init_hook,
13212 static int patch_alc269(struct hda_codec *codec)
13214 struct alc_spec *spec;
13218 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13222 codec->spec = spec;
13224 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13226 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13230 if (board_config < 0) {
13231 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13232 "trying auto-probe from BIOS...\n", codec->chip_name);
13233 board_config = ALC269_AUTO;
13236 if (board_config == ALC269_AUTO) {
13237 /* automatic parse from the BIOS config */
13238 err = alc269_parse_auto_config(codec);
13244 "hda_codec: Cannot set up configuration "
13245 "from BIOS. Using base mode...\n");
13246 board_config = ALC269_BASIC;
13250 err = snd_hda_attach_beep_device(codec, 0x1);
13256 if (board_config != ALC269_AUTO)
13257 setup_preset(spec, &alc269_presets[board_config]);
13259 if (codec->subsystem_id == 0x17aa3bf8) {
13260 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13261 * fix the sample rate of analog I/O to 44.1kHz
13263 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13264 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13266 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13267 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13269 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13270 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13272 spec->adc_nids = alc269_adc_nids;
13273 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13274 spec->capsrc_nids = alc269_capsrc_nids;
13275 if (!spec->cap_mixer)
13276 set_capture_mixer(spec);
13277 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13279 codec->patch_ops = alc_patch_ops;
13280 if (board_config == ALC269_AUTO)
13281 spec->init_hook = alc269_auto_init;
13282 #ifdef CONFIG_SND_HDA_POWER_SAVE
13283 if (!spec->loopback.amplist)
13284 spec->loopback.amplist = alc269_loopbacks;
13286 codec->proc_widget_hook = print_realtek_coef;
13292 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13296 * set the path ways for 2 channel output
13297 * need to set the codec line out and mic 1 pin widgets to inputs
13299 static struct hda_verb alc861_threestack_ch2_init[] = {
13300 /* set pin widget 1Ah (line in) for input */
13301 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13302 /* set pin widget 18h (mic1/2) for input, for mic also enable
13305 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13307 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13309 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13310 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13316 * need to set the codec line out and mic 1 pin widgets to outputs
13318 static struct hda_verb alc861_threestack_ch6_init[] = {
13319 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13320 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13321 /* set pin widget 18h (mic1) for output (CLFE)*/
13322 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13324 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13325 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13327 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13329 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13330 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13335 static struct hda_channel_mode alc861_threestack_modes[2] = {
13336 { 2, alc861_threestack_ch2_init },
13337 { 6, alc861_threestack_ch6_init },
13339 /* Set mic1 as input and unmute the mixer */
13340 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13341 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13342 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13345 /* Set mic1 as output and mute mixer */
13346 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13347 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13348 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13352 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13353 { 2, alc861_uniwill_m31_ch2_init },
13354 { 4, alc861_uniwill_m31_ch4_init },
13357 /* Set mic1 and line-in as input and unmute the mixer */
13358 static struct hda_verb alc861_asus_ch2_init[] = {
13359 /* set pin widget 1Ah (line in) for input */
13360 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13361 /* set pin widget 18h (mic1/2) for input, for mic also enable
13364 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13368 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13369 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13373 /* Set mic1 nad line-in as output and mute mixer */
13374 static struct hda_verb alc861_asus_ch6_init[] = {
13375 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13376 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13377 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13378 /* set pin widget 18h (mic1) for output (CLFE)*/
13379 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13380 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13381 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13382 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13384 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13386 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13392 static struct hda_channel_mode alc861_asus_modes[2] = {
13393 { 2, alc861_asus_ch2_init },
13394 { 6, alc861_asus_ch6_init },
13399 static struct snd_kcontrol_new alc861_base_mixer[] = {
13400 /* output mixer control */
13401 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13404 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13405 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13407 /*Input mixer control */
13408 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13409 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13410 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13411 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13412 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13413 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13414 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13415 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13416 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13417 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13422 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13423 /* output mixer control */
13424 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13425 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13426 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13427 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13428 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13430 /* Input mixer control */
13431 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13432 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13433 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13434 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13436 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13438 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13439 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13444 .name = "Channel Mode",
13445 .info = alc_ch_mode_info,
13446 .get = alc_ch_mode_get,
13447 .put = alc_ch_mode_put,
13448 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13453 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13454 /* output mixer control */
13455 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13457 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13462 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13463 /* output mixer control */
13464 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13465 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13466 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13467 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13468 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13470 /* Input mixer control */
13471 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13472 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13473 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13474 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13475 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13476 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13478 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13479 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13484 .name = "Channel Mode",
13485 .info = alc_ch_mode_info,
13486 .get = alc_ch_mode_get,
13487 .put = alc_ch_mode_put,
13488 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13493 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13494 /* output mixer control */
13495 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13496 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13497 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13498 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13499 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13501 /* Input mixer control */
13502 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13503 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13504 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13505 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13506 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13507 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13509 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13510 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13511 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13515 .name = "Channel Mode",
13516 .info = alc_ch_mode_info,
13517 .get = alc_ch_mode_get,
13518 .put = alc_ch_mode_put,
13519 .private_value = ARRAY_SIZE(alc861_asus_modes),
13524 /* additional mixer */
13525 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13526 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13527 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13532 * generic initialization of ADC, input mixers and output mixers
13534 static struct hda_verb alc861_base_init_verbs[] = {
13536 * Unmute ADC0 and set the default input to mic-in
13538 /* port-A for surround (rear panel) */
13539 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13540 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13541 /* port-B for mic-in (rear panel) with vref */
13542 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13543 /* port-C for line-in (rear panel) */
13544 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13545 /* port-D for Front */
13546 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13547 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13548 /* port-E for HP out (front panel) */
13549 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13550 /* route front PCM to HP */
13551 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13552 /* port-F for mic-in (front panel) with vref */
13553 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13554 /* port-G for CLFE (rear panel) */
13555 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13556 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13557 /* port-H for side (rear panel) */
13558 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13559 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13561 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13562 /* route front mic to ADC1*/
13563 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13564 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13566 /* Unmute DAC0~3 & spdif out*/
13567 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13568 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13570 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13573 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13574 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13575 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13576 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13577 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13579 /* Unmute Stereo Mixer 15 */
13580 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13581 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13582 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13585 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13586 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13587 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13588 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13589 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13590 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13591 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13592 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13593 /* hp used DAC 3 (Front) */
13594 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13595 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13600 static struct hda_verb alc861_threestack_init_verbs[] = {
13602 * Unmute ADC0 and set the default input to mic-in
13604 /* port-A for surround (rear panel) */
13605 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13606 /* port-B for mic-in (rear panel) with vref */
13607 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13608 /* port-C for line-in (rear panel) */
13609 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13610 /* port-D for Front */
13611 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13612 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13613 /* port-E for HP out (front panel) */
13614 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13615 /* route front PCM to HP */
13616 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13617 /* port-F for mic-in (front panel) with vref */
13618 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13619 /* port-G for CLFE (rear panel) */
13620 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13621 /* port-H for side (rear panel) */
13622 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13624 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13625 /* route front mic to ADC1*/
13626 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13627 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13628 /* Unmute DAC0~3 & spdif out*/
13629 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13630 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13631 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13632 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13633 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13635 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13636 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13637 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13638 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13639 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13641 /* Unmute Stereo Mixer 15 */
13642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13648 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13649 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13650 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13652 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13655 /* hp used DAC 3 (Front) */
13656 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13661 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13663 * Unmute ADC0 and set the default input to mic-in
13665 /* port-A for surround (rear panel) */
13666 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13667 /* port-B for mic-in (rear panel) with vref */
13668 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13669 /* port-C for line-in (rear panel) */
13670 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13671 /* port-D for Front */
13672 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13673 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13674 /* port-E for HP out (front panel) */
13675 /* this has to be set to VREF80 */
13676 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13677 /* route front PCM to HP */
13678 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13679 /* port-F for mic-in (front panel) with vref */
13680 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13681 /* port-G for CLFE (rear panel) */
13682 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13683 /* port-H for side (rear panel) */
13684 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13686 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13687 /* route front mic to ADC1*/
13688 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13689 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13690 /* Unmute DAC0~3 & spdif out*/
13691 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13692 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13693 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13694 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13697 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13698 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13699 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13700 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13701 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13703 /* Unmute Stereo Mixer 15 */
13704 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13706 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13709 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13710 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13711 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13712 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13713 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13714 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13715 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13717 /* hp used DAC 3 (Front) */
13718 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13719 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13723 static struct hda_verb alc861_asus_init_verbs[] = {
13725 * Unmute ADC0 and set the default input to mic-in
13727 /* port-A for surround (rear panel)
13728 * according to codec#0 this is the HP jack
13730 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13731 /* route front PCM to HP */
13732 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13733 /* port-B for mic-in (rear panel) with vref */
13734 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13735 /* port-C for line-in (rear panel) */
13736 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13737 /* port-D for Front */
13738 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13739 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13740 /* port-E for HP out (front panel) */
13741 /* this has to be set to VREF80 */
13742 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13743 /* route front PCM to HP */
13744 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13745 /* port-F for mic-in (front panel) with vref */
13746 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13747 /* port-G for CLFE (rear panel) */
13748 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13749 /* port-H for side (rear panel) */
13750 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13752 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13753 /* route front mic to ADC1*/
13754 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13755 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13756 /* Unmute DAC0~3 & spdif out*/
13757 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13758 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13759 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13760 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13761 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13762 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13763 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13764 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13765 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13766 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13768 /* Unmute Stereo Mixer 15 */
13769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13775 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13776 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13777 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13778 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13780 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13782 /* hp used DAC 3 (Front) */
13783 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13788 /* additional init verbs for ASUS laptops */
13789 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13790 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13791 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13796 * generic initialization of ADC, input mixers and output mixers
13798 static struct hda_verb alc861_auto_init_verbs[] = {
13800 * Unmute ADC0 and set the default input to mic-in
13802 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13803 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13805 /* Unmute DAC0~3 & spdif out*/
13806 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13807 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13808 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13809 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13810 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13812 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13813 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13814 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13815 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13816 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13818 /* Unmute Stereo Mixer 15 */
13819 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13821 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13824 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13826 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13829 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13830 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13833 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13835 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13836 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13838 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13840 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13842 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13847 static struct hda_verb alc861_toshiba_init_verbs[] = {
13848 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13853 /* toggle speaker-output according to the hp-jack state */
13854 static void alc861_toshiba_automute(struct hda_codec *codec)
13856 unsigned int present;
13858 present = snd_hda_codec_read(codec, 0x0f, 0,
13859 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13860 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13861 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13862 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13863 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13866 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13869 if ((res >> 26) == ALC880_HP_EVENT)
13870 alc861_toshiba_automute(codec);
13873 /* pcm configuration: identiacal with ALC880 */
13874 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13875 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13876 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13877 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13880 #define ALC861_DIGOUT_NID 0x07
13882 static struct hda_channel_mode alc861_8ch_modes[1] = {
13886 static hda_nid_t alc861_dac_nids[4] = {
13887 /* front, surround, clfe, side */
13888 0x03, 0x06, 0x05, 0x04
13891 static hda_nid_t alc660_dac_nids[3] = {
13892 /* front, clfe, surround */
13896 static hda_nid_t alc861_adc_nids[1] = {
13901 static struct hda_input_mux alc861_capture_source = {
13905 { "Front Mic", 0x3 },
13912 /* fill in the dac_nids table from the parsed pin configuration */
13913 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13914 const struct auto_pin_cfg *cfg)
13919 spec->multiout.dac_nids = spec->private_dac_nids;
13920 for (i = 0; i < cfg->line_outs; i++) {
13921 nid = cfg->line_out_pins[i];
13923 if (i >= ARRAY_SIZE(alc861_dac_nids))
13925 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13928 spec->multiout.num_dacs = cfg->line_outs;
13932 /* add playback controls from the parsed DAC table */
13933 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13934 const struct auto_pin_cfg *cfg)
13937 static const char *chname[4] = {
13938 "Front", "Surround", NULL /*CLFE*/, "Side"
13943 for (i = 0; i < cfg->line_outs; i++) {
13944 nid = spec->multiout.dac_nids[i];
13949 err = add_control(spec, ALC_CTL_BIND_MUTE,
13950 "Center Playback Switch",
13951 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13955 err = add_control(spec, ALC_CTL_BIND_MUTE,
13956 "LFE Playback Switch",
13957 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13962 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13964 if (nid == alc861_dac_nids[idx])
13966 sprintf(name, "%s Playback Switch", chname[idx]);
13967 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13968 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13977 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13985 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13987 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13988 "Headphone Playback Switch",
13989 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13992 spec->multiout.hp_nid = nid;
13997 /* create playback/capture controls for input pins */
13998 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13999 const struct auto_pin_cfg *cfg)
14001 struct hda_input_mux *imux = &spec->private_imux[0];
14002 int i, err, idx, idx1;
14004 for (i = 0; i < AUTO_PIN_LAST; i++) {
14005 switch (cfg->input_pins[i]) {
14008 idx = 2; /* Line In */
14012 idx = 2; /* Line In */
14016 idx = 1; /* Mic In */
14020 idx = 1; /* Mic In */
14030 err = new_analog_input(spec, cfg->input_pins[i],
14031 auto_pin_cfg_labels[i], idx, 0x15);
14035 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
14036 imux->items[imux->num_items].index = idx1;
14042 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14044 int pin_type, int dac_idx)
14046 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14048 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14052 static void alc861_auto_init_multi_out(struct hda_codec *codec)
14054 struct alc_spec *spec = codec->spec;
14057 for (i = 0; i < spec->autocfg.line_outs; i++) {
14058 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14059 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14061 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14062 spec->multiout.dac_nids[i]);
14066 static void alc861_auto_init_hp_out(struct hda_codec *codec)
14068 struct alc_spec *spec = codec->spec;
14071 pin = spec->autocfg.hp_pins[0];
14072 if (pin) /* connect to front */
14073 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
14074 spec->multiout.dac_nids[0]);
14075 pin = spec->autocfg.speaker_pins[0];
14077 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14080 static void alc861_auto_init_analog_input(struct hda_codec *codec)
14082 struct alc_spec *spec = codec->spec;
14085 for (i = 0; i < AUTO_PIN_LAST; i++) {
14086 hda_nid_t nid = spec->autocfg.input_pins[i];
14087 if (nid >= 0x0c && nid <= 0x11)
14088 alc_set_input_pin(codec, nid, i);
14092 /* parse the BIOS configuration and set up the alc_spec */
14093 /* return 1 if successful, 0 if the proper config is not found,
14094 * or a negative error code
14096 static int alc861_parse_auto_config(struct hda_codec *codec)
14098 struct alc_spec *spec = codec->spec;
14100 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14102 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14106 if (!spec->autocfg.line_outs)
14107 return 0; /* can't find valid BIOS pin config */
14109 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
14112 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
14115 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
14118 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
14122 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14124 if (spec->autocfg.dig_outs)
14125 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14127 if (spec->kctls.list)
14128 add_mixer(spec, spec->kctls.list);
14130 add_verb(spec, alc861_auto_init_verbs);
14132 spec->num_mux_defs = 1;
14133 spec->input_mux = &spec->private_imux[0];
14135 spec->adc_nids = alc861_adc_nids;
14136 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14137 set_capture_mixer(spec);
14139 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14144 /* additional initialization for auto-configuration model */
14145 static void alc861_auto_init(struct hda_codec *codec)
14147 struct alc_spec *spec = codec->spec;
14148 alc861_auto_init_multi_out(codec);
14149 alc861_auto_init_hp_out(codec);
14150 alc861_auto_init_analog_input(codec);
14151 if (spec->unsol_event)
14152 alc_inithook(codec);
14155 #ifdef CONFIG_SND_HDA_POWER_SAVE
14156 static struct hda_amp_list alc861_loopbacks[] = {
14157 { 0x15, HDA_INPUT, 0 },
14158 { 0x15, HDA_INPUT, 1 },
14159 { 0x15, HDA_INPUT, 2 },
14160 { 0x15, HDA_INPUT, 3 },
14167 * configuration and preset
14169 static const char *alc861_models[ALC861_MODEL_LAST] = {
14170 [ALC861_3ST] = "3stack",
14171 [ALC660_3ST] = "3stack-660",
14172 [ALC861_3ST_DIG] = "3stack-dig",
14173 [ALC861_6ST_DIG] = "6stack-dig",
14174 [ALC861_UNIWILL_M31] = "uniwill-m31",
14175 [ALC861_TOSHIBA] = "toshiba",
14176 [ALC861_ASUS] = "asus",
14177 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14178 [ALC861_AUTO] = "auto",
14181 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14182 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14183 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14184 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14185 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14186 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14187 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14188 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14189 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14190 * Any other models that need this preset?
14192 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14193 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14194 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14195 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14196 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14197 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14198 /* FIXME: the below seems conflict */
14199 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14200 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14201 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14205 static struct alc_config_preset alc861_presets[] = {
14207 .mixers = { alc861_3ST_mixer },
14208 .init_verbs = { alc861_threestack_init_verbs },
14209 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14210 .dac_nids = alc861_dac_nids,
14211 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14212 .channel_mode = alc861_threestack_modes,
14214 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14215 .adc_nids = alc861_adc_nids,
14216 .input_mux = &alc861_capture_source,
14218 [ALC861_3ST_DIG] = {
14219 .mixers = { alc861_base_mixer },
14220 .init_verbs = { alc861_threestack_init_verbs },
14221 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14222 .dac_nids = alc861_dac_nids,
14223 .dig_out_nid = ALC861_DIGOUT_NID,
14224 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14225 .channel_mode = alc861_threestack_modes,
14227 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14228 .adc_nids = alc861_adc_nids,
14229 .input_mux = &alc861_capture_source,
14231 [ALC861_6ST_DIG] = {
14232 .mixers = { alc861_base_mixer },
14233 .init_verbs = { alc861_base_init_verbs },
14234 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14235 .dac_nids = alc861_dac_nids,
14236 .dig_out_nid = ALC861_DIGOUT_NID,
14237 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14238 .channel_mode = alc861_8ch_modes,
14239 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14240 .adc_nids = alc861_adc_nids,
14241 .input_mux = &alc861_capture_source,
14244 .mixers = { alc861_3ST_mixer },
14245 .init_verbs = { alc861_threestack_init_verbs },
14246 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14247 .dac_nids = alc660_dac_nids,
14248 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14249 .channel_mode = alc861_threestack_modes,
14251 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14252 .adc_nids = alc861_adc_nids,
14253 .input_mux = &alc861_capture_source,
14255 [ALC861_UNIWILL_M31] = {
14256 .mixers = { alc861_uniwill_m31_mixer },
14257 .init_verbs = { alc861_uniwill_m31_init_verbs },
14258 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14259 .dac_nids = alc861_dac_nids,
14260 .dig_out_nid = ALC861_DIGOUT_NID,
14261 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14262 .channel_mode = alc861_uniwill_m31_modes,
14264 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14265 .adc_nids = alc861_adc_nids,
14266 .input_mux = &alc861_capture_source,
14268 [ALC861_TOSHIBA] = {
14269 .mixers = { alc861_toshiba_mixer },
14270 .init_verbs = { alc861_base_init_verbs,
14271 alc861_toshiba_init_verbs },
14272 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14273 .dac_nids = alc861_dac_nids,
14274 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14275 .channel_mode = alc883_3ST_2ch_modes,
14276 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14277 .adc_nids = alc861_adc_nids,
14278 .input_mux = &alc861_capture_source,
14279 .unsol_event = alc861_toshiba_unsol_event,
14280 .init_hook = alc861_toshiba_automute,
14283 .mixers = { alc861_asus_mixer },
14284 .init_verbs = { alc861_asus_init_verbs },
14285 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14286 .dac_nids = alc861_dac_nids,
14287 .dig_out_nid = ALC861_DIGOUT_NID,
14288 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14289 .channel_mode = alc861_asus_modes,
14292 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14293 .adc_nids = alc861_adc_nids,
14294 .input_mux = &alc861_capture_source,
14296 [ALC861_ASUS_LAPTOP] = {
14297 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14298 .init_verbs = { alc861_asus_init_verbs,
14299 alc861_asus_laptop_init_verbs },
14300 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14301 .dac_nids = alc861_dac_nids,
14302 .dig_out_nid = ALC861_DIGOUT_NID,
14303 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14304 .channel_mode = alc883_3ST_2ch_modes,
14306 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14307 .adc_nids = alc861_adc_nids,
14308 .input_mux = &alc861_capture_source,
14313 static int patch_alc861(struct hda_codec *codec)
14315 struct alc_spec *spec;
14319 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14323 codec->spec = spec;
14325 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14329 if (board_config < 0) {
14330 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14331 "trying auto-probe from BIOS...\n", codec->chip_name);
14332 board_config = ALC861_AUTO;
14335 if (board_config == ALC861_AUTO) {
14336 /* automatic parse from the BIOS config */
14337 err = alc861_parse_auto_config(codec);
14343 "hda_codec: Cannot set up configuration "
14344 "from BIOS. Using base mode...\n");
14345 board_config = ALC861_3ST_DIG;
14349 err = snd_hda_attach_beep_device(codec, 0x23);
14355 if (board_config != ALC861_AUTO)
14356 setup_preset(spec, &alc861_presets[board_config]);
14358 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14359 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14361 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14362 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14364 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14366 spec->vmaster_nid = 0x03;
14368 codec->patch_ops = alc_patch_ops;
14369 if (board_config == ALC861_AUTO)
14370 spec->init_hook = alc861_auto_init;
14371 #ifdef CONFIG_SND_HDA_POWER_SAVE
14372 if (!spec->loopback.amplist)
14373 spec->loopback.amplist = alc861_loopbacks;
14375 codec->proc_widget_hook = print_realtek_coef;
14381 * ALC861-VD support
14385 * In addition, an independent DAC
14387 #define ALC861VD_DIGOUT_NID 0x06
14389 static hda_nid_t alc861vd_dac_nids[4] = {
14390 /* front, surr, clfe, side surr */
14391 0x02, 0x03, 0x04, 0x05
14394 /* dac_nids for ALC660vd are in a different order - according to
14395 * Realtek's driver.
14396 * This should probably tesult in a different mixer for 6stack models
14397 * of ALC660vd codecs, but for now there is only 3stack mixer
14398 * - and it is the same as in 861vd.
14399 * adc_nids in ALC660vd are (is) the same as in 861vd
14401 static hda_nid_t alc660vd_dac_nids[3] = {
14402 /* front, rear, clfe, rear_surr */
14406 static hda_nid_t alc861vd_adc_nids[1] = {
14411 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14414 /* FIXME: should be a matrix-type input source selection */
14415 static struct hda_input_mux alc861vd_capture_source = {
14419 { "Front Mic", 0x1 },
14425 static struct hda_input_mux alc861vd_dallas_capture_source = {
14428 { "Ext Mic", 0x0 },
14429 { "Int Mic", 0x1 },
14433 static struct hda_input_mux alc861vd_hp_capture_source = {
14436 { "Front Mic", 0x0 },
14437 { "ATAPI Mic", 0x1 },
14444 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14451 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14452 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14453 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14454 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14455 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14462 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14463 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14464 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14465 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14466 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14470 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14471 { 6, alc861vd_6stack_ch6_init },
14472 { 8, alc861vd_6stack_ch8_init },
14475 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14478 .name = "Channel Mode",
14479 .info = alc_ch_mode_info,
14480 .get = alc_ch_mode_get,
14481 .put = alc_ch_mode_put,
14486 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14487 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14489 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14490 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14491 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14494 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14496 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14498 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14500 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14501 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14503 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14504 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14512 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14513 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14514 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14516 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14517 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14519 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14520 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14525 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14526 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14527 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14529 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14531 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14532 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14535 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14536 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14537 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14539 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14540 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14542 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14543 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14548 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14549 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14550 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14551 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14553 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14555 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14559 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14560 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14561 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14569 /* Pin assignment: Speaker=0x14, HP = 0x15,
14570 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14572 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14573 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14574 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14575 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14576 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14577 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14578 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14579 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14580 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14581 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14582 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14586 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14587 * Front Mic=0x18, ATAPI Mic = 0x19,
14589 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14590 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14591 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14592 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14593 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14595 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14596 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14597 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14603 * generic initialization of ADC, input mixers and output mixers
14605 static struct hda_verb alc861vd_volume_init_verbs[] = {
14607 * Unmute ADC0 and set the default input to mic-in
14609 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14610 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14612 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14613 * the analog-loopback mixer widget
14615 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14616 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14617 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14618 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14619 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14620 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14622 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14629 * Set up output mixers (0x02 - 0x05)
14631 /* set vol=0 to output mixers */
14632 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14633 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14634 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14635 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14637 /* set up input amps for analog loopback */
14638 /* Amp Indices: DAC = 0, mixer = 1 */
14639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14641 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14643 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14645 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14646 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14652 * 3-stack pin configuration:
14653 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14655 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14657 * Set pin mode and muting
14659 /* set front pin widgets 0x14 for output */
14660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14662 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14664 /* Mic (rear) pin: input vref at 80% */
14665 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14666 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14667 /* Front Mic pin: input vref at 80% */
14668 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14669 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14670 /* Line In pin: input */
14671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14672 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14673 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14676 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14677 /* CD pin widget for input */
14678 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14684 * 6-stack pin configuration:
14686 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14688 * Set pin mode and muting
14690 /* set front pin widgets 0x14 for output */
14691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14693 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14695 /* Rear Pin: output 1 (0x0d) */
14696 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14698 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14699 /* CLFE Pin: output 2 (0x0e) */
14700 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14701 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14702 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14703 /* Side Pin: output 3 (0x0f) */
14704 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14705 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14706 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14708 /* Mic (rear) pin: input vref at 80% */
14709 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14710 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14711 /* Front Mic pin: input vref at 80% */
14712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14714 /* Line In pin: input */
14715 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14716 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14717 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14719 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14720 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14721 /* CD pin widget for input */
14722 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14727 static struct hda_verb alc861vd_eapd_verbs[] = {
14728 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14732 static struct hda_verb alc660vd_eapd_verbs[] = {
14733 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14734 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14738 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14742 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14743 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14747 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14749 unsigned int present;
14750 unsigned char bits;
14752 present = snd_hda_codec_read(codec, 0x18, 0,
14753 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14754 bits = present ? HDA_AMP_MUTE : 0;
14755 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14756 HDA_AMP_MUTE, bits);
14759 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14761 struct alc_spec *spec = codec->spec;
14763 spec->autocfg.hp_pins[0] = 0x1b;
14764 spec->autocfg.speaker_pins[0] = 0x14;
14765 alc_automute_amp(codec);
14766 alc861vd_lenovo_mic_automute(codec);
14769 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14772 switch (res >> 26) {
14773 case ALC880_MIC_EVENT:
14774 alc861vd_lenovo_mic_automute(codec);
14777 alc_automute_amp_unsol_event(codec, res);
14782 static struct hda_verb alc861vd_dallas_verbs[] = {
14783 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14784 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14785 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14786 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14790 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14791 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14792 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14793 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14795 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14797 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14802 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14806 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14807 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14808 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14809 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14810 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14811 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14813 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14820 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14821 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14822 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14827 /* toggle speaker-output according to the hp-jack state */
14828 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14830 struct alc_spec *spec = codec->spec;
14832 spec->autocfg.hp_pins[0] = 0x15;
14833 spec->autocfg.speaker_pins[0] = 0x14;
14834 alc_automute_amp(codec);
14837 #ifdef CONFIG_SND_HDA_POWER_SAVE
14838 #define alc861vd_loopbacks alc880_loopbacks
14841 /* pcm configuration: identiacal with ALC880 */
14842 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14843 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14844 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14845 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14848 * configuration and preset
14850 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14851 [ALC660VD_3ST] = "3stack-660",
14852 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14853 [ALC660VD_ASUS_V1S] = "asus-v1s",
14854 [ALC861VD_3ST] = "3stack",
14855 [ALC861VD_3ST_DIG] = "3stack-digout",
14856 [ALC861VD_6ST_DIG] = "6stack-digout",
14857 [ALC861VD_LENOVO] = "lenovo",
14858 [ALC861VD_DALLAS] = "dallas",
14859 [ALC861VD_HP] = "hp",
14860 [ALC861VD_AUTO] = "auto",
14863 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14864 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14865 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14866 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14867 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14868 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14869 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14870 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14871 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14872 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14873 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14874 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14875 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14876 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14877 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14878 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14882 static struct alc_config_preset alc861vd_presets[] = {
14884 .mixers = { alc861vd_3st_mixer },
14885 .init_verbs = { alc861vd_volume_init_verbs,
14886 alc861vd_3stack_init_verbs },
14887 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14888 .dac_nids = alc660vd_dac_nids,
14889 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14890 .channel_mode = alc861vd_3stack_2ch_modes,
14891 .input_mux = &alc861vd_capture_source,
14893 [ALC660VD_3ST_DIG] = {
14894 .mixers = { alc861vd_3st_mixer },
14895 .init_verbs = { alc861vd_volume_init_verbs,
14896 alc861vd_3stack_init_verbs },
14897 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14898 .dac_nids = alc660vd_dac_nids,
14899 .dig_out_nid = ALC861VD_DIGOUT_NID,
14900 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14901 .channel_mode = alc861vd_3stack_2ch_modes,
14902 .input_mux = &alc861vd_capture_source,
14905 .mixers = { alc861vd_3st_mixer },
14906 .init_verbs = { alc861vd_volume_init_verbs,
14907 alc861vd_3stack_init_verbs },
14908 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14909 .dac_nids = alc861vd_dac_nids,
14910 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14911 .channel_mode = alc861vd_3stack_2ch_modes,
14912 .input_mux = &alc861vd_capture_source,
14914 [ALC861VD_3ST_DIG] = {
14915 .mixers = { alc861vd_3st_mixer },
14916 .init_verbs = { alc861vd_volume_init_verbs,
14917 alc861vd_3stack_init_verbs },
14918 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14919 .dac_nids = alc861vd_dac_nids,
14920 .dig_out_nid = ALC861VD_DIGOUT_NID,
14921 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14922 .channel_mode = alc861vd_3stack_2ch_modes,
14923 .input_mux = &alc861vd_capture_source,
14925 [ALC861VD_6ST_DIG] = {
14926 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14927 .init_verbs = { alc861vd_volume_init_verbs,
14928 alc861vd_6stack_init_verbs },
14929 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14930 .dac_nids = alc861vd_dac_nids,
14931 .dig_out_nid = ALC861VD_DIGOUT_NID,
14932 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14933 .channel_mode = alc861vd_6stack_modes,
14934 .input_mux = &alc861vd_capture_source,
14936 [ALC861VD_LENOVO] = {
14937 .mixers = { alc861vd_lenovo_mixer },
14938 .init_verbs = { alc861vd_volume_init_verbs,
14939 alc861vd_3stack_init_verbs,
14940 alc861vd_eapd_verbs,
14941 alc861vd_lenovo_unsol_verbs },
14942 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14943 .dac_nids = alc660vd_dac_nids,
14944 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14945 .channel_mode = alc861vd_3stack_2ch_modes,
14946 .input_mux = &alc861vd_capture_source,
14947 .unsol_event = alc861vd_lenovo_unsol_event,
14948 .init_hook = alc861vd_lenovo_init_hook,
14950 [ALC861VD_DALLAS] = {
14951 .mixers = { alc861vd_dallas_mixer },
14952 .init_verbs = { alc861vd_dallas_verbs },
14953 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14954 .dac_nids = alc861vd_dac_nids,
14955 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14956 .channel_mode = alc861vd_3stack_2ch_modes,
14957 .input_mux = &alc861vd_dallas_capture_source,
14958 .unsol_event = alc_automute_amp_unsol_event,
14959 .init_hook = alc861vd_dallas_init_hook,
14962 .mixers = { alc861vd_hp_mixer },
14963 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14964 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14965 .dac_nids = alc861vd_dac_nids,
14966 .dig_out_nid = ALC861VD_DIGOUT_NID,
14967 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14968 .channel_mode = alc861vd_3stack_2ch_modes,
14969 .input_mux = &alc861vd_hp_capture_source,
14970 .unsol_event = alc_automute_amp_unsol_event,
14971 .init_hook = alc861vd_dallas_init_hook,
14973 [ALC660VD_ASUS_V1S] = {
14974 .mixers = { alc861vd_lenovo_mixer },
14975 .init_verbs = { alc861vd_volume_init_verbs,
14976 alc861vd_3stack_init_verbs,
14977 alc861vd_eapd_verbs,
14978 alc861vd_lenovo_unsol_verbs },
14979 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14980 .dac_nids = alc660vd_dac_nids,
14981 .dig_out_nid = ALC861VD_DIGOUT_NID,
14982 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14983 .channel_mode = alc861vd_3stack_2ch_modes,
14984 .input_mux = &alc861vd_capture_source,
14985 .unsol_event = alc861vd_lenovo_unsol_event,
14986 .init_hook = alc861vd_lenovo_init_hook,
14991 * BIOS auto configuration
14993 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14994 hda_nid_t nid, int pin_type, int dac_idx)
14996 alc_set_pin_output(codec, nid, pin_type);
14999 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15001 struct alc_spec *spec = codec->spec;
15004 for (i = 0; i <= HDA_SIDE; i++) {
15005 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15006 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15008 alc861vd_auto_set_output_and_unmute(codec, nid,
15014 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15016 struct alc_spec *spec = codec->spec;
15019 pin = spec->autocfg.hp_pins[0];
15020 if (pin) /* connect to front and use dac 0 */
15021 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15022 pin = spec->autocfg.speaker_pins[0];
15024 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15027 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
15028 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15030 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15032 struct alc_spec *spec = codec->spec;
15035 for (i = 0; i < AUTO_PIN_LAST; i++) {
15036 hda_nid_t nid = spec->autocfg.input_pins[i];
15037 if (alc861vd_is_input_pin(nid)) {
15038 alc_set_input_pin(codec, nid, i);
15039 if (nid != ALC861VD_PIN_CD_NID &&
15040 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15041 snd_hda_codec_write(codec, nid, 0,
15042 AC_VERB_SET_AMP_GAIN_MUTE,
15048 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
15050 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15051 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15053 /* add playback controls from the parsed DAC table */
15054 /* Based on ALC880 version. But ALC861VD has separate,
15055 * different NIDs for mute/unmute switch and volume control */
15056 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15057 const struct auto_pin_cfg *cfg)
15060 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15061 hda_nid_t nid_v, nid_s;
15064 for (i = 0; i < cfg->line_outs; i++) {
15065 if (!spec->multiout.dac_nids[i])
15067 nid_v = alc861vd_idx_to_mixer_vol(
15069 spec->multiout.dac_nids[i]));
15070 nid_s = alc861vd_idx_to_mixer_switch(
15072 spec->multiout.dac_nids[i]));
15076 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15077 "Center Playback Volume",
15078 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15082 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15083 "LFE Playback Volume",
15084 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15088 err = add_control(spec, ALC_CTL_BIND_MUTE,
15089 "Center Playback Switch",
15090 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15094 err = add_control(spec, ALC_CTL_BIND_MUTE,
15095 "LFE Playback Switch",
15096 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15101 sprintf(name, "%s Playback Volume", chname[i]);
15102 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15103 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15107 sprintf(name, "%s Playback Switch", chname[i]);
15108 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15109 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15118 /* add playback controls for speaker and HP outputs */
15119 /* Based on ALC880 version. But ALC861VD has separate,
15120 * different NIDs for mute/unmute switch and volume control */
15121 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15122 hda_nid_t pin, const char *pfx)
15124 hda_nid_t nid_v, nid_s;
15131 if (alc880_is_fixed_pin(pin)) {
15132 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15133 /* specify the DAC as the extra output */
15134 if (!spec->multiout.hp_nid)
15135 spec->multiout.hp_nid = nid_v;
15137 spec->multiout.extra_out_nid[0] = nid_v;
15138 /* control HP volume/switch on the output mixer amp */
15139 nid_v = alc861vd_idx_to_mixer_vol(
15140 alc880_fixed_pin_idx(pin));
15141 nid_s = alc861vd_idx_to_mixer_switch(
15142 alc880_fixed_pin_idx(pin));
15144 sprintf(name, "%s Playback Volume", pfx);
15145 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15146 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15149 sprintf(name, "%s Playback Switch", pfx);
15150 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15151 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15154 } else if (alc880_is_multi_pin(pin)) {
15155 /* set manual connection */
15156 /* we have only a switch on HP-out PIN */
15157 sprintf(name, "%s Playback Switch", pfx);
15158 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15159 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15166 /* parse the BIOS configuration and set up the alc_spec
15167 * return 1 if successful, 0 if the proper config is not found,
15168 * or a negative error code
15169 * Based on ALC880 version - had to change it to override
15170 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15171 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15173 struct alc_spec *spec = codec->spec;
15175 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15177 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15181 if (!spec->autocfg.line_outs)
15182 return 0; /* can't find valid BIOS pin config */
15184 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15187 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15190 err = alc861vd_auto_create_extra_out(spec,
15191 spec->autocfg.speaker_pins[0],
15195 err = alc861vd_auto_create_extra_out(spec,
15196 spec->autocfg.hp_pins[0],
15200 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15204 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15206 if (spec->autocfg.dig_outs)
15207 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15209 if (spec->kctls.list)
15210 add_mixer(spec, spec->kctls.list);
15212 add_verb(spec, alc861vd_volume_init_verbs);
15214 spec->num_mux_defs = 1;
15215 spec->input_mux = &spec->private_imux[0];
15217 err = alc_auto_add_mic_boost(codec);
15221 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15226 /* additional initialization for auto-configuration model */
15227 static void alc861vd_auto_init(struct hda_codec *codec)
15229 struct alc_spec *spec = codec->spec;
15230 alc861vd_auto_init_multi_out(codec);
15231 alc861vd_auto_init_hp_out(codec);
15232 alc861vd_auto_init_analog_input(codec);
15233 alc861vd_auto_init_input_src(codec);
15234 if (spec->unsol_event)
15235 alc_inithook(codec);
15238 static int patch_alc861vd(struct hda_codec *codec)
15240 struct alc_spec *spec;
15241 int err, board_config;
15243 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15247 codec->spec = spec;
15249 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15253 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15254 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15255 "trying auto-probe from BIOS...\n", codec->chip_name);
15256 board_config = ALC861VD_AUTO;
15259 if (board_config == ALC861VD_AUTO) {
15260 /* automatic parse from the BIOS config */
15261 err = alc861vd_parse_auto_config(codec);
15267 "hda_codec: Cannot set up configuration "
15268 "from BIOS. Using base mode...\n");
15269 board_config = ALC861VD_3ST;
15273 err = snd_hda_attach_beep_device(codec, 0x23);
15279 if (board_config != ALC861VD_AUTO)
15280 setup_preset(spec, &alc861vd_presets[board_config]);
15282 if (codec->vendor_id == 0x10ec0660) {
15283 /* always turn on EAPD */
15284 add_verb(spec, alc660vd_eapd_verbs);
15287 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15288 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15290 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15291 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15293 spec->adc_nids = alc861vd_adc_nids;
15294 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15295 spec->capsrc_nids = alc861vd_capsrc_nids;
15296 spec->capture_style = CAPT_MIX;
15298 set_capture_mixer(spec);
15299 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15301 spec->vmaster_nid = 0x02;
15303 codec->patch_ops = alc_patch_ops;
15305 if (board_config == ALC861VD_AUTO)
15306 spec->init_hook = alc861vd_auto_init;
15307 #ifdef CONFIG_SND_HDA_POWER_SAVE
15308 if (!spec->loopback.amplist)
15309 spec->loopback.amplist = alc861vd_loopbacks;
15311 codec->proc_widget_hook = print_realtek_coef;
15319 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15320 * configuration. Each pin widget can choose any input DACs and a mixer.
15321 * Each ADC is connected from a mixer of all inputs. This makes possible
15322 * 6-channel independent captures.
15324 * In addition, an independent DAC for the multi-playback (not used in this
15327 #define ALC662_DIGOUT_NID 0x06
15328 #define ALC662_DIGIN_NID 0x0a
15330 static hda_nid_t alc662_dac_nids[4] = {
15331 /* front, rear, clfe, rear_surr */
15335 static hda_nid_t alc272_dac_nids[2] = {
15339 static hda_nid_t alc662_adc_nids[1] = {
15344 static hda_nid_t alc272_adc_nids[1] = {
15349 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15350 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15354 /* FIXME: should be a matrix-type input source selection */
15355 static struct hda_input_mux alc662_capture_source = {
15359 { "Front Mic", 0x1 },
15365 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15373 static struct hda_input_mux alc662_eeepc_capture_source = {
15381 static struct hda_input_mux alc663_capture_source = {
15385 { "Front Mic", 0x1 },
15390 static struct hda_input_mux alc663_m51va_capture_source = {
15393 { "Ext-Mic", 0x0 },
15398 #if 1 /* set to 0 for testing other input sources below */
15399 static struct hda_input_mux alc272_nc10_capture_source = {
15402 { "Autoselect Mic", 0x0 },
15403 { "Internal Mic", 0x1 },
15407 static struct hda_input_mux alc272_nc10_capture_source = {
15410 { "Autoselect Mic", 0x0 },
15411 { "Internal Mic", 0x1 },
15412 { "In-0x02", 0x2 },
15413 { "In-0x03", 0x3 },
15414 { "In-0x04", 0x4 },
15415 { "In-0x05", 0x5 },
15416 { "In-0x06", 0x6 },
15417 { "In-0x07", 0x7 },
15418 { "In-0x08", 0x8 },
15419 { "In-0x09", 0x9 },
15420 { "In-0x0a", 0x0a },
15421 { "In-0x0b", 0x0b },
15422 { "In-0x0c", 0x0c },
15423 { "In-0x0d", 0x0d },
15424 { "In-0x0e", 0x0e },
15425 { "In-0x0f", 0x0f },
15433 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15440 static struct hda_verb alc662_3ST_ch2_init[] = {
15441 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15442 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15443 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15444 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15451 static struct hda_verb alc662_3ST_ch6_init[] = {
15452 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15453 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15454 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15455 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15456 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15457 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15461 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15462 { 2, alc662_3ST_ch2_init },
15463 { 6, alc662_3ST_ch6_init },
15469 static struct hda_verb alc662_sixstack_ch6_init[] = {
15470 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15471 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15472 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15479 static struct hda_verb alc662_sixstack_ch8_init[] = {
15480 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15481 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15482 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15486 static struct hda_channel_mode alc662_5stack_modes[2] = {
15487 { 2, alc662_sixstack_ch6_init },
15488 { 6, alc662_sixstack_ch8_init },
15491 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15492 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15495 static struct snd_kcontrol_new alc662_base_mixer[] = {
15496 /* output mixer control */
15497 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15498 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15499 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15500 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15501 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15502 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15503 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15504 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15507 /*Input mixer control */
15508 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15509 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15510 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15511 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15512 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15513 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15514 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15515 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15519 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15520 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15521 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15522 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15524 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15525 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15526 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15527 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15528 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15529 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15530 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15534 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15535 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15536 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15537 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15538 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15539 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15540 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15541 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15542 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15545 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15546 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15547 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15550 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15555 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15556 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15557 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15558 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15559 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15560 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15562 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15564 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15568 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15569 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15570 ALC262_HIPPO_MASTER_SWITCH,
15572 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15573 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15574 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15576 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15577 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15578 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15582 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15583 ALC262_HIPPO_MASTER_SWITCH,
15584 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15585 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15586 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15587 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15588 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15592 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15596 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15597 .ops = &snd_hda_bind_vol,
15599 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15600 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15605 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15606 .ops = &snd_hda_bind_sw,
15608 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15609 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15614 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15615 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15616 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15622 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15623 .ops = &snd_hda_bind_sw,
15625 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15626 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15627 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15632 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15633 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15634 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15636 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15637 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15638 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15643 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15644 .ops = &snd_hda_bind_sw,
15646 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15647 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15648 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15653 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15654 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15655 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15658 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15659 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15663 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15664 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15665 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15666 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15669 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15670 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15674 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15675 .ops = &snd_hda_bind_vol,
15677 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15678 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15683 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15684 .ops = &snd_hda_bind_sw,
15686 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15687 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15692 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15693 HDA_BIND_VOL("Master Playback Volume",
15694 &alc663_asus_two_bind_master_vol),
15695 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15696 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15699 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15703 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15704 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15705 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15706 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15713 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15714 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15715 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15716 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15717 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15722 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15723 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15727 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15728 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15729 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15730 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15734 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15735 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15736 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15737 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15741 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15744 .name = "Channel Mode",
15745 .info = alc_ch_mode_info,
15746 .get = alc_ch_mode_get,
15747 .put = alc_ch_mode_put,
15752 static struct hda_verb alc662_init_verbs[] = {
15753 /* ADC: mute amp left and right */
15754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15755 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15756 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15758 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15760 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15761 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15762 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771 /* Front Pin: output 0 (0x0c) */
15772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15775 /* Rear Pin: output 1 (0x0d) */
15776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15779 /* CLFE Pin: output 2 (0x0e) */
15780 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15781 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15783 /* Mic (rear) pin: input vref at 80% */
15784 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15786 /* Front Mic pin: input vref at 80% */
15787 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15789 /* Line In pin: input */
15790 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15791 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15792 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15793 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15794 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15795 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15796 /* CD pin widget for input */
15797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15799 /* FIXME: use matrix-type input source selection */
15800 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15802 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15803 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15805 /* always trun on EAPD */
15806 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15807 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15812 static struct hda_verb alc662_sue_init_verbs[] = {
15813 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15814 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15818 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15819 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15820 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15824 /* Set Unsolicited Event*/
15825 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15826 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15827 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15832 * generic initialization of ADC, input mixers and output mixers
15834 static struct hda_verb alc662_auto_init_verbs[] = {
15836 * Unmute ADC and set the default input to mic-in
15838 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15839 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15841 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15843 * Note: PASD motherboards uses the Line In 2 as the input for front
15844 * panel mic (mic 2)
15846 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15854 * Set up output mixers (0x0c - 0x0f)
15856 /* set vol=0 to output mixers */
15857 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15858 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15859 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15861 /* set up input amps for analog loopback */
15862 /* Amp Indices: DAC = 0, mixer = 1 */
15863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15871 /* FIXME: use matrix-type input source selection */
15872 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15875 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15879 /* additional verbs for ALC663 */
15880 static struct hda_verb alc663_auto_init_verbs[] = {
15881 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15882 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15886 static struct hda_verb alc663_m51va_init_verbs[] = {
15887 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15888 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15889 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15890 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15891 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15894 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15895 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15899 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15900 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15901 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15902 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15903 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15904 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15905 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15906 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15910 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15911 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15912 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15913 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15914 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15917 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15918 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15922 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15925 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15928 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15929 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15933 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15935 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15936 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15937 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15939 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15940 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15941 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15943 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15944 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15945 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15949 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15950 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15951 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15952 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15953 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15956 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15957 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15958 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15959 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15960 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15965 static struct hda_verb alc663_g71v_init_verbs[] = {
15966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15967 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15968 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15970 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15971 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15972 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15974 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15975 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15976 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15980 static struct hda_verb alc663_g50v_init_verbs[] = {
15981 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15982 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15983 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15985 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15986 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15990 static struct hda_verb alc662_ecs_init_verbs[] = {
15991 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15993 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15994 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15998 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15999 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16000 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16002 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16003 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16004 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16005 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16008 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16009 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16013 static struct hda_verb alc272_dell_init_verbs[] = {
16014 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16015 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16016 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16017 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16018 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16019 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16020 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16023 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16024 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16028 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16029 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16030 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16034 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16035 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16036 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16040 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16042 unsigned int present;
16043 unsigned char bits;
16045 present = snd_hda_codec_read(codec, 0x14, 0,
16046 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16047 bits = present ? HDA_AMP_MUTE : 0;
16048 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16049 HDA_AMP_MUTE, bits);
16052 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16054 unsigned int present;
16055 unsigned char bits;
16057 present = snd_hda_codec_read(codec, 0x1b, 0,
16058 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16059 bits = present ? HDA_AMP_MUTE : 0;
16060 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16061 HDA_AMP_MUTE, bits);
16062 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16063 HDA_AMP_MUTE, bits);
16066 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16069 if ((res >> 26) == ALC880_HP_EVENT)
16070 alc662_lenovo_101e_all_automute(codec);
16071 if ((res >> 26) == ALC880_FRONT_EVENT)
16072 alc662_lenovo_101e_ispeaker_automute(codec);
16075 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
16077 unsigned int present;
16079 present = snd_hda_codec_read(codec, 0x18, 0,
16080 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16081 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16082 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16083 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16084 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16085 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16086 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16087 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16088 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16091 /* unsolicited event for HP jack sensing */
16092 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16095 if ((res >> 26) == ALC880_MIC_EVENT)
16096 alc662_eeepc_mic_automute(codec);
16098 alc262_hippo_unsol_event(codec, res);
16101 static void alc662_eeepc_inithook(struct hda_codec *codec)
16103 alc262_hippo1_init_hook(codec);
16104 alc662_eeepc_mic_automute(codec);
16107 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16109 struct alc_spec *spec = codec->spec;
16111 spec->autocfg.hp_pins[0] = 0x14;
16112 spec->autocfg.speaker_pins[0] = 0x1b;
16113 alc262_hippo_master_update(codec);
16116 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16118 unsigned int present;
16119 unsigned char bits;
16121 present = snd_hda_codec_read(codec, 0x21, 0,
16122 AC_VERB_GET_PIN_SENSE, 0)
16123 & AC_PINSENSE_PRESENCE;
16124 bits = present ? HDA_AMP_MUTE : 0;
16125 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16126 AMP_IN_MUTE(0), bits);
16127 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16128 AMP_IN_MUTE(0), bits);
16131 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16133 unsigned int present;
16134 unsigned char bits;
16136 present = snd_hda_codec_read(codec, 0x21, 0,
16137 AC_VERB_GET_PIN_SENSE, 0)
16138 & AC_PINSENSE_PRESENCE;
16139 bits = present ? HDA_AMP_MUTE : 0;
16140 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16141 AMP_IN_MUTE(0), bits);
16142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16143 AMP_IN_MUTE(0), bits);
16144 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16145 AMP_IN_MUTE(0), bits);
16146 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16147 AMP_IN_MUTE(0), bits);
16150 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16152 unsigned int present;
16153 unsigned char bits;
16155 present = snd_hda_codec_read(codec, 0x15, 0,
16156 AC_VERB_GET_PIN_SENSE, 0)
16157 & AC_PINSENSE_PRESENCE;
16158 bits = present ? HDA_AMP_MUTE : 0;
16159 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16160 AMP_IN_MUTE(0), bits);
16161 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16162 AMP_IN_MUTE(0), bits);
16163 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16164 AMP_IN_MUTE(0), bits);
16165 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16166 AMP_IN_MUTE(0), bits);
16169 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16171 unsigned int present;
16172 unsigned char bits;
16174 present = snd_hda_codec_read(codec, 0x1b, 0,
16175 AC_VERB_GET_PIN_SENSE, 0)
16176 & AC_PINSENSE_PRESENCE;
16177 bits = present ? 0 : PIN_OUT;
16178 snd_hda_codec_write(codec, 0x14, 0,
16179 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16182 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16184 unsigned int present1, present2;
16186 present1 = snd_hda_codec_read(codec, 0x21, 0,
16187 AC_VERB_GET_PIN_SENSE, 0)
16188 & AC_PINSENSE_PRESENCE;
16189 present2 = snd_hda_codec_read(codec, 0x15, 0,
16190 AC_VERB_GET_PIN_SENSE, 0)
16191 & AC_PINSENSE_PRESENCE;
16193 if (present1 || present2) {
16194 snd_hda_codec_write_cache(codec, 0x14, 0,
16195 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16197 snd_hda_codec_write_cache(codec, 0x14, 0,
16198 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16202 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16204 unsigned int present1, present2;
16206 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16207 AC_VERB_GET_PIN_SENSE, 0)
16208 & AC_PINSENSE_PRESENCE;
16209 present2 = snd_hda_codec_read(codec, 0x15, 0,
16210 AC_VERB_GET_PIN_SENSE, 0)
16211 & AC_PINSENSE_PRESENCE;
16213 if (present1 || present2) {
16214 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16215 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16216 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16217 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16219 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16220 AMP_IN_MUTE(0), 0);
16221 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16222 AMP_IN_MUTE(0), 0);
16226 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16228 unsigned int present;
16230 present = snd_hda_codec_read(codec, 0x18, 0,
16231 AC_VERB_GET_PIN_SENSE, 0)
16232 & AC_PINSENSE_PRESENCE;
16233 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16234 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16235 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16236 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16237 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16238 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16239 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16240 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16243 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16246 switch (res >> 26) {
16247 case ALC880_HP_EVENT:
16248 alc663_m51va_speaker_automute(codec);
16250 case ALC880_MIC_EVENT:
16251 alc663_m51va_mic_automute(codec);
16256 static void alc663_m51va_inithook(struct hda_codec *codec)
16258 alc663_m51va_speaker_automute(codec);
16259 alc663_m51va_mic_automute(codec);
16262 /* ***************** Mode1 ******************************/
16263 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16266 switch (res >> 26) {
16267 case ALC880_HP_EVENT:
16268 alc663_m51va_speaker_automute(codec);
16270 case ALC880_MIC_EVENT:
16271 alc662_eeepc_mic_automute(codec);
16276 static void alc663_mode1_inithook(struct hda_codec *codec)
16278 alc663_m51va_speaker_automute(codec);
16279 alc662_eeepc_mic_automute(codec);
16281 /* ***************** Mode2 ******************************/
16282 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16285 switch (res >> 26) {
16286 case ALC880_HP_EVENT:
16287 alc662_f5z_speaker_automute(codec);
16289 case ALC880_MIC_EVENT:
16290 alc662_eeepc_mic_automute(codec);
16295 static void alc662_mode2_inithook(struct hda_codec *codec)
16297 alc662_f5z_speaker_automute(codec);
16298 alc662_eeepc_mic_automute(codec);
16300 /* ***************** Mode3 ******************************/
16301 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16304 switch (res >> 26) {
16305 case ALC880_HP_EVENT:
16306 alc663_two_hp_m1_speaker_automute(codec);
16308 case ALC880_MIC_EVENT:
16309 alc662_eeepc_mic_automute(codec);
16314 static void alc663_mode3_inithook(struct hda_codec *codec)
16316 alc663_two_hp_m1_speaker_automute(codec);
16317 alc662_eeepc_mic_automute(codec);
16319 /* ***************** Mode4 ******************************/
16320 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16323 switch (res >> 26) {
16324 case ALC880_HP_EVENT:
16325 alc663_21jd_two_speaker_automute(codec);
16327 case ALC880_MIC_EVENT:
16328 alc662_eeepc_mic_automute(codec);
16333 static void alc663_mode4_inithook(struct hda_codec *codec)
16335 alc663_21jd_two_speaker_automute(codec);
16336 alc662_eeepc_mic_automute(codec);
16338 /* ***************** Mode5 ******************************/
16339 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16342 switch (res >> 26) {
16343 case ALC880_HP_EVENT:
16344 alc663_15jd_two_speaker_automute(codec);
16346 case ALC880_MIC_EVENT:
16347 alc662_eeepc_mic_automute(codec);
16352 static void alc663_mode5_inithook(struct hda_codec *codec)
16354 alc663_15jd_two_speaker_automute(codec);
16355 alc662_eeepc_mic_automute(codec);
16357 /* ***************** Mode6 ******************************/
16358 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16361 switch (res >> 26) {
16362 case ALC880_HP_EVENT:
16363 alc663_two_hp_m2_speaker_automute(codec);
16365 case ALC880_MIC_EVENT:
16366 alc662_eeepc_mic_automute(codec);
16371 static void alc663_mode6_inithook(struct hda_codec *codec)
16373 alc663_two_hp_m2_speaker_automute(codec);
16374 alc662_eeepc_mic_automute(codec);
16377 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16379 unsigned int present;
16380 unsigned char bits;
16382 present = snd_hda_codec_read(codec, 0x21, 0,
16383 AC_VERB_GET_PIN_SENSE, 0)
16384 & AC_PINSENSE_PRESENCE;
16385 bits = present ? HDA_AMP_MUTE : 0;
16386 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16387 HDA_AMP_MUTE, bits);
16388 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16389 HDA_AMP_MUTE, bits);
16392 static void alc663_g71v_front_automute(struct hda_codec *codec)
16394 unsigned int present;
16395 unsigned char bits;
16397 present = snd_hda_codec_read(codec, 0x15, 0,
16398 AC_VERB_GET_PIN_SENSE, 0)
16399 & AC_PINSENSE_PRESENCE;
16400 bits = present ? HDA_AMP_MUTE : 0;
16401 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16402 HDA_AMP_MUTE, bits);
16405 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16408 switch (res >> 26) {
16409 case ALC880_HP_EVENT:
16410 alc663_g71v_hp_automute(codec);
16412 case ALC880_FRONT_EVENT:
16413 alc663_g71v_front_automute(codec);
16415 case ALC880_MIC_EVENT:
16416 alc662_eeepc_mic_automute(codec);
16421 static void alc663_g71v_inithook(struct hda_codec *codec)
16423 alc663_g71v_front_automute(codec);
16424 alc663_g71v_hp_automute(codec);
16425 alc662_eeepc_mic_automute(codec);
16428 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16431 switch (res >> 26) {
16432 case ALC880_HP_EVENT:
16433 alc663_m51va_speaker_automute(codec);
16435 case ALC880_MIC_EVENT:
16436 alc662_eeepc_mic_automute(codec);
16441 static void alc663_g50v_inithook(struct hda_codec *codec)
16443 alc663_m51va_speaker_automute(codec);
16444 alc662_eeepc_mic_automute(codec);
16447 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16448 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16449 ALC262_HIPPO_MASTER_SWITCH,
16451 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16452 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16453 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16455 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16456 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16457 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16461 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16462 /* Master Playback automatically created from Speaker and Headphone */
16463 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16464 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16465 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16466 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16468 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16469 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16470 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16472 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16473 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16474 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16478 #ifdef CONFIG_SND_HDA_POWER_SAVE
16479 #define alc662_loopbacks alc880_loopbacks
16483 /* pcm configuration: identiacal with ALC880 */
16484 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16485 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16486 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16487 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16490 * configuration and preset
16492 static const char *alc662_models[ALC662_MODEL_LAST] = {
16493 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16494 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16495 [ALC662_3ST_6ch] = "3stack-6ch",
16496 [ALC662_5ST_DIG] = "6stack-dig",
16497 [ALC662_LENOVO_101E] = "lenovo-101e",
16498 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16499 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16500 [ALC662_ECS] = "ecs",
16501 [ALC663_ASUS_M51VA] = "m51va",
16502 [ALC663_ASUS_G71V] = "g71v",
16503 [ALC663_ASUS_H13] = "h13",
16504 [ALC663_ASUS_G50V] = "g50v",
16505 [ALC663_ASUS_MODE1] = "asus-mode1",
16506 [ALC662_ASUS_MODE2] = "asus-mode2",
16507 [ALC663_ASUS_MODE3] = "asus-mode3",
16508 [ALC663_ASUS_MODE4] = "asus-mode4",
16509 [ALC663_ASUS_MODE5] = "asus-mode5",
16510 [ALC663_ASUS_MODE6] = "asus-mode6",
16511 [ALC272_DELL] = "dell",
16512 [ALC272_DELL_ZM1] = "dell-zm1",
16513 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16514 [ALC662_AUTO] = "auto",
16517 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16518 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16519 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16520 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16521 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16522 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16523 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16524 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16525 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16526 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16527 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16528 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16529 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16530 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16531 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16532 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16533 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16534 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16535 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16536 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16537 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16538 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16539 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16540 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16541 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16542 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16543 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16544 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16545 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16546 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16547 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16548 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16549 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16550 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16551 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16552 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16553 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16554 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16555 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16556 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16557 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16558 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16559 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16560 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16561 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16562 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16563 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16564 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16565 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16566 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16567 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16568 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16569 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16570 ALC662_3ST_6ch_DIG),
16571 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16572 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16573 ALC662_3ST_6ch_DIG),
16574 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16575 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16576 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16577 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16578 ALC662_3ST_6ch_DIG),
16579 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16584 static struct alc_config_preset alc662_presets[] = {
16585 [ALC662_3ST_2ch_DIG] = {
16586 .mixers = { alc662_3ST_2ch_mixer },
16587 .init_verbs = { alc662_init_verbs },
16588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16589 .dac_nids = alc662_dac_nids,
16590 .dig_out_nid = ALC662_DIGOUT_NID,
16591 .dig_in_nid = ALC662_DIGIN_NID,
16592 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16593 .channel_mode = alc662_3ST_2ch_modes,
16594 .input_mux = &alc662_capture_source,
16596 [ALC662_3ST_6ch_DIG] = {
16597 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16598 .init_verbs = { alc662_init_verbs },
16599 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16600 .dac_nids = alc662_dac_nids,
16601 .dig_out_nid = ALC662_DIGOUT_NID,
16602 .dig_in_nid = ALC662_DIGIN_NID,
16603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16604 .channel_mode = alc662_3ST_6ch_modes,
16606 .input_mux = &alc662_capture_source,
16608 [ALC662_3ST_6ch] = {
16609 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16610 .init_verbs = { alc662_init_verbs },
16611 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16612 .dac_nids = alc662_dac_nids,
16613 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16614 .channel_mode = alc662_3ST_6ch_modes,
16616 .input_mux = &alc662_capture_source,
16618 [ALC662_5ST_DIG] = {
16619 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16620 .init_verbs = { alc662_init_verbs },
16621 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16622 .dac_nids = alc662_dac_nids,
16623 .dig_out_nid = ALC662_DIGOUT_NID,
16624 .dig_in_nid = ALC662_DIGIN_NID,
16625 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16626 .channel_mode = alc662_5stack_modes,
16627 .input_mux = &alc662_capture_source,
16629 [ALC662_LENOVO_101E] = {
16630 .mixers = { alc662_lenovo_101e_mixer },
16631 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16632 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16633 .dac_nids = alc662_dac_nids,
16634 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16635 .channel_mode = alc662_3ST_2ch_modes,
16636 .input_mux = &alc662_lenovo_101e_capture_source,
16637 .unsol_event = alc662_lenovo_101e_unsol_event,
16638 .init_hook = alc662_lenovo_101e_all_automute,
16640 [ALC662_ASUS_EEEPC_P701] = {
16641 .mixers = { alc662_eeepc_p701_mixer },
16642 .init_verbs = { alc662_init_verbs,
16643 alc662_eeepc_sue_init_verbs },
16644 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16645 .dac_nids = alc662_dac_nids,
16646 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16647 .channel_mode = alc662_3ST_2ch_modes,
16648 .input_mux = &alc662_eeepc_capture_source,
16649 .unsol_event = alc662_eeepc_unsol_event,
16650 .init_hook = alc662_eeepc_inithook,
16652 [ALC662_ASUS_EEEPC_EP20] = {
16653 .mixers = { alc662_eeepc_ep20_mixer,
16654 alc662_chmode_mixer },
16655 .init_verbs = { alc662_init_verbs,
16656 alc662_eeepc_ep20_sue_init_verbs },
16657 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16658 .dac_nids = alc662_dac_nids,
16659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16660 .channel_mode = alc662_3ST_6ch_modes,
16661 .input_mux = &alc662_lenovo_101e_capture_source,
16662 .unsol_event = alc662_eeepc_unsol_event,
16663 .init_hook = alc662_eeepc_ep20_inithook,
16666 .mixers = { alc662_ecs_mixer },
16667 .init_verbs = { alc662_init_verbs,
16668 alc662_ecs_init_verbs },
16669 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16670 .dac_nids = alc662_dac_nids,
16671 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16672 .channel_mode = alc662_3ST_2ch_modes,
16673 .input_mux = &alc662_eeepc_capture_source,
16674 .unsol_event = alc662_eeepc_unsol_event,
16675 .init_hook = alc662_eeepc_inithook,
16677 [ALC663_ASUS_M51VA] = {
16678 .mixers = { alc663_m51va_mixer },
16679 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16680 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16681 .dac_nids = alc662_dac_nids,
16682 .dig_out_nid = ALC662_DIGOUT_NID,
16683 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16684 .channel_mode = alc662_3ST_2ch_modes,
16685 .input_mux = &alc663_m51va_capture_source,
16686 .unsol_event = alc663_m51va_unsol_event,
16687 .init_hook = alc663_m51va_inithook,
16689 [ALC663_ASUS_G71V] = {
16690 .mixers = { alc663_g71v_mixer },
16691 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16692 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16693 .dac_nids = alc662_dac_nids,
16694 .dig_out_nid = ALC662_DIGOUT_NID,
16695 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16696 .channel_mode = alc662_3ST_2ch_modes,
16697 .input_mux = &alc662_eeepc_capture_source,
16698 .unsol_event = alc663_g71v_unsol_event,
16699 .init_hook = alc663_g71v_inithook,
16701 [ALC663_ASUS_H13] = {
16702 .mixers = { alc663_m51va_mixer },
16703 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16704 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16705 .dac_nids = alc662_dac_nids,
16706 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16707 .channel_mode = alc662_3ST_2ch_modes,
16708 .input_mux = &alc663_m51va_capture_source,
16709 .unsol_event = alc663_m51va_unsol_event,
16710 .init_hook = alc663_m51va_inithook,
16712 [ALC663_ASUS_G50V] = {
16713 .mixers = { alc663_g50v_mixer },
16714 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16715 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16716 .dac_nids = alc662_dac_nids,
16717 .dig_out_nid = ALC662_DIGOUT_NID,
16718 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16719 .channel_mode = alc662_3ST_6ch_modes,
16720 .input_mux = &alc663_capture_source,
16721 .unsol_event = alc663_g50v_unsol_event,
16722 .init_hook = alc663_g50v_inithook,
16724 [ALC663_ASUS_MODE1] = {
16725 .mixers = { alc663_m51va_mixer },
16726 .cap_mixer = alc662_auto_capture_mixer,
16727 .init_verbs = { alc662_init_verbs,
16728 alc663_21jd_amic_init_verbs },
16729 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16731 .dac_nids = alc662_dac_nids,
16732 .dig_out_nid = ALC662_DIGOUT_NID,
16733 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16734 .channel_mode = alc662_3ST_2ch_modes,
16735 .input_mux = &alc662_eeepc_capture_source,
16736 .unsol_event = alc663_mode1_unsol_event,
16737 .init_hook = alc663_mode1_inithook,
16739 [ALC662_ASUS_MODE2] = {
16740 .mixers = { alc662_1bjd_mixer },
16741 .cap_mixer = alc662_auto_capture_mixer,
16742 .init_verbs = { alc662_init_verbs,
16743 alc662_1bjd_amic_init_verbs },
16744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16745 .dac_nids = alc662_dac_nids,
16746 .dig_out_nid = ALC662_DIGOUT_NID,
16747 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16748 .channel_mode = alc662_3ST_2ch_modes,
16749 .input_mux = &alc662_eeepc_capture_source,
16750 .unsol_event = alc662_mode2_unsol_event,
16751 .init_hook = alc662_mode2_inithook,
16753 [ALC663_ASUS_MODE3] = {
16754 .mixers = { alc663_two_hp_m1_mixer },
16755 .cap_mixer = alc662_auto_capture_mixer,
16756 .init_verbs = { alc662_init_verbs,
16757 alc663_two_hp_amic_m1_init_verbs },
16758 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16760 .dac_nids = alc662_dac_nids,
16761 .dig_out_nid = ALC662_DIGOUT_NID,
16762 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16763 .channel_mode = alc662_3ST_2ch_modes,
16764 .input_mux = &alc662_eeepc_capture_source,
16765 .unsol_event = alc663_mode3_unsol_event,
16766 .init_hook = alc663_mode3_inithook,
16768 [ALC663_ASUS_MODE4] = {
16769 .mixers = { alc663_asus_21jd_clfe_mixer },
16770 .cap_mixer = alc662_auto_capture_mixer,
16771 .init_verbs = { alc662_init_verbs,
16772 alc663_21jd_amic_init_verbs},
16773 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16775 .dac_nids = alc662_dac_nids,
16776 .dig_out_nid = ALC662_DIGOUT_NID,
16777 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16778 .channel_mode = alc662_3ST_2ch_modes,
16779 .input_mux = &alc662_eeepc_capture_source,
16780 .unsol_event = alc663_mode4_unsol_event,
16781 .init_hook = alc663_mode4_inithook,
16783 [ALC663_ASUS_MODE5] = {
16784 .mixers = { alc663_asus_15jd_clfe_mixer },
16785 .cap_mixer = alc662_auto_capture_mixer,
16786 .init_verbs = { alc662_init_verbs,
16787 alc663_15jd_amic_init_verbs },
16788 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16790 .dac_nids = alc662_dac_nids,
16791 .dig_out_nid = ALC662_DIGOUT_NID,
16792 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16793 .channel_mode = alc662_3ST_2ch_modes,
16794 .input_mux = &alc662_eeepc_capture_source,
16795 .unsol_event = alc663_mode5_unsol_event,
16796 .init_hook = alc663_mode5_inithook,
16798 [ALC663_ASUS_MODE6] = {
16799 .mixers = { alc663_two_hp_m2_mixer },
16800 .cap_mixer = alc662_auto_capture_mixer,
16801 .init_verbs = { alc662_init_verbs,
16802 alc663_two_hp_amic_m2_init_verbs },
16803 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16805 .dac_nids = alc662_dac_nids,
16806 .dig_out_nid = ALC662_DIGOUT_NID,
16807 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16808 .channel_mode = alc662_3ST_2ch_modes,
16809 .input_mux = &alc662_eeepc_capture_source,
16810 .unsol_event = alc663_mode6_unsol_event,
16811 .init_hook = alc663_mode6_inithook,
16814 .mixers = { alc663_m51va_mixer },
16815 .cap_mixer = alc272_auto_capture_mixer,
16816 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16817 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16818 .dac_nids = alc662_dac_nids,
16819 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16820 .adc_nids = alc272_adc_nids,
16821 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16822 .capsrc_nids = alc272_capsrc_nids,
16823 .channel_mode = alc662_3ST_2ch_modes,
16824 .input_mux = &alc663_m51va_capture_source,
16825 .unsol_event = alc663_m51va_unsol_event,
16826 .init_hook = alc663_m51va_inithook,
16828 [ALC272_DELL_ZM1] = {
16829 .mixers = { alc663_m51va_mixer },
16830 .cap_mixer = alc662_auto_capture_mixer,
16831 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16832 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16833 .dac_nids = alc662_dac_nids,
16834 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16835 .adc_nids = alc662_adc_nids,
16836 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16837 .capsrc_nids = alc662_capsrc_nids,
16838 .channel_mode = alc662_3ST_2ch_modes,
16839 .input_mux = &alc663_m51va_capture_source,
16840 .unsol_event = alc663_m51va_unsol_event,
16841 .init_hook = alc663_m51va_inithook,
16843 [ALC272_SAMSUNG_NC10] = {
16844 .mixers = { alc272_nc10_mixer },
16845 .init_verbs = { alc662_init_verbs,
16846 alc663_21jd_amic_init_verbs },
16847 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16848 .dac_nids = alc272_dac_nids,
16849 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16850 .channel_mode = alc662_3ST_2ch_modes,
16851 .input_mux = &alc272_nc10_capture_source,
16852 .unsol_event = alc663_mode4_unsol_event,
16853 .init_hook = alc663_mode4_inithook,
16859 * BIOS auto configuration
16862 /* add playback controls from the parsed DAC table */
16863 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16864 const struct auto_pin_cfg *cfg)
16867 static const char *chname[4] = {
16868 "Front", "Surround", NULL /*CLFE*/, "Side"
16873 for (i = 0; i < cfg->line_outs; i++) {
16874 if (!spec->multiout.dac_nids[i])
16876 nid = alc880_idx_to_dac(i);
16879 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16880 "Center Playback Volume",
16881 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16885 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16886 "LFE Playback Volume",
16887 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16891 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16892 "Center Playback Switch",
16893 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16897 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16898 "LFE Playback Switch",
16899 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16904 sprintf(name, "%s Playback Volume", chname[i]);
16905 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16906 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16910 sprintf(name, "%s Playback Switch", chname[i]);
16911 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16912 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16921 /* add playback controls for speaker and HP outputs */
16922 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16933 /* ALC663 has a mono output pin on 0x17 */
16934 sprintf(name, "%s Playback Switch", pfx);
16935 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16936 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16940 if (alc880_is_fixed_pin(pin)) {
16941 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16942 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16943 /* specify the DAC as the extra output */
16944 if (!spec->multiout.hp_nid)
16945 spec->multiout.hp_nid = nid;
16947 spec->multiout.extra_out_nid[0] = nid;
16948 /* control HP volume/switch on the output mixer amp */
16949 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16950 sprintf(name, "%s Playback Volume", pfx);
16951 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16952 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16955 sprintf(name, "%s Playback Switch", pfx);
16956 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16957 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16960 } else if (alc880_is_multi_pin(pin)) {
16961 /* set manual connection */
16962 /* we have only a switch on HP-out PIN */
16963 sprintf(name, "%s Playback Switch", pfx);
16964 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16965 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16972 /* return the index of the src widget from the connection list of the nid.
16973 * return -1 if not found
16975 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16978 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16981 conns = snd_hda_get_connections(codec, nid, conn_list,
16982 ARRAY_SIZE(conn_list));
16985 for (i = 0; i < conns; i++)
16986 if (conn_list[i] == src)
16991 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16993 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16994 return (pincap & AC_PINCAP_IN) != 0;
16997 /* create playback/capture controls for input pins */
16998 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16999 const struct auto_pin_cfg *cfg)
17001 struct alc_spec *spec = codec->spec;
17002 struct hda_input_mux *imux = &spec->private_imux[0];
17005 for (i = 0; i < AUTO_PIN_LAST; i++) {
17006 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
17007 idx = alc662_input_pin_idx(codec, 0x0b,
17008 cfg->input_pins[i]);
17010 err = new_analog_input(spec, cfg->input_pins[i],
17011 auto_pin_cfg_labels[i],
17016 idx = alc662_input_pin_idx(codec, 0x22,
17017 cfg->input_pins[i]);
17019 imux->items[imux->num_items].label =
17020 auto_pin_cfg_labels[i];
17021 imux->items[imux->num_items].index = idx;
17029 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17030 hda_nid_t nid, int pin_type,
17033 alc_set_pin_output(codec, nid, pin_type);
17034 /* need the manual connection? */
17035 if (alc880_is_multi_pin(nid)) {
17036 struct alc_spec *spec = codec->spec;
17037 int idx = alc880_multi_pin_idx(nid);
17038 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
17039 AC_VERB_SET_CONNECT_SEL,
17040 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
17044 static void alc662_auto_init_multi_out(struct hda_codec *codec)
17046 struct alc_spec *spec = codec->spec;
17049 for (i = 0; i <= HDA_SIDE; i++) {
17050 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17051 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17053 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17058 static void alc662_auto_init_hp_out(struct hda_codec *codec)
17060 struct alc_spec *spec = codec->spec;
17063 pin = spec->autocfg.hp_pins[0];
17064 if (pin) /* connect to front */
17066 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17067 pin = spec->autocfg.speaker_pins[0];
17069 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17072 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17074 static void alc662_auto_init_analog_input(struct hda_codec *codec)
17076 struct alc_spec *spec = codec->spec;
17079 for (i = 0; i < AUTO_PIN_LAST; i++) {
17080 hda_nid_t nid = spec->autocfg.input_pins[i];
17081 if (alc662_is_input_pin(codec, nid)) {
17082 alc_set_input_pin(codec, nid, i);
17083 if (nid != ALC662_PIN_CD_NID &&
17084 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17085 snd_hda_codec_write(codec, nid, 0,
17086 AC_VERB_SET_AMP_GAIN_MUTE,
17092 #define alc662_auto_init_input_src alc882_auto_init_input_src
17094 static int alc662_parse_auto_config(struct hda_codec *codec)
17096 struct alc_spec *spec = codec->spec;
17098 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17100 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17104 if (!spec->autocfg.line_outs)
17105 return 0; /* can't find valid BIOS pin config */
17107 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17110 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17113 err = alc662_auto_create_extra_out(spec,
17114 spec->autocfg.speaker_pins[0],
17118 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17122 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17126 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17128 if (spec->autocfg.dig_outs)
17129 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17131 if (spec->kctls.list)
17132 add_mixer(spec, spec->kctls.list);
17134 spec->num_mux_defs = 1;
17135 spec->input_mux = &spec->private_imux[0];
17137 add_verb(spec, alc662_auto_init_verbs);
17138 if (codec->vendor_id == 0x10ec0663)
17139 add_verb(spec, alc663_auto_init_verbs);
17141 err = alc_auto_add_mic_boost(codec);
17145 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17150 /* additional initialization for auto-configuration model */
17151 static void alc662_auto_init(struct hda_codec *codec)
17153 struct alc_spec *spec = codec->spec;
17154 alc662_auto_init_multi_out(codec);
17155 alc662_auto_init_hp_out(codec);
17156 alc662_auto_init_analog_input(codec);
17157 alc662_auto_init_input_src(codec);
17158 if (spec->unsol_event)
17159 alc_inithook(codec);
17162 static int patch_alc662(struct hda_codec *codec)
17164 struct alc_spec *spec;
17165 int err, board_config;
17167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17171 codec->spec = spec;
17173 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17175 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17178 if (board_config < 0) {
17179 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17180 "trying auto-probe from BIOS...\n", codec->chip_name);
17181 board_config = ALC662_AUTO;
17184 if (board_config == ALC662_AUTO) {
17185 /* automatic parse from the BIOS config */
17186 err = alc662_parse_auto_config(codec);
17192 "hda_codec: Cannot set up configuration "
17193 "from BIOS. Using base mode...\n");
17194 board_config = ALC662_3ST_2ch_DIG;
17198 err = snd_hda_attach_beep_device(codec, 0x1);
17204 if (board_config != ALC662_AUTO)
17205 setup_preset(spec, &alc662_presets[board_config]);
17207 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17208 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17210 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17211 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17213 spec->adc_nids = alc662_adc_nids;
17214 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17215 spec->capsrc_nids = alc662_capsrc_nids;
17216 spec->capture_style = CAPT_MIX;
17218 if (!spec->cap_mixer)
17219 set_capture_mixer(spec);
17220 if (codec->vendor_id == 0x10ec0662)
17221 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17223 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17225 spec->vmaster_nid = 0x02;
17227 codec->patch_ops = alc_patch_ops;
17228 if (board_config == ALC662_AUTO)
17229 spec->init_hook = alc662_auto_init;
17230 #ifdef CONFIG_SND_HDA_POWER_SAVE
17231 if (!spec->loopback.amplist)
17232 spec->loopback.amplist = alc662_loopbacks;
17234 codec->proc_widget_hook = print_realtek_coef;
17242 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17243 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17244 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17245 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17246 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17247 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17248 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17249 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17250 .patch = patch_alc861 },
17251 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17252 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17253 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17254 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17255 .patch = patch_alc883 },
17256 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17257 .patch = patch_alc662 },
17258 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17259 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17260 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17261 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17262 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17263 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17264 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17265 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17266 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17267 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17268 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17269 .patch = patch_alc883 },
17270 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17271 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17272 {} /* terminator */
17275 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17277 MODULE_LICENSE("GPL");
17278 MODULE_DESCRIPTION("Realtek HD-audio codec");
17280 static struct hda_codec_preset_list realtek_list = {
17281 .preset = snd_hda_preset_realtek,
17282 .owner = THIS_MODULE,
17285 static int __init patch_realtek_init(void)
17287 return snd_hda_add_codec_preset(&realtek_list);
17290 static void __exit patch_realtek_exit(void)
17292 snd_hda_delete_codec_preset(&realtek_list);
17295 module_init(patch_realtek_init)
17296 module_exit(patch_realtek_exit)