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,
216 ALC883_TARGA_2ch_DIG,
217 ALC883_TARGA_8ch_DIG,
220 ALC888_ACER_ASPIRE_4930G,
221 ALC888_ACER_ASPIRE_6530G,
222 ALC888_ACER_ASPIRE_8930G,
226 ALC883_LENOVO_101E_2ch,
227 ALC883_LENOVO_NB0763,
228 ALC888_LENOVO_MS7195_DIG,
235 ALC883_FUJITSU_PI2515,
236 ALC888_FUJITSU_XA3530,
237 ALC883_3ST_6ch_INTEL,
248 #define GPIO_MASK 0x03
250 /* extra amp-initialization sequence types */
260 /* codec parameterization */
261 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
262 unsigned int num_mixers;
263 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
264 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
266 const struct hda_verb *init_verbs[5]; /* initialization verbs
270 unsigned int num_init_verbs;
272 char stream_name_analog[16]; /* analog PCM stream */
273 struct hda_pcm_stream *stream_analog_playback;
274 struct hda_pcm_stream *stream_analog_capture;
275 struct hda_pcm_stream *stream_analog_alt_playback;
276 struct hda_pcm_stream *stream_analog_alt_capture;
278 char stream_name_digital[16]; /* digital PCM stream */
279 struct hda_pcm_stream *stream_digital_playback;
280 struct hda_pcm_stream *stream_digital_capture;
283 struct hda_multi_out multiout; /* playback set-up
284 * max_channels, dacs must be set
285 * dig_out_nid and hp_nid are optional
287 hda_nid_t alt_dac_nid;
288 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
292 unsigned int num_adc_nids;
294 hda_nid_t *capsrc_nids;
295 hda_nid_t dig_in_nid; /* digital-in NID; optional */
298 unsigned int num_mux_defs;
299 const struct hda_input_mux *input_mux;
300 unsigned int cur_mux[3];
303 const struct hda_channel_mode *channel_mode;
304 int num_channel_mode;
306 int const_channel_count;
307 int ext_channel_count;
309 /* PCM information */
310 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
312 /* dynamic controls, init_verbs and input_mux */
313 struct auto_pin_cfg autocfg;
314 struct snd_array kctls;
315 struct hda_input_mux private_imux[3];
316 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
317 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
318 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
321 void (*init_hook)(struct hda_codec *codec);
322 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
324 /* for pin sensing */
325 unsigned int sense_updated: 1;
326 unsigned int jack_present: 1;
327 unsigned int master_sw: 1;
330 unsigned int no_analog :1; /* digital I/O only */
333 /* for virtual master */
334 hda_nid_t vmaster_nid;
335 #ifdef CONFIG_SND_HDA_POWER_SAVE
336 struct hda_loopback_check loopback;
341 unsigned int pll_coef_idx, pll_coef_bit;
345 * configuration template - to be copied to the spec instance
347 struct alc_config_preset {
348 struct snd_kcontrol_new *mixers[5]; /* should be identical size
351 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
352 const struct hda_verb *init_verbs[5];
353 unsigned int num_dacs;
355 hda_nid_t dig_out_nid; /* optional */
356 hda_nid_t hp_nid; /* optional */
357 hda_nid_t *slave_dig_outs;
358 unsigned int num_adc_nids;
360 hda_nid_t *capsrc_nids;
361 hda_nid_t dig_in_nid;
362 unsigned int num_channel_mode;
363 const struct hda_channel_mode *channel_mode;
365 int const_channel_count;
366 unsigned int num_mux_defs;
367 const struct hda_input_mux *input_mux;
368 void (*unsol_event)(struct hda_codec *, unsigned int);
369 void (*init_hook)(struct hda_codec *);
370 #ifdef CONFIG_SND_HDA_POWER_SAVE
371 struct hda_amp_list *loopbacks;
379 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
380 struct snd_ctl_elem_info *uinfo)
382 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
383 struct alc_spec *spec = codec->spec;
384 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
385 if (mux_idx >= spec->num_mux_defs)
387 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
390 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol)
393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct alc_spec *spec = codec->spec;
395 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
397 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
401 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405 struct alc_spec *spec = codec->spec;
406 const struct hda_input_mux *imux;
407 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
408 unsigned int mux_idx;
409 hda_nid_t nid = spec->capsrc_nids ?
410 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
413 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
414 imux = &spec->input_mux[mux_idx];
416 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
417 if (type == AC_WID_AUD_MIX) {
418 /* Matrix-mixer style (e.g. ALC882) */
419 unsigned int *cur_val = &spec->cur_mux[adc_idx];
422 idx = ucontrol->value.enumerated.item[0];
423 if (idx >= imux->num_items)
424 idx = imux->num_items - 1;
427 for (i = 0; i < imux->num_items; i++) {
428 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
429 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
430 imux->items[i].index,
436 /* MUX style (e.g. ALC880) */
437 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
438 &spec->cur_mux[adc_idx]);
443 * channel mode setting
445 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_info *uinfo)
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct alc_spec *spec = codec->spec;
450 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
451 spec->num_channel_mode);
454 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
455 struct snd_ctl_elem_value *ucontrol)
457 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
458 struct alc_spec *spec = codec->spec;
459 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
460 spec->num_channel_mode,
461 spec->ext_channel_count);
464 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
465 struct snd_ctl_elem_value *ucontrol)
467 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
468 struct alc_spec *spec = codec->spec;
469 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
470 spec->num_channel_mode,
471 &spec->ext_channel_count);
472 if (err >= 0 && !spec->const_channel_count) {
473 spec->multiout.max_channels = spec->ext_channel_count;
474 if (spec->need_dac_fix)
475 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
481 * Control the mode of pin widget settings via the mixer. "pc" is used
482 * instead of "%" to avoid consequences of accidently treating the % as
483 * being part of a format specifier. Maximum allowed length of a value is
484 * 63 characters plus NULL terminator.
486 * Note: some retasking pin complexes seem to ignore requests for input
487 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
488 * are requested. Therefore order this list so that this behaviour will not
489 * cause problems when mixer clients move through the enum sequentially.
490 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
493 static char *alc_pin_mode_names[] = {
494 "Mic 50pc bias", "Mic 80pc bias",
495 "Line in", "Line out", "Headphone out",
497 static unsigned char alc_pin_mode_values[] = {
498 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
500 /* The control can present all 5 options, or it can limit the options based
501 * in the pin being assumed to be exclusively an input or an output pin. In
502 * addition, "input" pins may or may not process the mic bias option
503 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
504 * accept requests for bias as of chip versions up to March 2006) and/or
505 * wiring in the computer.
507 #define ALC_PIN_DIR_IN 0x00
508 #define ALC_PIN_DIR_OUT 0x01
509 #define ALC_PIN_DIR_INOUT 0x02
510 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
511 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
513 /* Info about the pin modes supported by the different pin direction modes.
514 * For each direction the minimum and maximum values are given.
516 static signed char alc_pin_mode_dir_info[5][2] = {
517 { 0, 2 }, /* ALC_PIN_DIR_IN */
518 { 3, 4 }, /* ALC_PIN_DIR_OUT */
519 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
520 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
521 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
523 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
524 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
525 #define alc_pin_mode_n_items(_dir) \
526 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
528 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_info *uinfo)
531 unsigned int item_num = uinfo->value.enumerated.item;
532 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
534 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
536 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
538 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
539 item_num = alc_pin_mode_min(dir);
540 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
544 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
549 hda_nid_t nid = kcontrol->private_value & 0xffff;
550 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
551 long *valp = ucontrol->value.integer.value;
552 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
553 AC_VERB_GET_PIN_WIDGET_CONTROL,
556 /* Find enumerated value for current pinctl setting */
557 i = alc_pin_mode_min(dir);
558 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
560 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
564 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
569 hda_nid_t nid = kcontrol->private_value & 0xffff;
570 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
571 long val = *ucontrol->value.integer.value;
572 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
573 AC_VERB_GET_PIN_WIDGET_CONTROL,
576 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
577 val = alc_pin_mode_min(dir);
579 change = pinctl != alc_pin_mode_values[val];
581 /* Set pin mode to that requested */
582 snd_hda_codec_write_cache(codec, nid, 0,
583 AC_VERB_SET_PIN_WIDGET_CONTROL,
584 alc_pin_mode_values[val]);
586 /* Also enable the retasking pin's input/output as required
587 * for the requested pin mode. Enum values of 2 or less are
590 * Dynamically switching the input/output buffers probably
591 * reduces noise slightly (particularly on input) so we'll
592 * do it. However, having both input and output buffers
593 * enabled simultaneously doesn't seem to be problematic if
594 * this turns out to be necessary in the future.
597 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
598 HDA_AMP_MUTE, HDA_AMP_MUTE);
599 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
602 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
603 HDA_AMP_MUTE, HDA_AMP_MUTE);
604 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
611 #define ALC_PIN_MODE(xname, nid, dir) \
612 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
613 .info = alc_pin_mode_info, \
614 .get = alc_pin_mode_get, \
615 .put = alc_pin_mode_put, \
616 .private_value = nid | (dir<<16) }
618 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
619 * together using a mask with more than one bit set. This control is
620 * currently used only by the ALC260 test model. At this stage they are not
621 * needed for any "production" models.
623 #ifdef CONFIG_SND_DEBUG
624 #define alc_gpio_data_info snd_ctl_boolean_mono_info
626 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_value *ucontrol)
629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
630 hda_nid_t nid = kcontrol->private_value & 0xffff;
631 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
632 long *valp = ucontrol->value.integer.value;
633 unsigned int val = snd_hda_codec_read(codec, nid, 0,
634 AC_VERB_GET_GPIO_DATA, 0x00);
636 *valp = (val & mask) != 0;
639 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644 hda_nid_t nid = kcontrol->private_value & 0xffff;
645 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
646 long val = *ucontrol->value.integer.value;
647 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
648 AC_VERB_GET_GPIO_DATA,
651 /* Set/unset the masked GPIO bit(s) as needed */
652 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
657 snd_hda_codec_write_cache(codec, nid, 0,
658 AC_VERB_SET_GPIO_DATA, gpio_data);
662 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
663 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
664 .info = alc_gpio_data_info, \
665 .get = alc_gpio_data_get, \
666 .put = alc_gpio_data_put, \
667 .private_value = nid | (mask<<16) }
668 #endif /* CONFIG_SND_DEBUG */
670 /* A switch control to allow the enabling of the digital IO pins on the
671 * ALC260. This is incredibly simplistic; the intention of this control is
672 * to provide something in the test model allowing digital outputs to be
673 * identified if present. If models are found which can utilise these
674 * outputs a more complete mixer control can be devised for those models if
677 #ifdef CONFIG_SND_DEBUG
678 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
680 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684 hda_nid_t nid = kcontrol->private_value & 0xffff;
685 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686 long *valp = ucontrol->value.integer.value;
687 unsigned int val = snd_hda_codec_read(codec, nid, 0,
688 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
690 *valp = (val & mask) != 0;
693 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
694 struct snd_ctl_elem_value *ucontrol)
697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
698 hda_nid_t nid = kcontrol->private_value & 0xffff;
699 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
700 long val = *ucontrol->value.integer.value;
701 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
702 AC_VERB_GET_DIGI_CONVERT_1,
705 /* Set/unset the masked control bit(s) as needed */
706 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
711 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
716 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
717 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
718 .info = alc_spdif_ctrl_info, \
719 .get = alc_spdif_ctrl_get, \
720 .put = alc_spdif_ctrl_put, \
721 .private_value = nid | (mask<<16) }
722 #endif /* CONFIG_SND_DEBUG */
724 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
725 * Again, this is only used in the ALC26x test models to help identify when
726 * the EAPD line must be asserted for features to work.
728 #ifdef CONFIG_SND_DEBUG
729 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
731 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
732 struct snd_ctl_elem_value *ucontrol)
734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
735 hda_nid_t nid = kcontrol->private_value & 0xffff;
736 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
737 long *valp = ucontrol->value.integer.value;
738 unsigned int val = snd_hda_codec_read(codec, nid, 0,
739 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
741 *valp = (val & mask) != 0;
745 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
746 struct snd_ctl_elem_value *ucontrol)
749 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
750 hda_nid_t nid = kcontrol->private_value & 0xffff;
751 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
752 long val = *ucontrol->value.integer.value;
753 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
754 AC_VERB_GET_EAPD_BTLENABLE,
757 /* Set/unset the masked control bit(s) as needed */
758 change = (!val ? 0 : mask) != (ctrl_data & mask);
763 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
769 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
770 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
771 .info = alc_eapd_ctrl_info, \
772 .get = alc_eapd_ctrl_get, \
773 .put = alc_eapd_ctrl_put, \
774 .private_value = nid | (mask<<16) }
775 #endif /* CONFIG_SND_DEBUG */
778 * set up the input pin config (depending on the given auto-pin type)
780 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
783 unsigned int val = PIN_IN;
785 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
787 pincap = snd_hda_query_pin_caps(codec, nid);
788 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
789 if (pincap & AC_PINCAP_VREF_80)
791 else if (pincap & AC_PINCAP_VREF_50)
793 else if (pincap & AC_PINCAP_VREF_100)
795 else if (pincap & AC_PINCAP_VREF_GRD)
798 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
803 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
805 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
807 spec->mixers[spec->num_mixers++] = mix;
810 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
812 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
814 spec->init_verbs[spec->num_init_verbs++] = verb;
817 #ifdef CONFIG_PROC_FS
821 static void print_realtek_coef(struct snd_info_buffer *buffer,
822 struct hda_codec *codec, hda_nid_t nid)
828 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
829 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
830 coeff = snd_hda_codec_read(codec, nid, 0,
831 AC_VERB_GET_COEF_INDEX, 0);
832 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
835 #define print_realtek_coef NULL
839 * set up from the preset table
841 static void setup_preset(struct alc_spec *spec,
842 const struct alc_config_preset *preset)
846 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
847 add_mixer(spec, preset->mixers[i]);
848 spec->cap_mixer = preset->cap_mixer;
849 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
851 add_verb(spec, preset->init_verbs[i]);
853 spec->channel_mode = preset->channel_mode;
854 spec->num_channel_mode = preset->num_channel_mode;
855 spec->need_dac_fix = preset->need_dac_fix;
856 spec->const_channel_count = preset->const_channel_count;
858 if (preset->const_channel_count)
859 spec->multiout.max_channels = preset->const_channel_count;
861 spec->multiout.max_channels = spec->channel_mode[0].channels;
862 spec->ext_channel_count = spec->channel_mode[0].channels;
864 spec->multiout.num_dacs = preset->num_dacs;
865 spec->multiout.dac_nids = preset->dac_nids;
866 spec->multiout.dig_out_nid = preset->dig_out_nid;
867 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
868 spec->multiout.hp_nid = preset->hp_nid;
870 spec->num_mux_defs = preset->num_mux_defs;
871 if (!spec->num_mux_defs)
872 spec->num_mux_defs = 1;
873 spec->input_mux = preset->input_mux;
875 spec->num_adc_nids = preset->num_adc_nids;
876 spec->adc_nids = preset->adc_nids;
877 spec->capsrc_nids = preset->capsrc_nids;
878 spec->dig_in_nid = preset->dig_in_nid;
880 spec->unsol_event = preset->unsol_event;
881 spec->init_hook = preset->init_hook;
882 #ifdef CONFIG_SND_HDA_POWER_SAVE
883 spec->loopback.amplist = preset->loopbacks;
887 /* Enable GPIO mask and set output */
888 static struct hda_verb alc_gpio1_init_verbs[] = {
889 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
890 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
891 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
895 static struct hda_verb alc_gpio2_init_verbs[] = {
896 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
897 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
898 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
902 static struct hda_verb alc_gpio3_init_verbs[] = {
903 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
904 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
905 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
910 * Fix hardware PLL issue
911 * On some codecs, the analog PLL gating control must be off while
912 * the default value is 1.
914 static void alc_fix_pll(struct hda_codec *codec)
916 struct alc_spec *spec = codec->spec;
921 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
923 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
924 AC_VERB_GET_PROC_COEF, 0);
925 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
927 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
928 val & ~(1 << spec->pll_coef_bit));
931 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
932 unsigned int coef_idx, unsigned int coef_bit)
934 struct alc_spec *spec = codec->spec;
936 spec->pll_coef_idx = coef_idx;
937 spec->pll_coef_bit = coef_bit;
941 static void alc_automute_pin(struct hda_codec *codec)
943 struct alc_spec *spec = codec->spec;
944 unsigned int present, pincap;
945 unsigned int nid = spec->autocfg.hp_pins[0];
948 pincap = snd_hda_query_pin_caps(codec, nid);
949 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
950 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
951 present = snd_hda_codec_read(codec, nid, 0,
952 AC_VERB_GET_PIN_SENSE, 0);
953 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
954 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
955 nid = spec->autocfg.speaker_pins[i];
958 snd_hda_codec_write(codec, nid, 0,
959 AC_VERB_SET_PIN_WIDGET_CONTROL,
960 spec->jack_present ? 0 : PIN_OUT);
964 #if 0 /* it's broken in some cases -- temporarily disabled */
965 static void alc_mic_automute(struct hda_codec *codec)
967 struct alc_spec *spec = codec->spec;
968 unsigned int present;
969 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
970 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
971 unsigned int mix_nid = spec->capsrc_nids[0];
972 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
974 capsrc_idx_mic = mic_nid - 0x18;
975 capsrc_idx_fmic = fmic_nid - 0x18;
976 present = snd_hda_codec_read(codec, mic_nid, 0,
977 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
978 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
979 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
980 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
981 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
982 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
983 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
986 #define alc_mic_automute(codec) do {} while(0) /* NOP */
987 #endif /* disabled */
989 /* unsolicited event for HP jack sensing */
990 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
992 if (codec->vendor_id == 0x10ec0880)
997 case ALC880_HP_EVENT:
998 alc_automute_pin(codec);
1000 case ALC880_MIC_EVENT:
1001 alc_mic_automute(codec);
1006 static void alc_inithook(struct hda_codec *codec)
1008 alc_automute_pin(codec);
1009 alc_mic_automute(codec);
1012 /* additional initialization for ALC888 variants */
1013 static void alc888_coef_init(struct hda_codec *codec)
1017 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1018 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1019 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1020 if ((tmp & 0xf0) == 0x20)
1022 snd_hda_codec_read(codec, 0x20, 0,
1023 AC_VERB_SET_PROC_COEF, 0x830);
1026 snd_hda_codec_read(codec, 0x20, 0,
1027 AC_VERB_SET_PROC_COEF, 0x3030);
1030 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1035 case ALC_INIT_GPIO1:
1036 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1038 case ALC_INIT_GPIO2:
1039 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1041 case ALC_INIT_GPIO3:
1042 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1044 case ALC_INIT_DEFAULT:
1045 switch (codec->vendor_id) {
1047 snd_hda_codec_write(codec, 0x0f, 0,
1048 AC_VERB_SET_EAPD_BTLENABLE, 2);
1049 snd_hda_codec_write(codec, 0x10, 0,
1050 AC_VERB_SET_EAPD_BTLENABLE, 2);
1062 snd_hda_codec_write(codec, 0x14, 0,
1063 AC_VERB_SET_EAPD_BTLENABLE, 2);
1064 snd_hda_codec_write(codec, 0x15, 0,
1065 AC_VERB_SET_EAPD_BTLENABLE, 2);
1068 switch (codec->vendor_id) {
1070 snd_hda_codec_write(codec, 0x1a, 0,
1071 AC_VERB_SET_COEF_INDEX, 7);
1072 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1073 AC_VERB_GET_PROC_COEF, 0);
1074 snd_hda_codec_write(codec, 0x1a, 0,
1075 AC_VERB_SET_COEF_INDEX, 7);
1076 snd_hda_codec_write(codec, 0x1a, 0,
1077 AC_VERB_SET_PROC_COEF,
1087 snd_hda_codec_write(codec, 0x20, 0,
1088 AC_VERB_SET_COEF_INDEX, 7);
1089 tmp = snd_hda_codec_read(codec, 0x20, 0,
1090 AC_VERB_GET_PROC_COEF, 0);
1091 snd_hda_codec_write(codec, 0x20, 0,
1092 AC_VERB_SET_COEF_INDEX, 7);
1093 snd_hda_codec_write(codec, 0x20, 0,
1094 AC_VERB_SET_PROC_COEF,
1098 alc888_coef_init(codec);
1102 snd_hda_codec_write(codec, 0x20, 0,
1103 AC_VERB_SET_COEF_INDEX, 7);
1104 tmp = snd_hda_codec_read(codec, 0x20, 0,
1105 AC_VERB_GET_PROC_COEF, 0);
1106 snd_hda_codec_write(codec, 0x20, 0,
1107 AC_VERB_SET_COEF_INDEX, 7);
1108 snd_hda_codec_write(codec, 0x20, 0,
1109 AC_VERB_SET_PROC_COEF,
1117 static void alc_init_auto_hp(struct hda_codec *codec)
1119 struct alc_spec *spec = codec->spec;
1121 if (!spec->autocfg.hp_pins[0])
1124 if (!spec->autocfg.speaker_pins[0]) {
1125 if (spec->autocfg.line_out_pins[0] &&
1126 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1127 spec->autocfg.speaker_pins[0] =
1128 spec->autocfg.line_out_pins[0];
1133 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1134 spec->autocfg.hp_pins[0]);
1135 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1136 AC_VERB_SET_UNSOLICITED_ENABLE,
1137 AC_USRSP_EN | ALC880_HP_EVENT);
1138 spec->unsol_event = alc_sku_unsol_event;
1141 /* check subsystem ID and set up device-specific initialization;
1142 * return 1 if initialized, 0 if invalid SSID
1144 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1145 * 31 ~ 16 : Manufacture ID
1147 * 7 ~ 0 : Assembly ID
1148 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1150 static int alc_subsystem_id(struct hda_codec *codec,
1151 hda_nid_t porta, hda_nid_t porte,
1154 unsigned int ass, tmp, i;
1156 struct alc_spec *spec = codec->spec;
1158 ass = codec->subsystem_id & 0xffff;
1159 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1162 /* invalid SSID, check the special NID pin defcfg instead */
1164 * 31~30 : port connectivity
1167 * 19~16 : Check sum (15:1)
1172 if (codec->vendor_id == 0x10ec0260)
1174 ass = snd_hda_codec_get_pincfg(codec, nid);
1175 snd_printd("realtek: No valid SSID, "
1176 "checking pincfg 0x%08x for NID 0x%x\n",
1178 if (!(ass & 1) && !(ass & 0x100000))
1180 if ((ass >> 30) != 1) /* no physical connection */
1185 for (i = 1; i < 16; i++) {
1189 if (((ass >> 16) & 0xf) != tmp)
1192 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1193 ass & 0xffff, codec->vendor_id);
1197 * 2 : 0 --> Desktop, 1 --> Laptop
1198 * 3~5 : External Amplifier control
1201 tmp = (ass & 0x38) >> 3; /* external Amp control */
1204 spec->init_amp = ALC_INIT_GPIO1;
1207 spec->init_amp = ALC_INIT_GPIO2;
1210 spec->init_amp = ALC_INIT_GPIO3;
1213 spec->init_amp = ALC_INIT_DEFAULT;
1217 /* is laptop or Desktop and enable the function "Mute internal speaker
1218 * when the external headphone out jack is plugged"
1220 if (!(ass & 0x8000))
1223 * 10~8 : Jack location
1224 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1226 * 15 : 1 --> enable the function "Mute internal speaker
1227 * when the external headphone out jack is plugged"
1229 if (!spec->autocfg.hp_pins[0]) {
1230 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1232 spec->autocfg.hp_pins[0] = porta;
1234 spec->autocfg.hp_pins[0] = porte;
1236 spec->autocfg.hp_pins[0] = portd;
1241 alc_init_auto_hp(codec);
1245 static void alc_ssid_check(struct hda_codec *codec,
1246 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1248 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1249 struct alc_spec *spec = codec->spec;
1250 snd_printd("realtek: "
1251 "Enable default setup for auto mode as fallback\n");
1252 spec->init_amp = ALC_INIT_DEFAULT;
1253 alc_init_auto_hp(codec);
1258 * Fix-up pin default configurations
1266 static void alc_fix_pincfg(struct hda_codec *codec,
1267 const struct snd_pci_quirk *quirk,
1268 const struct alc_pincfg **pinfix)
1270 const struct alc_pincfg *cfg;
1272 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1276 cfg = pinfix[quirk->value];
1277 for (; cfg->nid; cfg++)
1278 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1288 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1289 /* Mic-in jack as mic in */
1290 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1291 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1292 /* Line-in jack as Line in */
1293 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1294 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1295 /* Line-Out as Front */
1296 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1303 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1304 /* Mic-in jack as mic in */
1305 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1306 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1307 /* Line-in jack as Surround */
1308 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1309 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1310 /* Line-Out as Front */
1311 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1318 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1319 /* Mic-in jack as CLFE */
1320 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1321 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1322 /* Line-in jack as Surround */
1323 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1324 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1325 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1326 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1333 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1334 /* Mic-in jack as CLFE */
1335 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1336 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1337 /* Line-in jack as Surround */
1338 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1339 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1340 /* Line-Out as Side */
1341 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1345 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1346 { 2, alc888_4ST_ch2_intel_init },
1347 { 4, alc888_4ST_ch4_intel_init },
1348 { 6, alc888_4ST_ch6_intel_init },
1349 { 8, alc888_4ST_ch8_intel_init },
1353 * ALC888 Fujitsu Siemens Amillo xa3530
1356 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1357 /* Front Mic: set to PIN_IN (empty by default) */
1358 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1359 /* Connect Internal HP to Front */
1360 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1363 /* Connect Bass HP to Front */
1364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1367 /* Connect Line-Out side jack (SPDIF) to Side */
1368 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1369 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1370 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1371 /* Connect Mic jack to CLFE */
1372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1374 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1375 /* Connect Line-in jack to Surround */
1376 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1378 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1379 /* Connect HP out jack to Front */
1380 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1381 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1382 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1383 /* Enable unsolicited event for HP jack and Line-out jack */
1384 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1385 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1389 static void alc_automute_amp(struct hda_codec *codec)
1391 struct alc_spec *spec = codec->spec;
1392 unsigned int val, mute, pincap;
1396 spec->jack_present = 0;
1397 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1398 nid = spec->autocfg.hp_pins[i];
1401 pincap = snd_hda_query_pin_caps(codec, nid);
1402 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1403 snd_hda_codec_read(codec, nid, 0,
1404 AC_VERB_SET_PIN_SENSE, 0);
1405 val = snd_hda_codec_read(codec, nid, 0,
1406 AC_VERB_GET_PIN_SENSE, 0);
1407 if (val & AC_PINSENSE_PRESENCE) {
1408 spec->jack_present = 1;
1413 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1414 /* Toggle internal speakers muting */
1415 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1416 nid = spec->autocfg.speaker_pins[i];
1419 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1420 HDA_AMP_MUTE, mute);
1424 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1427 if (codec->vendor_id == 0x10ec0880)
1431 if (res == ALC880_HP_EVENT)
1432 alc_automute_amp(codec);
1435 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1437 struct alc_spec *spec = codec->spec;
1439 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1440 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1441 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1442 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1443 alc_automute_amp(codec);
1447 * ALC888 Acer Aspire 4930G model
1450 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1451 /* Front Mic: set to PIN_IN (empty by default) */
1452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1453 /* Unselect Front Mic by default in input mixer 3 */
1454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1455 /* Enable unsolicited event for HP jack */
1456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1457 /* Connect Internal HP to front */
1458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1459 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1460 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1461 /* Connect HP out to front */
1462 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1463 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1464 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1469 * ALC888 Acer Aspire 6530G model
1472 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1473 /* Bias voltage on for external mic port */
1474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1475 /* Front Mic: set to PIN_IN (empty by default) */
1476 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477 /* Unselect Front Mic by default in input mixer 3 */
1478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1479 /* Enable unsolicited event for HP jack */
1480 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1481 /* Enable speaker output */
1482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1484 /* Enable headphone output */
1485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1487 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1492 * ALC889 Acer Aspire 8930G model
1495 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1496 /* Front Mic: set to PIN_IN (empty by default) */
1497 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1498 /* Unselect Front Mic by default in input mixer 3 */
1499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1500 /* Enable unsolicited event for HP jack */
1501 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1502 /* Connect Internal Front to Front */
1503 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1505 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1506 /* Connect Internal Rear to Rear */
1507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1509 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1510 /* Connect Internal CLFE to CLFE */
1511 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1512 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1513 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1514 /* Connect HP out to Front */
1515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1518 /* Enable all DACs */
1519 /* DAC DISABLE/MUTE 1? */
1520 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1521 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1522 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1523 /* DAC DISABLE/MUTE 2? */
1524 /* some bit here disables the other DACs. Init=0x4900 */
1525 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1526 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1527 /* Enable amplifiers */
1528 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1529 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1531 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1532 * which makes the stereo useless. However, either the mic or the ALC889
1533 * makes the signal become a difference/sum signal instead of standard
1534 * stereo, which is annoying. So instead we flip this bit which makes the
1535 * codec replicate the sum signal to both channels, turning it into a
1538 /* DMIC_CONTROL? Init value = 0x0001 */
1539 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1540 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1544 static struct hda_input_mux alc888_2_capture_sources[2] = {
1545 /* Front mic only available on one ADC */
1552 { "Front Mic", 0xb },
1565 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1566 /* Interal mic only available on one ADC */
1573 { "Input Mix", 0xa },
1583 { "Input Mix", 0xa },
1588 static struct hda_input_mux alc889_capture_sources[3] = {
1589 /* Digital mic only available on first "ADC" */
1596 { "Front Mic", 0xb },
1597 { "Input Mix", 0xa },
1606 { "Input Mix", 0xa },
1615 { "Input Mix", 0xa },
1620 static struct snd_kcontrol_new alc888_base_mixer[] = {
1621 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1622 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1623 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1624 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1625 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1628 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1629 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1630 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1631 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1634 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1635 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1637 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1642 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1644 struct alc_spec *spec = codec->spec;
1646 spec->autocfg.hp_pins[0] = 0x15;
1647 spec->autocfg.speaker_pins[0] = 0x14;
1648 alc_automute_amp(codec);
1651 static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec)
1653 struct alc_spec *spec = codec->spec;
1655 spec->autocfg.hp_pins[0] = 0x15;
1656 spec->autocfg.speaker_pins[0] = 0x14;
1657 spec->autocfg.speaker_pins[1] = 0x16;
1658 spec->autocfg.speaker_pins[2] = 0x17;
1659 alc_automute_amp(codec);
1662 static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
1664 struct alc_spec *spec = codec->spec;
1666 spec->autocfg.hp_pins[0] = 0x15;
1667 spec->autocfg.speaker_pins[0] = 0x14;
1668 spec->autocfg.speaker_pins[1] = 0x16;
1669 spec->autocfg.speaker_pins[2] = 0x1b;
1670 alc_automute_amp(codec);
1674 * ALC880 3-stack model
1676 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1677 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1678 * F-Mic = 0x1b, HP = 0x19
1681 static hda_nid_t alc880_dac_nids[4] = {
1682 /* front, rear, clfe, rear_surr */
1683 0x02, 0x05, 0x04, 0x03
1686 static hda_nid_t alc880_adc_nids[3] = {
1691 /* The datasheet says the node 0x07 is connected from inputs,
1692 * but it shows zero connection in the real implementation on some devices.
1693 * Note: this is a 915GAV bug, fixed on 915GLV
1695 static hda_nid_t alc880_adc_nids_alt[2] = {
1700 #define ALC880_DIGOUT_NID 0x06
1701 #define ALC880_DIGIN_NID 0x0a
1703 static struct hda_input_mux alc880_capture_source = {
1707 { "Front Mic", 0x3 },
1713 /* channel source setting (2/6 channel selection for 3-stack) */
1715 static struct hda_verb alc880_threestack_ch2_init[] = {
1716 /* set line-in to input, mute it */
1717 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1718 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1719 /* set mic-in to input vref 80%, mute it */
1720 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1721 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1726 static struct hda_verb alc880_threestack_ch6_init[] = {
1727 /* set line-in to output, unmute it */
1728 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1729 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1730 /* set mic-in to output, unmute it */
1731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1736 static struct hda_channel_mode alc880_threestack_modes[2] = {
1737 { 2, alc880_threestack_ch2_init },
1738 { 6, alc880_threestack_ch6_init },
1741 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1742 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1743 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1744 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1745 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1746 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1747 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1748 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1749 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1750 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1751 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1752 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1753 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1755 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1756 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1757 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1761 .name = "Channel Mode",
1762 .info = alc_ch_mode_info,
1763 .get = alc_ch_mode_get,
1764 .put = alc_ch_mode_put,
1769 /* capture mixer elements */
1770 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1771 struct snd_ctl_elem_info *uinfo)
1773 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1774 struct alc_spec *spec = codec->spec;
1777 mutex_lock(&codec->control_mutex);
1778 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1780 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1781 mutex_unlock(&codec->control_mutex);
1785 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1786 unsigned int size, unsigned int __user *tlv)
1788 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1789 struct alc_spec *spec = codec->spec;
1792 mutex_lock(&codec->control_mutex);
1793 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1795 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1796 mutex_unlock(&codec->control_mutex);
1800 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1801 struct snd_ctl_elem_value *ucontrol);
1803 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1804 struct snd_ctl_elem_value *ucontrol,
1807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1808 struct alc_spec *spec = codec->spec;
1809 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1812 mutex_lock(&codec->control_mutex);
1813 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1815 err = func(kcontrol, ucontrol);
1816 mutex_unlock(&codec->control_mutex);
1820 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1821 struct snd_ctl_elem_value *ucontrol)
1823 return alc_cap_getput_caller(kcontrol, ucontrol,
1824 snd_hda_mixer_amp_volume_get);
1827 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1828 struct snd_ctl_elem_value *ucontrol)
1830 return alc_cap_getput_caller(kcontrol, ucontrol,
1831 snd_hda_mixer_amp_volume_put);
1834 /* capture mixer elements */
1835 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1837 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1838 struct snd_ctl_elem_value *ucontrol)
1840 return alc_cap_getput_caller(kcontrol, ucontrol,
1841 snd_hda_mixer_amp_switch_get);
1844 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1845 struct snd_ctl_elem_value *ucontrol)
1847 return alc_cap_getput_caller(kcontrol, ucontrol,
1848 snd_hda_mixer_amp_switch_put);
1851 #define _DEFINE_CAPMIX(num) \
1853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1854 .name = "Capture Switch", \
1855 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1857 .info = alc_cap_sw_info, \
1858 .get = alc_cap_sw_get, \
1859 .put = alc_cap_sw_put, \
1862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1863 .name = "Capture Volume", \
1864 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1865 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1866 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1868 .info = alc_cap_vol_info, \
1869 .get = alc_cap_vol_get, \
1870 .put = alc_cap_vol_put, \
1871 .tlv = { .c = alc_cap_vol_tlv }, \
1874 #define _DEFINE_CAPSRC(num) \
1876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1877 /* .name = "Capture Source", */ \
1878 .name = "Input Source", \
1880 .info = alc_mux_enum_info, \
1881 .get = alc_mux_enum_get, \
1882 .put = alc_mux_enum_put, \
1885 #define DEFINE_CAPMIX(num) \
1886 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1887 _DEFINE_CAPMIX(num), \
1888 _DEFINE_CAPSRC(num), \
1892 #define DEFINE_CAPMIX_NOSRC(num) \
1893 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1894 _DEFINE_CAPMIX(num), \
1898 /* up to three ADCs */
1902 DEFINE_CAPMIX_NOSRC(1);
1903 DEFINE_CAPMIX_NOSRC(2);
1904 DEFINE_CAPMIX_NOSRC(3);
1907 * ALC880 5-stack model
1909 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1911 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1912 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1915 /* additional mixers to alc880_three_stack_mixer */
1916 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1917 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1918 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1922 /* channel source setting (6/8 channel selection for 5-stack) */
1924 static struct hda_verb alc880_fivestack_ch6_init[] = {
1925 /* set line-in to input, mute it */
1926 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1927 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1932 static struct hda_verb alc880_fivestack_ch8_init[] = {
1933 /* set line-in to output, unmute it */
1934 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1935 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1939 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1940 { 6, alc880_fivestack_ch6_init },
1941 { 8, alc880_fivestack_ch8_init },
1946 * ALC880 6-stack model
1948 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1949 * Side = 0x05 (0x0f)
1950 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1951 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1954 static hda_nid_t alc880_6st_dac_nids[4] = {
1955 /* front, rear, clfe, rear_surr */
1956 0x02, 0x03, 0x04, 0x05
1959 static struct hda_input_mux alc880_6stack_capture_source = {
1963 { "Front Mic", 0x1 },
1969 /* fixed 8-channels */
1970 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1974 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1977 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1978 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1979 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1980 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1981 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1982 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1983 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1984 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1995 .name = "Channel Mode",
1996 .info = alc_ch_mode_info,
1997 .get = alc_ch_mode_get,
1998 .put = alc_ch_mode_put,
2007 * W810 has rear IO for:
2010 * Center/LFE (DAC 04)
2013 * The system also has a pair of internal speakers, and a headphone jack.
2014 * These are both connected to Line2 on the codec, hence to DAC 02.
2016 * There is a variable resistor to control the speaker or headphone
2017 * volume. This is a hardware-only device without a software API.
2019 * Plugging headphones in will disable the internal speakers. This is
2020 * implemented in hardware, not via the driver using jack sense. In
2021 * a similar fashion, plugging into the rear socket marked "front" will
2022 * disable both the speakers and headphones.
2024 * For input, there's a microphone jack, and an "audio in" jack.
2025 * These may not do anything useful with this driver yet, because I
2026 * haven't setup any initialization verbs for these yet...
2029 static hda_nid_t alc880_w810_dac_nids[3] = {
2030 /* front, rear/surround, clfe */
2034 /* fixed 6 channels */
2035 static struct hda_channel_mode alc880_w810_modes[1] = {
2039 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2040 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2041 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2042 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2043 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2044 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2045 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2046 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2047 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2048 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2049 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2057 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2058 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2062 static hda_nid_t alc880_z71v_dac_nids[1] = {
2065 #define ALC880_Z71V_HP_DAC 0x03
2067 /* fixed 2 channels */
2068 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2072 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2074 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2076 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
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),
2086 * ALC880 F1734 model
2088 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2089 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2092 static hda_nid_t alc880_f1734_dac_nids[1] = {
2095 #define ALC880_F1734_HP_DAC 0x02
2097 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2098 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2099 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2101 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2102 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2103 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2104 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2109 static struct hda_input_mux alc880_f1734_capture_source = {
2121 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2122 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2123 * Mic = 0x18, Line = 0x1a
2126 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2127 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2129 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2130 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2131 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2132 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2133 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2134 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2135 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2136 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2137 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2145 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2146 .name = "Channel Mode",
2147 .info = alc_ch_mode_info,
2148 .get = alc_ch_mode_get,
2149 .put = alc_ch_mode_put,
2155 * ALC880 ASUS W1V model
2157 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2158 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2159 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2162 /* additional mixers to alc880_asus_mixer */
2163 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2164 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2165 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2170 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2172 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2174 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2175 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2178 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2179 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2184 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2186 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2187 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2188 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2189 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2190 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2191 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2192 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2193 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2194 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2195 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2196 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2198 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2200 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2202 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2203 .name = "Channel Mode",
2204 .info = alc_ch_mode_info,
2205 .get = alc_ch_mode_get,
2206 .put = alc_ch_mode_put,
2211 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2213 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2215 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2218 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2219 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2220 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2221 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2225 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2228 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2229 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2236 * virtual master controls
2240 * slave controls for virtual master
2242 static const char *alc_slave_vols[] = {
2243 "Front Playback Volume",
2244 "Surround Playback Volume",
2245 "Center Playback Volume",
2246 "LFE Playback Volume",
2247 "Side Playback Volume",
2248 "Headphone Playback Volume",
2249 "Speaker Playback Volume",
2250 "Mono Playback Volume",
2251 "Line-Out Playback Volume",
2252 "PCM Playback Volume",
2256 static const char *alc_slave_sws[] = {
2257 "Front Playback Switch",
2258 "Surround Playback Switch",
2259 "Center Playback Switch",
2260 "LFE Playback Switch",
2261 "Side Playback Switch",
2262 "Headphone Playback Switch",
2263 "Speaker Playback Switch",
2264 "Mono Playback Switch",
2265 "IEC958 Playback Switch",
2270 * build control elements
2273 static void alc_free_kctls(struct hda_codec *codec);
2275 /* additional beep mixers; the actual parameters are overwritten at build */
2276 static struct snd_kcontrol_new alc_beep_mixer[] = {
2277 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2278 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2282 static int alc_build_controls(struct hda_codec *codec)
2284 struct alc_spec *spec = codec->spec;
2288 for (i = 0; i < spec->num_mixers; i++) {
2289 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2293 if (spec->cap_mixer) {
2294 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2298 if (spec->multiout.dig_out_nid) {
2299 err = snd_hda_create_spdif_out_ctls(codec,
2300 spec->multiout.dig_out_nid);
2303 if (!spec->no_analog) {
2304 err = snd_hda_create_spdif_share_sw(codec,
2308 spec->multiout.share_spdif = 1;
2311 if (spec->dig_in_nid) {
2312 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2317 /* create beep controls if needed */
2318 if (spec->beep_amp) {
2319 struct snd_kcontrol_new *knew;
2320 for (knew = alc_beep_mixer; knew->name; knew++) {
2321 struct snd_kcontrol *kctl;
2322 kctl = snd_ctl_new1(knew, codec);
2325 kctl->private_value = spec->beep_amp;
2326 err = snd_hda_ctl_add(codec, kctl);
2332 /* if we have no master control, let's create it */
2333 if (!spec->no_analog &&
2334 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2335 unsigned int vmaster_tlv[4];
2336 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2337 HDA_OUTPUT, vmaster_tlv);
2338 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2339 vmaster_tlv, alc_slave_vols);
2343 if (!spec->no_analog &&
2344 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2345 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2346 NULL, alc_slave_sws);
2351 alc_free_kctls(codec); /* no longer needed */
2357 * initialize the codec volumes, etc
2361 * generic initialization of ADC, input mixers and output mixers
2363 static struct hda_verb alc880_volume_init_verbs[] = {
2365 * Unmute ADC0-2 and set the default input to mic-in
2367 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2368 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2369 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2370 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2371 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2372 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2374 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2376 * Note: PASD motherboards uses the Line In 2 as the input for front
2379 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2382 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2389 * Set up output mixers (0x0c - 0x0f)
2391 /* set vol=0 to output mixers */
2392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2395 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2396 /* set up input amps for analog loopback */
2397 /* Amp Indices: DAC = 0, mixer = 1 */
2398 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2402 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2411 * 3-stack pin configuration:
2412 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2414 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2416 * preset connection lists of input pins
2417 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2419 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2420 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2421 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2424 * Set pin mode and muting
2426 /* set front pin widgets 0x14 for output */
2427 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2428 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2429 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2430 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2432 /* Mic2 (as headphone out) for HP output */
2433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2435 /* Line In pin widget for input */
2436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2438 /* Line2 (as front mic) pin widget for input and vref at 80% */
2439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2441 /* CD pin widget for input */
2442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2448 * 5-stack pin configuration:
2449 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2450 * line-in/side = 0x1a, f-mic = 0x1b
2452 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2454 * preset connection lists of input pins
2455 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2457 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2458 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2461 * Set pin mode and muting
2463 /* set pin widgets 0x14-0x17 for output */
2464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2467 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2468 /* unmute pins for output (no gain on this amp) */
2469 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2471 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2472 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2474 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2475 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2476 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2477 /* Mic2 (as headphone out) for HP output */
2478 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2479 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2480 /* Line In pin widget for input */
2481 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2482 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2483 /* Line2 (as front mic) pin widget for input and vref at 80% */
2484 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2485 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2486 /* CD pin widget for input */
2487 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2493 * W810 pin configuration:
2494 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2496 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2497 /* hphone/speaker input selector: front DAC */
2498 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2501 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2514 * Z71V pin configuration:
2515 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2517 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2518 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2519 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2520 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2521 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2524 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2526 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2532 * 6-stack pin configuration:
2533 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2534 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2536 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2537 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2544 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2545 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2548 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2549 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2550 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2551 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2552 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2556 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2562 * Uniwill pin configuration:
2563 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2566 static struct hda_verb alc880_uniwill_init_verbs[] = {
2567 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2572 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2574 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2575 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2576 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2580 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2584 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2590 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2591 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2594 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2595 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2602 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2604 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2605 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2611 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2621 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2622 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2623 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2624 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2625 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2627 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2628 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2633 static struct hda_verb alc880_beep_init_verbs[] = {
2634 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2638 /* auto-toggle front mic */
2639 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2641 unsigned int present;
2644 present = snd_hda_codec_read(codec, 0x18, 0,
2645 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2646 bits = present ? HDA_AMP_MUTE : 0;
2647 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2650 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2652 struct alc_spec *spec = codec->spec;
2654 spec->autocfg.hp_pins[0] = 0x14;
2655 spec->autocfg.speaker_pins[0] = 0x15;
2656 spec->autocfg.speaker_pins[0] = 0x16;
2657 alc_automute_amp(codec);
2658 alc880_uniwill_mic_automute(codec);
2661 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2664 /* Looks like the unsol event is incompatible with the standard
2665 * definition. 4bit tag is placed at 28 bit!
2667 switch (res >> 28) {
2668 case ALC880_MIC_EVENT:
2669 alc880_uniwill_mic_automute(codec);
2672 alc_automute_amp_unsol_event(codec, res);
2677 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2679 struct alc_spec *spec = codec->spec;
2681 spec->autocfg.hp_pins[0] = 0x14;
2682 spec->autocfg.speaker_pins[0] = 0x15;
2683 alc_automute_amp(codec);
2686 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2688 unsigned int present;
2690 present = snd_hda_codec_read(codec, 0x21, 0,
2691 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2692 present &= HDA_AMP_VOLMASK;
2693 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2694 HDA_AMP_VOLMASK, present);
2695 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2696 HDA_AMP_VOLMASK, present);
2699 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2702 /* Looks like the unsol event is incompatible with the standard
2703 * definition. 4bit tag is placed at 28 bit!
2705 if ((res >> 28) == ALC880_DCVOL_EVENT)
2706 alc880_uniwill_p53_dcvol_automute(codec);
2708 alc_automute_amp_unsol_event(codec, res);
2712 * F1734 pin configuration:
2713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2715 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2716 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2717 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2719 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2720 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2734 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2737 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2738 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2744 * ASUS pin configuration:
2745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2747 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2748 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2749 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2750 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2751 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2757 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2775 /* Enable GPIO mask and set output */
2776 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2777 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2778 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2780 /* Clevo m520g init */
2781 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2782 /* headphone output */
2783 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2792 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2793 /* Mic1 (rear panel) */
2794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 /* Mic2 (front panel) */
2797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802 /* change to EAPD mode */
2803 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2804 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2809 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2810 /* change to EAPD mode */
2811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2814 /* Headphone output */
2815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2820 /* Line In pin widget for input */
2821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2822 /* CD pin widget for input */
2823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2824 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2825 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2827 /* change to EAPD mode */
2828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2829 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2835 * LG m1 express dual
2838 * Rear Line-In/Out (blue): 0x14
2839 * Build-in Mic-In: 0x15
2841 * HP-Out (green): 0x1b
2842 * Mic-In/Out (red): 0x19
2846 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2847 static hda_nid_t alc880_lg_dac_nids[3] = {
2851 /* seems analog CD is not working */
2852 static struct hda_input_mux alc880_lg_capture_source = {
2857 { "Internal Mic", 0x6 },
2861 /* 2,4,6 channel modes */
2862 static struct hda_verb alc880_lg_ch2_init[] = {
2863 /* set line-in and mic-in to input */
2864 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2869 static struct hda_verb alc880_lg_ch4_init[] = {
2870 /* set line-in to out and mic-in to input */
2871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2876 static struct hda_verb alc880_lg_ch6_init[] = {
2877 /* set line-in and mic-in to output */
2878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2883 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2884 { 2, alc880_lg_ch2_init },
2885 { 4, alc880_lg_ch4_init },
2886 { 6, alc880_lg_ch6_init },
2889 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2891 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2893 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2903 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2906 .name = "Channel Mode",
2907 .info = alc_ch_mode_info,
2908 .get = alc_ch_mode_get,
2909 .put = alc_ch_mode_put,
2914 static struct hda_verb alc880_lg_init_verbs[] = {
2915 /* set capture source to mic-in */
2916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2919 /* mute all amp mixer inputs */
2920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2923 /* line-in to input */
2924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2930 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2931 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 /* mic-in to input */
2933 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2937 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2939 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2945 /* toggle speaker-output according to the hp-jack state */
2946 static void alc880_lg_init_hook(struct hda_codec *codec)
2948 struct alc_spec *spec = codec->spec;
2950 spec->autocfg.hp_pins[0] = 0x1b;
2951 spec->autocfg.speaker_pins[0] = 0x17;
2952 alc_automute_amp(codec);
2961 * Built-in Mic-In: 0x19
2967 static struct hda_input_mux alc880_lg_lw_capture_source = {
2971 { "Internal Mic", 0x1 },
2976 #define alc880_lg_lw_modes alc880_threestack_modes
2978 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2982 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2983 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2991 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2992 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2995 .name = "Channel Mode",
2996 .info = alc_ch_mode_info,
2997 .get = alc_ch_mode_get,
2998 .put = alc_ch_mode_put,
3003 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3004 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3005 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3006 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3008 /* set capture source to mic-in */
3009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3014 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3019 /* mic-in to input */
3020 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3021 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3023 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3024 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3026 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3030 /* toggle speaker-output according to the hp-jack state */
3031 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
3033 struct alc_spec *spec = codec->spec;
3035 spec->autocfg.hp_pins[0] = 0x1b;
3036 spec->autocfg.speaker_pins[0] = 0x14;
3037 alc_automute_amp(codec);
3040 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3041 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3042 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3046 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3050 static struct hda_input_mux alc880_medion_rim_capture_source = {
3054 { "Internal Mic", 0x1 },
3058 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3059 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3061 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3062 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3064 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3065 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3066 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3067 /* Mic2 (as headphone out) for HP output */
3068 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3069 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3070 /* Internal Speaker */
3071 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3072 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3074 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3075 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3077 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3081 /* toggle speaker-output according to the hp-jack state */
3082 static void alc880_medion_rim_automute(struct hda_codec *codec)
3084 struct alc_spec *spec = codec->spec;
3085 alc_automute_amp(codec);
3087 if (spec->jack_present)
3088 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3090 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3093 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3096 /* Looks like the unsol event is incompatible with the standard
3097 * definition. 4bit tag is placed at 28 bit!
3099 if ((res >> 28) == ALC880_HP_EVENT)
3100 alc880_medion_rim_automute(codec);
3103 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3105 struct alc_spec *spec = codec->spec;
3107 spec->autocfg.hp_pins[0] = 0x14;
3108 spec->autocfg.speaker_pins[0] = 0x1b;
3109 alc880_medion_rim_automute(codec);
3112 #ifdef CONFIG_SND_HDA_POWER_SAVE
3113 static struct hda_amp_list alc880_loopbacks[] = {
3114 { 0x0b, HDA_INPUT, 0 },
3115 { 0x0b, HDA_INPUT, 1 },
3116 { 0x0b, HDA_INPUT, 2 },
3117 { 0x0b, HDA_INPUT, 3 },
3118 { 0x0b, HDA_INPUT, 4 },
3122 static struct hda_amp_list alc880_lg_loopbacks[] = {
3123 { 0x0b, HDA_INPUT, 1 },
3124 { 0x0b, HDA_INPUT, 6 },
3125 { 0x0b, HDA_INPUT, 7 },
3134 static int alc_init(struct hda_codec *codec)
3136 struct alc_spec *spec = codec->spec;
3140 alc_auto_init_amp(codec, spec->init_amp);
3142 for (i = 0; i < spec->num_init_verbs; i++)
3143 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3145 if (spec->init_hook)
3146 spec->init_hook(codec);
3151 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3153 struct alc_spec *spec = codec->spec;
3155 if (spec->unsol_event)
3156 spec->unsol_event(codec, res);
3159 #ifdef CONFIG_SND_HDA_POWER_SAVE
3160 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3162 struct alc_spec *spec = codec->spec;
3163 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3168 * Analog playback callbacks
3170 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3171 struct hda_codec *codec,
3172 struct snd_pcm_substream *substream)
3174 struct alc_spec *spec = codec->spec;
3175 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3179 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3180 struct hda_codec *codec,
3181 unsigned int stream_tag,
3182 unsigned int format,
3183 struct snd_pcm_substream *substream)
3185 struct alc_spec *spec = codec->spec;
3186 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3187 stream_tag, format, substream);
3190 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3191 struct hda_codec *codec,
3192 struct snd_pcm_substream *substream)
3194 struct alc_spec *spec = codec->spec;
3195 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3201 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3202 struct hda_codec *codec,
3203 struct snd_pcm_substream *substream)
3205 struct alc_spec *spec = codec->spec;
3206 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3209 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3210 struct hda_codec *codec,
3211 unsigned int stream_tag,
3212 unsigned int format,
3213 struct snd_pcm_substream *substream)
3215 struct alc_spec *spec = codec->spec;
3216 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3217 stream_tag, format, substream);
3220 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3221 struct hda_codec *codec,
3222 struct snd_pcm_substream *substream)
3224 struct alc_spec *spec = codec->spec;
3225 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3228 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3229 struct hda_codec *codec,
3230 struct snd_pcm_substream *substream)
3232 struct alc_spec *spec = codec->spec;
3233 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3239 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3240 struct hda_codec *codec,
3241 unsigned int stream_tag,
3242 unsigned int format,
3243 struct snd_pcm_substream *substream)
3245 struct alc_spec *spec = codec->spec;
3247 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3248 stream_tag, 0, format);
3252 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3253 struct hda_codec *codec,
3254 struct snd_pcm_substream *substream)
3256 struct alc_spec *spec = codec->spec;
3258 snd_hda_codec_cleanup_stream(codec,
3259 spec->adc_nids[substream->number + 1]);
3266 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3270 /* NID is set in alc_build_pcms */
3272 .open = alc880_playback_pcm_open,
3273 .prepare = alc880_playback_pcm_prepare,
3274 .cleanup = alc880_playback_pcm_cleanup
3278 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3282 /* NID is set in alc_build_pcms */
3285 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3289 /* NID is set in alc_build_pcms */
3292 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3293 .substreams = 2, /* can be overridden */
3296 /* NID is set in alc_build_pcms */
3298 .prepare = alc880_alt_capture_pcm_prepare,
3299 .cleanup = alc880_alt_capture_pcm_cleanup
3303 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3307 /* NID is set in alc_build_pcms */
3309 .open = alc880_dig_playback_pcm_open,
3310 .close = alc880_dig_playback_pcm_close,
3311 .prepare = alc880_dig_playback_pcm_prepare,
3312 .cleanup = alc880_dig_playback_pcm_cleanup
3316 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3320 /* NID is set in alc_build_pcms */
3323 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3324 static struct hda_pcm_stream alc_pcm_null_stream = {
3330 static int alc_build_pcms(struct hda_codec *codec)
3332 struct alc_spec *spec = codec->spec;
3333 struct hda_pcm *info = spec->pcm_rec;
3336 codec->num_pcms = 1;
3337 codec->pcm_info = info;
3339 if (spec->no_analog)
3342 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3343 "%s Analog", codec->chip_name);
3344 info->name = spec->stream_name_analog;
3346 if (spec->stream_analog_playback) {
3347 if (snd_BUG_ON(!spec->multiout.dac_nids))
3349 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3350 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3352 if (spec->stream_analog_capture) {
3353 if (snd_BUG_ON(!spec->adc_nids))
3355 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3356 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3359 if (spec->channel_mode) {
3360 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3361 for (i = 0; i < spec->num_channel_mode; i++) {
3362 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3363 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3369 /* SPDIF for stream index #1 */
3370 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3371 snprintf(spec->stream_name_digital,
3372 sizeof(spec->stream_name_digital),
3373 "%s Digital", codec->chip_name);
3374 codec->num_pcms = 2;
3375 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3376 info = spec->pcm_rec + 1;
3377 info->name = spec->stream_name_digital;
3378 if (spec->dig_out_type)
3379 info->pcm_type = spec->dig_out_type;
3381 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3382 if (spec->multiout.dig_out_nid &&
3383 spec->stream_digital_playback) {
3384 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3385 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3387 if (spec->dig_in_nid &&
3388 spec->stream_digital_capture) {
3389 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3390 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3392 /* FIXME: do we need this for all Realtek codec models? */
3393 codec->spdif_status_reset = 1;
3396 if (spec->no_analog)
3399 /* If the use of more than one ADC is requested for the current
3400 * model, configure a second analog capture-only PCM.
3402 /* Additional Analaog capture for index #2 */
3403 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3404 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3405 codec->num_pcms = 3;
3406 info = spec->pcm_rec + 2;
3407 info->name = spec->stream_name_analog;
3408 if (spec->alt_dac_nid) {
3409 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3410 *spec->stream_analog_alt_playback;
3411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3414 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3415 alc_pcm_null_stream;
3416 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3418 if (spec->num_adc_nids > 1) {
3419 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3420 *spec->stream_analog_alt_capture;
3421 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3423 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3424 spec->num_adc_nids - 1;
3426 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3427 alc_pcm_null_stream;
3428 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3435 static void alc_free_kctls(struct hda_codec *codec)
3437 struct alc_spec *spec = codec->spec;
3439 if (spec->kctls.list) {
3440 struct snd_kcontrol_new *kctl = spec->kctls.list;
3442 for (i = 0; i < spec->kctls.used; i++)
3443 kfree(kctl[i].name);
3445 snd_array_free(&spec->kctls);
3448 static void alc_free(struct hda_codec *codec)
3450 struct alc_spec *spec = codec->spec;
3455 alc_free_kctls(codec);
3457 snd_hda_detach_beep_device(codec);
3460 #ifdef SND_HDA_NEEDS_RESUME
3461 static int alc_resume(struct hda_codec *codec)
3463 codec->patch_ops.init(codec);
3464 snd_hda_codec_resume_amp(codec);
3465 snd_hda_codec_resume_cache(codec);
3472 static struct hda_codec_ops alc_patch_ops = {
3473 .build_controls = alc_build_controls,
3474 .build_pcms = alc_build_pcms,
3477 .unsol_event = alc_unsol_event,
3478 #ifdef SND_HDA_NEEDS_RESUME
3479 .resume = alc_resume,
3481 #ifdef CONFIG_SND_HDA_POWER_SAVE
3482 .check_power_status = alc_check_power_status,
3488 * Test configuration for debugging
3490 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3493 #ifdef CONFIG_SND_DEBUG
3494 static hda_nid_t alc880_test_dac_nids[4] = {
3495 0x02, 0x03, 0x04, 0x05
3498 static struct hda_input_mux alc880_test_capture_source = {
3507 { "Surround", 0x6 },
3511 static struct hda_channel_mode alc880_test_modes[4] = {
3518 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3519 struct snd_ctl_elem_info *uinfo)
3521 static char *texts[] = {
3522 "N/A", "Line Out", "HP Out",
3523 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3525 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3527 uinfo->value.enumerated.items = 8;
3528 if (uinfo->value.enumerated.item >= 8)
3529 uinfo->value.enumerated.item = 7;
3530 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3534 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3535 struct snd_ctl_elem_value *ucontrol)
3537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3538 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3539 unsigned int pin_ctl, item = 0;
3541 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3542 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3543 if (pin_ctl & AC_PINCTL_OUT_EN) {
3544 if (pin_ctl & AC_PINCTL_HP_EN)
3548 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3549 switch (pin_ctl & AC_PINCTL_VREFEN) {
3550 case AC_PINCTL_VREF_HIZ: item = 3; break;
3551 case AC_PINCTL_VREF_50: item = 4; break;
3552 case AC_PINCTL_VREF_GRD: item = 5; break;
3553 case AC_PINCTL_VREF_80: item = 6; break;
3554 case AC_PINCTL_VREF_100: item = 7; break;
3557 ucontrol->value.enumerated.item[0] = item;
3561 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3562 struct snd_ctl_elem_value *ucontrol)
3564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3565 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3566 static unsigned int ctls[] = {
3567 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3568 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3569 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3570 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3571 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3572 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3574 unsigned int old_ctl, new_ctl;
3576 old_ctl = snd_hda_codec_read(codec, nid, 0,
3577 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3578 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3579 if (old_ctl != new_ctl) {
3581 snd_hda_codec_write_cache(codec, nid, 0,
3582 AC_VERB_SET_PIN_WIDGET_CONTROL,
3584 val = ucontrol->value.enumerated.item[0] >= 3 ?
3586 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3593 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3594 struct snd_ctl_elem_info *uinfo)
3596 static char *texts[] = {
3597 "Front", "Surround", "CLFE", "Side"
3599 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3601 uinfo->value.enumerated.items = 4;
3602 if (uinfo->value.enumerated.item >= 4)
3603 uinfo->value.enumerated.item = 3;
3604 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3608 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3609 struct snd_ctl_elem_value *ucontrol)
3611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3612 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3615 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3616 ucontrol->value.enumerated.item[0] = sel & 3;
3620 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3621 struct snd_ctl_elem_value *ucontrol)
3623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3624 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3627 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3628 if (ucontrol->value.enumerated.item[0] != sel) {
3629 sel = ucontrol->value.enumerated.item[0] & 3;
3630 snd_hda_codec_write_cache(codec, nid, 0,
3631 AC_VERB_SET_CONNECT_SEL, sel);
3637 #define PIN_CTL_TEST(xname,nid) { \
3638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3640 .info = alc_test_pin_ctl_info, \
3641 .get = alc_test_pin_ctl_get, \
3642 .put = alc_test_pin_ctl_put, \
3643 .private_value = nid \
3646 #define PIN_SRC_TEST(xname,nid) { \
3647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3649 .info = alc_test_pin_src_info, \
3650 .get = alc_test_pin_src_get, \
3651 .put = alc_test_pin_src_put, \
3652 .private_value = nid \
3655 static struct snd_kcontrol_new alc880_test_mixer[] = {
3656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3658 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3659 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3660 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3661 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3662 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3663 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3664 PIN_CTL_TEST("Front Pin Mode", 0x14),
3665 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3666 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3667 PIN_CTL_TEST("Side Pin Mode", 0x17),
3668 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3669 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3670 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3671 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3672 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3673 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3674 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3675 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3676 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3677 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3678 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3679 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3680 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3681 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3682 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3683 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3684 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3685 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3687 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3688 .name = "Channel Mode",
3689 .info = alc_ch_mode_info,
3690 .get = alc_ch_mode_get,
3691 .put = alc_ch_mode_put,
3696 static struct hda_verb alc880_test_init_verbs[] = {
3697 /* Unmute inputs of 0x0c - 0x0f */
3698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3706 /* Vol output for 0x0c-0x0f */
3707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3710 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3711 /* Set output pins 0x14-0x17 */
3712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3713 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3714 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3715 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3716 /* Unmute output pins 0x14-0x17 */
3717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3720 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3721 /* Set input pins 0x18-0x1c */
3722 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3723 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3724 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3726 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3727 /* Mute input pins 0x18-0x1b */
3728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3731 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3734 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3735 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3737 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3739 /* Analog input/passthru */
3740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3743 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3744 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3752 static const char *alc880_models[ALC880_MODEL_LAST] = {
3753 [ALC880_3ST] = "3stack",
3754 [ALC880_TCL_S700] = "tcl",
3755 [ALC880_3ST_DIG] = "3stack-digout",
3756 [ALC880_CLEVO] = "clevo",
3757 [ALC880_5ST] = "5stack",
3758 [ALC880_5ST_DIG] = "5stack-digout",
3759 [ALC880_W810] = "w810",
3760 [ALC880_Z71V] = "z71v",
3761 [ALC880_6ST] = "6stack",
3762 [ALC880_6ST_DIG] = "6stack-digout",
3763 [ALC880_ASUS] = "asus",
3764 [ALC880_ASUS_W1V] = "asus-w1v",
3765 [ALC880_ASUS_DIG] = "asus-dig",
3766 [ALC880_ASUS_DIG2] = "asus-dig2",
3767 [ALC880_UNIWILL_DIG] = "uniwill",
3768 [ALC880_UNIWILL_P53] = "uniwill-p53",
3769 [ALC880_FUJITSU] = "fujitsu",
3770 [ALC880_F1734] = "F1734",
3772 [ALC880_LG_LW] = "lg-lw",
3773 [ALC880_MEDION_RIM] = "medion",
3774 #ifdef CONFIG_SND_DEBUG
3775 [ALC880_TEST] = "test",
3777 [ALC880_AUTO] = "auto",
3780 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3781 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3782 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3783 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3784 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3785 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3786 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3787 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3788 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3789 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3790 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3791 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3792 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3793 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3794 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3795 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3796 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3797 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3798 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3799 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3800 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3801 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3802 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3803 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3804 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3805 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3806 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3807 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3808 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3809 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3810 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3811 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3812 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3813 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3814 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3815 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3816 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3817 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3818 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3819 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3820 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3821 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3822 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3823 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3824 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3825 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3826 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3827 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3828 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3829 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3830 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3831 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3832 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3833 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3834 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3835 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3836 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3837 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3838 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3839 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3840 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3841 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3842 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3843 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3844 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3845 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3846 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3847 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3848 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3850 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3851 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3852 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3857 * ALC880 codec presets
3859 static struct alc_config_preset alc880_presets[] = {
3861 .mixers = { alc880_three_stack_mixer },
3862 .init_verbs = { alc880_volume_init_verbs,
3863 alc880_pin_3stack_init_verbs },
3864 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3865 .dac_nids = alc880_dac_nids,
3866 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3867 .channel_mode = alc880_threestack_modes,
3869 .input_mux = &alc880_capture_source,
3871 [ALC880_3ST_DIG] = {
3872 .mixers = { alc880_three_stack_mixer },
3873 .init_verbs = { alc880_volume_init_verbs,
3874 alc880_pin_3stack_init_verbs },
3875 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3876 .dac_nids = alc880_dac_nids,
3877 .dig_out_nid = ALC880_DIGOUT_NID,
3878 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3879 .channel_mode = alc880_threestack_modes,
3881 .input_mux = &alc880_capture_source,
3883 [ALC880_TCL_S700] = {
3884 .mixers = { alc880_tcl_s700_mixer },
3885 .init_verbs = { alc880_volume_init_verbs,
3886 alc880_pin_tcl_S700_init_verbs,
3887 alc880_gpio2_init_verbs },
3888 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3889 .dac_nids = alc880_dac_nids,
3890 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3891 .num_adc_nids = 1, /* single ADC */
3893 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3894 .channel_mode = alc880_2_jack_modes,
3895 .input_mux = &alc880_capture_source,
3898 .mixers = { alc880_three_stack_mixer,
3899 alc880_five_stack_mixer},
3900 .init_verbs = { alc880_volume_init_verbs,
3901 alc880_pin_5stack_init_verbs },
3902 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3903 .dac_nids = alc880_dac_nids,
3904 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3905 .channel_mode = alc880_fivestack_modes,
3906 .input_mux = &alc880_capture_source,
3908 [ALC880_5ST_DIG] = {
3909 .mixers = { alc880_three_stack_mixer,
3910 alc880_five_stack_mixer },
3911 .init_verbs = { alc880_volume_init_verbs,
3912 alc880_pin_5stack_init_verbs },
3913 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3914 .dac_nids = alc880_dac_nids,
3915 .dig_out_nid = ALC880_DIGOUT_NID,
3916 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3917 .channel_mode = alc880_fivestack_modes,
3918 .input_mux = &alc880_capture_source,
3921 .mixers = { alc880_six_stack_mixer },
3922 .init_verbs = { alc880_volume_init_verbs,
3923 alc880_pin_6stack_init_verbs },
3924 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3925 .dac_nids = alc880_6st_dac_nids,
3926 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3927 .channel_mode = alc880_sixstack_modes,
3928 .input_mux = &alc880_6stack_capture_source,
3930 [ALC880_6ST_DIG] = {
3931 .mixers = { alc880_six_stack_mixer },
3932 .init_verbs = { alc880_volume_init_verbs,
3933 alc880_pin_6stack_init_verbs },
3934 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3935 .dac_nids = alc880_6st_dac_nids,
3936 .dig_out_nid = ALC880_DIGOUT_NID,
3937 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3938 .channel_mode = alc880_sixstack_modes,
3939 .input_mux = &alc880_6stack_capture_source,
3942 .mixers = { alc880_w810_base_mixer },
3943 .init_verbs = { alc880_volume_init_verbs,
3944 alc880_pin_w810_init_verbs,
3945 alc880_gpio2_init_verbs },
3946 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3947 .dac_nids = alc880_w810_dac_nids,
3948 .dig_out_nid = ALC880_DIGOUT_NID,
3949 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3950 .channel_mode = alc880_w810_modes,
3951 .input_mux = &alc880_capture_source,
3954 .mixers = { alc880_z71v_mixer },
3955 .init_verbs = { alc880_volume_init_verbs,
3956 alc880_pin_z71v_init_verbs },
3957 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3958 .dac_nids = alc880_z71v_dac_nids,
3959 .dig_out_nid = ALC880_DIGOUT_NID,
3961 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3962 .channel_mode = alc880_2_jack_modes,
3963 .input_mux = &alc880_capture_source,
3966 .mixers = { alc880_f1734_mixer },
3967 .init_verbs = { alc880_volume_init_verbs,
3968 alc880_pin_f1734_init_verbs },
3969 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3970 .dac_nids = alc880_f1734_dac_nids,
3972 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3973 .channel_mode = alc880_2_jack_modes,
3974 .input_mux = &alc880_f1734_capture_source,
3975 .unsol_event = alc880_uniwill_p53_unsol_event,
3976 .init_hook = alc880_uniwill_p53_init_hook,
3979 .mixers = { alc880_asus_mixer },
3980 .init_verbs = { alc880_volume_init_verbs,
3981 alc880_pin_asus_init_verbs,
3982 alc880_gpio1_init_verbs },
3983 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3984 .dac_nids = alc880_asus_dac_nids,
3985 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3986 .channel_mode = alc880_asus_modes,
3988 .input_mux = &alc880_capture_source,
3990 [ALC880_ASUS_DIG] = {
3991 .mixers = { alc880_asus_mixer },
3992 .init_verbs = { alc880_volume_init_verbs,
3993 alc880_pin_asus_init_verbs,
3994 alc880_gpio1_init_verbs },
3995 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3996 .dac_nids = alc880_asus_dac_nids,
3997 .dig_out_nid = ALC880_DIGOUT_NID,
3998 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3999 .channel_mode = alc880_asus_modes,
4001 .input_mux = &alc880_capture_source,
4003 [ALC880_ASUS_DIG2] = {
4004 .mixers = { alc880_asus_mixer },
4005 .init_verbs = { alc880_volume_init_verbs,
4006 alc880_pin_asus_init_verbs,
4007 alc880_gpio2_init_verbs }, /* use GPIO2 */
4008 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4009 .dac_nids = alc880_asus_dac_nids,
4010 .dig_out_nid = ALC880_DIGOUT_NID,
4011 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4012 .channel_mode = alc880_asus_modes,
4014 .input_mux = &alc880_capture_source,
4016 [ALC880_ASUS_W1V] = {
4017 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4018 .init_verbs = { alc880_volume_init_verbs,
4019 alc880_pin_asus_init_verbs,
4020 alc880_gpio1_init_verbs },
4021 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4022 .dac_nids = alc880_asus_dac_nids,
4023 .dig_out_nid = ALC880_DIGOUT_NID,
4024 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4025 .channel_mode = alc880_asus_modes,
4027 .input_mux = &alc880_capture_source,
4029 [ALC880_UNIWILL_DIG] = {
4030 .mixers = { alc880_asus_mixer },
4031 .init_verbs = { alc880_volume_init_verbs,
4032 alc880_pin_asus_init_verbs },
4033 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4034 .dac_nids = alc880_asus_dac_nids,
4035 .dig_out_nid = ALC880_DIGOUT_NID,
4036 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4037 .channel_mode = alc880_asus_modes,
4039 .input_mux = &alc880_capture_source,
4041 [ALC880_UNIWILL] = {
4042 .mixers = { alc880_uniwill_mixer },
4043 .init_verbs = { alc880_volume_init_verbs,
4044 alc880_uniwill_init_verbs },
4045 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4046 .dac_nids = alc880_asus_dac_nids,
4047 .dig_out_nid = ALC880_DIGOUT_NID,
4048 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4049 .channel_mode = alc880_threestack_modes,
4051 .input_mux = &alc880_capture_source,
4052 .unsol_event = alc880_uniwill_unsol_event,
4053 .init_hook = alc880_uniwill_init_hook,
4055 [ALC880_UNIWILL_P53] = {
4056 .mixers = { alc880_uniwill_p53_mixer },
4057 .init_verbs = { alc880_volume_init_verbs,
4058 alc880_uniwill_p53_init_verbs },
4059 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4060 .dac_nids = alc880_asus_dac_nids,
4061 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4062 .channel_mode = alc880_threestack_modes,
4063 .input_mux = &alc880_capture_source,
4064 .unsol_event = alc880_uniwill_p53_unsol_event,
4065 .init_hook = alc880_uniwill_p53_init_hook,
4067 [ALC880_FUJITSU] = {
4068 .mixers = { alc880_fujitsu_mixer },
4069 .init_verbs = { alc880_volume_init_verbs,
4070 alc880_uniwill_p53_init_verbs,
4071 alc880_beep_init_verbs },
4072 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4073 .dac_nids = alc880_dac_nids,
4074 .dig_out_nid = ALC880_DIGOUT_NID,
4075 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4076 .channel_mode = alc880_2_jack_modes,
4077 .input_mux = &alc880_capture_source,
4078 .unsol_event = alc880_uniwill_p53_unsol_event,
4079 .init_hook = alc880_uniwill_p53_init_hook,
4082 .mixers = { alc880_three_stack_mixer },
4083 .init_verbs = { alc880_volume_init_verbs,
4084 alc880_pin_clevo_init_verbs },
4085 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4086 .dac_nids = alc880_dac_nids,
4088 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4089 .channel_mode = alc880_threestack_modes,
4091 .input_mux = &alc880_capture_source,
4094 .mixers = { alc880_lg_mixer },
4095 .init_verbs = { alc880_volume_init_verbs,
4096 alc880_lg_init_verbs },
4097 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4098 .dac_nids = alc880_lg_dac_nids,
4099 .dig_out_nid = ALC880_DIGOUT_NID,
4100 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4101 .channel_mode = alc880_lg_ch_modes,
4103 .input_mux = &alc880_lg_capture_source,
4104 .unsol_event = alc_automute_amp_unsol_event,
4105 .init_hook = alc880_lg_init_hook,
4106 #ifdef CONFIG_SND_HDA_POWER_SAVE
4107 .loopbacks = alc880_lg_loopbacks,
4111 .mixers = { alc880_lg_lw_mixer },
4112 .init_verbs = { alc880_volume_init_verbs,
4113 alc880_lg_lw_init_verbs },
4114 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4115 .dac_nids = alc880_dac_nids,
4116 .dig_out_nid = ALC880_DIGOUT_NID,
4117 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4118 .channel_mode = alc880_lg_lw_modes,
4119 .input_mux = &alc880_lg_lw_capture_source,
4120 .unsol_event = alc_automute_amp_unsol_event,
4121 .init_hook = alc880_lg_lw_init_hook,
4123 [ALC880_MEDION_RIM] = {
4124 .mixers = { alc880_medion_rim_mixer },
4125 .init_verbs = { alc880_volume_init_verbs,
4126 alc880_medion_rim_init_verbs,
4127 alc_gpio2_init_verbs },
4128 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4129 .dac_nids = alc880_dac_nids,
4130 .dig_out_nid = ALC880_DIGOUT_NID,
4131 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4132 .channel_mode = alc880_2_jack_modes,
4133 .input_mux = &alc880_medion_rim_capture_source,
4134 .unsol_event = alc880_medion_rim_unsol_event,
4135 .init_hook = alc880_medion_rim_init_hook,
4137 #ifdef CONFIG_SND_DEBUG
4139 .mixers = { alc880_test_mixer },
4140 .init_verbs = { alc880_test_init_verbs },
4141 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4142 .dac_nids = alc880_test_dac_nids,
4143 .dig_out_nid = ALC880_DIGOUT_NID,
4144 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4145 .channel_mode = alc880_test_modes,
4146 .input_mux = &alc880_test_capture_source,
4152 * Automatic parse of I/O pins from the BIOS configuration
4157 ALC_CTL_WIDGET_MUTE,
4160 static struct snd_kcontrol_new alc880_control_templates[] = {
4161 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4162 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4163 HDA_BIND_MUTE(NULL, 0, 0, 0),
4166 /* add dynamic controls */
4167 static int add_control(struct alc_spec *spec, int type, const char *name,
4170 struct snd_kcontrol_new *knew;
4172 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4173 knew = snd_array_new(&spec->kctls);
4176 *knew = alc880_control_templates[type];
4177 knew->name = kstrdup(name, GFP_KERNEL);
4180 knew->private_value = val;
4184 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4185 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4186 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4187 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4188 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4189 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4190 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4191 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4192 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4193 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4194 #define ALC880_PIN_CD_NID 0x1c
4196 /* fill in the dac_nids table from the parsed pin configuration */
4197 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4198 const struct auto_pin_cfg *cfg)
4204 memset(assigned, 0, sizeof(assigned));
4205 spec->multiout.dac_nids = spec->private_dac_nids;
4207 /* check the pins hardwired to audio widget */
4208 for (i = 0; i < cfg->line_outs; i++) {
4209 nid = cfg->line_out_pins[i];
4210 if (alc880_is_fixed_pin(nid)) {
4211 int idx = alc880_fixed_pin_idx(nid);
4212 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4216 /* left pins can be connect to any audio widget */
4217 for (i = 0; i < cfg->line_outs; i++) {
4218 nid = cfg->line_out_pins[i];
4219 if (alc880_is_fixed_pin(nid))
4221 /* search for an empty channel */
4222 for (j = 0; j < cfg->line_outs; j++) {
4224 spec->multiout.dac_nids[i] =
4225 alc880_idx_to_dac(j);
4231 spec->multiout.num_dacs = cfg->line_outs;
4235 /* add playback controls from the parsed DAC table */
4236 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4237 const struct auto_pin_cfg *cfg)
4240 static const char *chname[4] = {
4241 "Front", "Surround", NULL /*CLFE*/, "Side"
4246 for (i = 0; i < cfg->line_outs; i++) {
4247 if (!spec->multiout.dac_nids[i])
4249 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4252 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4253 "Center Playback Volume",
4254 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4258 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4259 "LFE Playback Volume",
4260 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4264 err = add_control(spec, ALC_CTL_BIND_MUTE,
4265 "Center Playback Switch",
4266 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4270 err = add_control(spec, ALC_CTL_BIND_MUTE,
4271 "LFE Playback Switch",
4272 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4277 sprintf(name, "%s Playback Volume", chname[i]);
4278 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4279 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4283 sprintf(name, "%s Playback Switch", chname[i]);
4284 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4285 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4294 /* add playback controls for speaker and HP outputs */
4295 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4305 if (alc880_is_fixed_pin(pin)) {
4306 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4307 /* specify the DAC as the extra output */
4308 if (!spec->multiout.hp_nid)
4309 spec->multiout.hp_nid = nid;
4311 spec->multiout.extra_out_nid[0] = nid;
4312 /* control HP volume/switch on the output mixer amp */
4313 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4314 sprintf(name, "%s Playback Volume", pfx);
4315 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4316 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4319 sprintf(name, "%s Playback Switch", pfx);
4320 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4321 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4324 } else if (alc880_is_multi_pin(pin)) {
4325 /* set manual connection */
4326 /* we have only a switch on HP-out PIN */
4327 sprintf(name, "%s Playback Switch", pfx);
4328 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4329 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4336 /* create input playback/capture controls for the given pin */
4337 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4338 const char *ctlname,
4339 int idx, hda_nid_t mix_nid)
4344 sprintf(name, "%s Playback Volume", ctlname);
4345 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4346 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4349 sprintf(name, "%s Playback Switch", ctlname);
4350 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4351 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4357 /* create playback/capture controls for input pins */
4358 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4359 const struct auto_pin_cfg *cfg)
4361 struct hda_input_mux *imux = &spec->private_imux[0];
4364 for (i = 0; i < AUTO_PIN_LAST; i++) {
4365 if (alc880_is_input_pin(cfg->input_pins[i])) {
4366 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4367 err = new_analog_input(spec, cfg->input_pins[i],
4368 auto_pin_cfg_labels[i],
4372 imux->items[imux->num_items].label =
4373 auto_pin_cfg_labels[i];
4374 imux->items[imux->num_items].index =
4375 alc880_input_pin_idx(cfg->input_pins[i]);
4382 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4383 unsigned int pin_type)
4385 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4388 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4392 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4393 hda_nid_t nid, int pin_type,
4396 alc_set_pin_output(codec, nid, pin_type);
4397 /* need the manual connection? */
4398 if (alc880_is_multi_pin(nid)) {
4399 struct alc_spec *spec = codec->spec;
4400 int idx = alc880_multi_pin_idx(nid);
4401 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4402 AC_VERB_SET_CONNECT_SEL,
4403 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4407 static int get_pin_type(int line_out_type)
4409 if (line_out_type == AUTO_PIN_HP_OUT)
4415 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4417 struct alc_spec *spec = codec->spec;
4420 for (i = 0; i < spec->autocfg.line_outs; i++) {
4421 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4422 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4423 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4427 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4429 struct alc_spec *spec = codec->spec;
4432 pin = spec->autocfg.speaker_pins[0];
4433 if (pin) /* connect to front */
4434 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4435 pin = spec->autocfg.hp_pins[0];
4436 if (pin) /* connect to front */
4437 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4440 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4442 struct alc_spec *spec = codec->spec;
4445 for (i = 0; i < AUTO_PIN_LAST; i++) {
4446 hda_nid_t nid = spec->autocfg.input_pins[i];
4447 if (alc880_is_input_pin(nid)) {
4448 alc_set_input_pin(codec, nid, i);
4449 if (nid != ALC880_PIN_CD_NID &&
4450 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4451 snd_hda_codec_write(codec, nid, 0,
4452 AC_VERB_SET_AMP_GAIN_MUTE,
4458 /* parse the BIOS configuration and set up the alc_spec */
4459 /* return 1 if successful, 0 if the proper config is not found,
4460 * or a negative error code
4462 static int alc880_parse_auto_config(struct hda_codec *codec)
4464 struct alc_spec *spec = codec->spec;
4466 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4468 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4472 if (!spec->autocfg.line_outs)
4473 return 0; /* can't find valid BIOS pin config */
4475 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4478 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4481 err = alc880_auto_create_extra_out(spec,
4482 spec->autocfg.speaker_pins[0],
4486 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4490 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4494 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4496 /* check multiple SPDIF-out (for recent codecs) */
4497 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4499 err = snd_hda_get_connections(codec,
4500 spec->autocfg.dig_out_pins[i],
4504 if (dig_nid > 0x7f) {
4505 printk(KERN_ERR "alc880_auto: invalid dig_nid "
4506 "connection 0x%x for NID 0x%x\n", dig_nid,
4507 spec->autocfg.dig_out_pins[i]);
4511 spec->multiout.dig_out_nid = dig_nid;
4513 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4514 spec->slave_dig_outs[i - 1] = dig_nid;
4515 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4519 if (spec->autocfg.dig_in_pin)
4520 spec->dig_in_nid = ALC880_DIGIN_NID;
4522 if (spec->kctls.list)
4523 add_mixer(spec, spec->kctls.list);
4525 add_verb(spec, alc880_volume_init_verbs);
4527 spec->num_mux_defs = 1;
4528 spec->input_mux = &spec->private_imux[0];
4530 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4535 /* additional initialization for auto-configuration model */
4536 static void alc880_auto_init(struct hda_codec *codec)
4538 struct alc_spec *spec = codec->spec;
4539 alc880_auto_init_multi_out(codec);
4540 alc880_auto_init_extra_out(codec);
4541 alc880_auto_init_analog_input(codec);
4542 if (spec->unsol_event)
4543 alc_inithook(codec);
4546 static void set_capture_mixer(struct alc_spec *spec)
4548 static struct snd_kcontrol_new *caps[2][3] = {
4549 { alc_capture_mixer_nosrc1,
4550 alc_capture_mixer_nosrc2,
4551 alc_capture_mixer_nosrc3 },
4552 { alc_capture_mixer1,
4554 alc_capture_mixer3 },
4556 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4558 if (spec->input_mux && spec->input_mux->num_items > 1)
4562 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4566 #define set_beep_amp(spec, nid, idx, dir) \
4567 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4570 * OK, here we have finally the patch for ALC880
4573 static int patch_alc880(struct hda_codec *codec)
4575 struct alc_spec *spec;
4579 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4585 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4588 if (board_config < 0) {
4589 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4590 "trying auto-probe from BIOS...\n", codec->chip_name);
4591 board_config = ALC880_AUTO;
4594 if (board_config == ALC880_AUTO) {
4595 /* automatic parse from the BIOS config */
4596 err = alc880_parse_auto_config(codec);
4602 "hda_codec: Cannot set up configuration "
4603 "from BIOS. Using 3-stack mode...\n");
4604 board_config = ALC880_3ST;
4608 err = snd_hda_attach_beep_device(codec, 0x1);
4614 if (board_config != ALC880_AUTO)
4615 setup_preset(spec, &alc880_presets[board_config]);
4617 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4618 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4619 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4621 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4622 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4624 if (!spec->adc_nids && spec->input_mux) {
4625 /* check whether NID 0x07 is valid */
4626 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4628 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4629 if (wcap != AC_WID_AUD_IN) {
4630 spec->adc_nids = alc880_adc_nids_alt;
4631 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4633 spec->adc_nids = alc880_adc_nids;
4634 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4637 set_capture_mixer(spec);
4638 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4640 spec->vmaster_nid = 0x0c;
4642 codec->patch_ops = alc_patch_ops;
4643 if (board_config == ALC880_AUTO)
4644 spec->init_hook = alc880_auto_init;
4645 #ifdef CONFIG_SND_HDA_POWER_SAVE
4646 if (!spec->loopback.amplist)
4647 spec->loopback.amplist = alc880_loopbacks;
4649 codec->proc_widget_hook = print_realtek_coef;
4659 static hda_nid_t alc260_dac_nids[1] = {
4664 static hda_nid_t alc260_adc_nids[1] = {
4669 static hda_nid_t alc260_adc_nids_alt[1] = {
4674 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4675 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4677 static hda_nid_t alc260_dual_adc_nids[2] = {
4682 #define ALC260_DIGOUT_NID 0x03
4683 #define ALC260_DIGIN_NID 0x06
4685 static struct hda_input_mux alc260_capture_source = {
4689 { "Front Mic", 0x1 },
4695 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4696 * headphone jack and the internal CD lines since these are the only pins at
4697 * which audio can appear. For flexibility, also allow the option of
4698 * recording the mixer output on the second ADC (ADC0 doesn't have a
4699 * connection to the mixer output).
4701 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4705 { "Mic/Line", 0x0 },
4707 { "Headphone", 0x2 },
4713 { "Mic/Line", 0x0 },
4715 { "Headphone", 0x2 },
4722 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4723 * the Fujitsu S702x, but jacks are marked differently.
4725 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4732 { "Headphone", 0x5 },
4741 { "Headphone", 0x6 },
4747 /* Maxdata Favorit 100XS */
4748 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4752 { "Line/Mic", 0x0 },
4759 { "Line/Mic", 0x0 },
4767 * This is just place-holder, so there's something for alc_build_pcms to look
4768 * at when it calculates the maximum number of channels. ALC260 has no mixer
4769 * element which allows changing the channel mode, so the verb list is
4772 static struct hda_channel_mode alc260_modes[1] = {
4777 /* Mixer combinations
4779 * basic: base_output + input + pc_beep + capture
4780 * HP: base_output + input + capture_alt
4781 * HP_3013: hp_3013 + input + capture
4782 * fujitsu: fujitsu + capture
4783 * acer: acer + capture
4786 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4787 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4788 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4789 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4790 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4791 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4792 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4796 static struct snd_kcontrol_new alc260_input_mixer[] = {
4797 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4798 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4799 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4800 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4801 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4802 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4803 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4804 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4808 /* update HP, line and mono out pins according to the master switch */
4809 static void alc260_hp_master_update(struct hda_codec *codec,
4810 hda_nid_t hp, hda_nid_t line,
4813 struct alc_spec *spec = codec->spec;
4814 unsigned int val = spec->master_sw ? PIN_HP : 0;
4815 /* change HP and line-out pins */
4816 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4818 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4820 /* mono (speaker) depending on the HP jack sense */
4821 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4822 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4826 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4827 struct snd_ctl_elem_value *ucontrol)
4829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4830 struct alc_spec *spec = codec->spec;
4831 *ucontrol->value.integer.value = spec->master_sw;
4835 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4836 struct snd_ctl_elem_value *ucontrol)
4838 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4839 struct alc_spec *spec = codec->spec;
4840 int val = !!*ucontrol->value.integer.value;
4841 hda_nid_t hp, line, mono;
4843 if (val == spec->master_sw)
4845 spec->master_sw = val;
4846 hp = (kcontrol->private_value >> 16) & 0xff;
4847 line = (kcontrol->private_value >> 8) & 0xff;
4848 mono = kcontrol->private_value & 0xff;
4849 alc260_hp_master_update(codec, hp, line, mono);
4853 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4856 .name = "Master Playback Switch",
4857 .info = snd_ctl_boolean_mono_info,
4858 .get = alc260_hp_master_sw_get,
4859 .put = alc260_hp_master_sw_put,
4860 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4862 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4863 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4864 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4865 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4866 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4868 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4872 static struct hda_verb alc260_hp_unsol_verbs[] = {
4873 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4877 static void alc260_hp_automute(struct hda_codec *codec)
4879 struct alc_spec *spec = codec->spec;
4880 unsigned int present;
4882 present = snd_hda_codec_read(codec, 0x10, 0,
4883 AC_VERB_GET_PIN_SENSE, 0);
4884 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4885 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4888 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4890 if ((res >> 26) == ALC880_HP_EVENT)
4891 alc260_hp_automute(codec);
4894 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4897 .name = "Master Playback Switch",
4898 .info = snd_ctl_boolean_mono_info,
4899 .get = alc260_hp_master_sw_get,
4900 .put = alc260_hp_master_sw_put,
4901 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4903 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4904 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4905 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4906 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4907 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4908 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4909 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4910 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4914 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4915 .ops = &snd_hda_bind_vol,
4917 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4918 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4919 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4924 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4925 .ops = &snd_hda_bind_sw,
4927 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4928 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4933 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4934 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4935 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4936 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4937 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4941 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4942 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4946 static void alc260_hp_3013_automute(struct hda_codec *codec)
4948 struct alc_spec *spec = codec->spec;
4949 unsigned int present;
4951 present = snd_hda_codec_read(codec, 0x15, 0,
4952 AC_VERB_GET_PIN_SENSE, 0);
4953 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4954 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4957 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4960 if ((res >> 26) == ALC880_HP_EVENT)
4961 alc260_hp_3013_automute(codec);
4964 static void alc260_hp_3012_automute(struct hda_codec *codec)
4966 unsigned int present, bits;
4968 present = snd_hda_codec_read(codec, 0x10, 0,
4969 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4971 bits = present ? 0 : PIN_OUT;
4972 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4974 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4976 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4980 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4983 if ((res >> 26) == ALC880_HP_EVENT)
4984 alc260_hp_3012_automute(codec);
4987 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4988 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4990 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4991 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4992 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4993 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4994 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4995 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4996 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4997 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4998 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4999 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5000 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5004 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5005 * versions of the ALC260 don't act on requests to enable mic bias from NID
5006 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5007 * datasheet doesn't mention this restriction. At this stage it's not clear
5008 * whether this behaviour is intentional or is a hardware bug in chip
5009 * revisions available in early 2006. Therefore for now allow the
5010 * "Headphone Jack Mode" control to span all choices, but if it turns out
5011 * that the lack of mic bias for this NID is intentional we could change the
5012 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5014 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5015 * don't appear to make the mic bias available from the "line" jack, even
5016 * though the NID used for this jack (0x14) can supply it. The theory is
5017 * that perhaps Acer have included blocking capacitors between the ALC260
5018 * and the output jack. If this turns out to be the case for all such
5019 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5020 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5022 * The C20x Tablet series have a mono internal speaker which is controlled
5023 * via the chip's Mono sum widget and pin complex, so include the necessary
5024 * controls for such models. On models without a "mono speaker" the control
5025 * won't do anything.
5027 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5028 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5029 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5030 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5031 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5033 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5035 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5036 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5038 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5039 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5040 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5041 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5042 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5046 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5048 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5049 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5050 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5051 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5052 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5053 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5054 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5058 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5059 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5061 static struct snd_kcontrol_new alc260_will_mixer[] = {
5062 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5063 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5065 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5066 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5067 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5068 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5069 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5070 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5071 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5075 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5076 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5078 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5079 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5080 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5082 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5083 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5084 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5085 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5086 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5087 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5088 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5093 * initialization verbs
5095 static struct hda_verb alc260_init_verbs[] = {
5096 /* Line In pin widget for input */
5097 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5098 /* CD pin widget for input */
5099 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5100 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5101 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5102 /* Mic2 (front panel) pin widget for input and vref at 80% */
5103 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5104 /* LINE-2 is used for line-out in rear */
5105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5106 /* select line-out */
5107 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5109 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5111 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5113 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5114 /* mute capture amp left and right */
5115 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5116 /* set connection select to line in (default select for this ADC) */
5117 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5118 /* mute capture amp left and right */
5119 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5120 /* set connection select to line in (default select for this ADC) */
5121 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5122 /* set vol=0 Line-Out mixer amp left and right */
5123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5124 /* unmute pin widget amp left and right (no gain on this amp) */
5125 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5126 /* set vol=0 HP mixer amp left and right */
5127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5128 /* unmute pin widget amp left and right (no gain on this amp) */
5129 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5130 /* set vol=0 Mono mixer amp left and right */
5131 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5132 /* unmute pin widget amp left and right (no gain on this amp) */
5133 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5134 /* unmute LINE-2 out pin */
5135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5136 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5139 /* mute analog inputs */
5140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5145 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5146 /* mute Front out path */
5147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5149 /* mute Headphone out path */
5150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5152 /* mute Mono out path */
5153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5158 #if 0 /* should be identical with alc260_init_verbs? */
5159 static struct hda_verb alc260_hp_init_verbs[] = {
5160 /* Headphone and output */
5161 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5163 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5164 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5165 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5166 /* Mic2 (front panel) pin widget for input and vref at 80% */
5167 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5168 /* Line In pin widget for input */
5169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5170 /* Line-2 pin widget for output */
5171 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5172 /* CD pin widget for input */
5173 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5174 /* unmute amp left and right */
5175 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5176 /* set connection select to line in (default select for this ADC) */
5177 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5178 /* unmute Line-Out mixer amp left and right (volume = 0) */
5179 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5180 /* mute pin widget amp left and right (no gain on this amp) */
5181 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5182 /* unmute HP mixer amp left and right (volume = 0) */
5183 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5184 /* mute pin widget amp left and right (no gain on this amp) */
5185 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5186 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5189 /* mute analog inputs */
5190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5195 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5196 /* Unmute Front out path */
5197 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5199 /* Unmute Headphone out path */
5200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5202 /* Unmute Mono out path */
5203 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5204 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5209 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5210 /* Line out and output */
5211 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5213 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5214 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5215 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5216 /* Mic2 (front panel) pin widget for input and vref at 80% */
5217 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5218 /* Line In pin widget for input */
5219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5220 /* Headphone pin widget for output */
5221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5222 /* CD pin widget for input */
5223 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5224 /* unmute amp left and right */
5225 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5226 /* set connection select to line in (default select for this ADC) */
5227 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5228 /* unmute Line-Out mixer amp left and right (volume = 0) */
5229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5230 /* mute pin widget amp left and right (no gain on this amp) */
5231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5232 /* unmute HP mixer amp left and right (volume = 0) */
5233 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5234 /* mute pin widget amp left and right (no gain on this amp) */
5235 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5236 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5239 /* mute analog inputs */
5240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5243 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5244 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5245 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5246 /* Unmute Front out path */
5247 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5248 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5249 /* Unmute Headphone out path */
5250 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5251 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5252 /* Unmute Mono out path */
5253 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5254 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5258 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5259 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5260 * audio = 0x16, internal speaker = 0x10.
5262 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5263 /* Disable all GPIOs */
5264 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5265 /* Internal speaker is connected to headphone pin */
5266 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5267 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5269 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5270 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5271 /* Ensure all other unused pins are disabled and muted. */
5272 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5273 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5274 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5275 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5276 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5277 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5279 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5281 /* Disable digital (SPDIF) pins */
5282 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5283 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5285 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5286 * when acting as an output.
5288 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5290 /* Start with output sum widgets muted and their output gains at min */
5291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5292 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5294 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5295 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5296 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5297 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5298 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5299 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5301 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5302 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5303 /* Unmute Line1 pin widget output buffer since it starts as an output.
5304 * If the pin mode is changed by the user the pin mode control will
5305 * take care of enabling the pin's input/output buffers as needed.
5306 * Therefore there's no need to enable the input buffer at this
5309 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5310 /* Unmute input buffer of pin widget used for Line-in (no equiv
5313 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5315 /* Mute capture amp left and right */
5316 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5317 /* Set ADC connection select to match default mixer setting - line
5320 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5322 /* Do the same for the second ADC: mute capture input amp and
5323 * set ADC connection to line in (on mic1 pin)
5325 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5326 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5328 /* Mute all inputs to mixer widget (even unconnected ones) */
5329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5341 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5342 * similar laptops (adapted from Fujitsu init verbs).
5344 static struct hda_verb alc260_acer_init_verbs[] = {
5345 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5346 * the headphone jack. Turn this on and rely on the standard mute
5347 * methods whenever the user wants to turn these outputs off.
5349 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5350 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5351 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5352 /* Internal speaker/Headphone jack is connected to Line-out pin */
5353 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5354 /* Internal microphone/Mic jack is connected to Mic1 pin */
5355 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5356 /* Line In jack is connected to Line1 pin */
5357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5358 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5359 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5360 /* Ensure all other unused pins are disabled and muted. */
5361 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5362 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5363 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5364 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5366 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5367 /* Disable digital (SPDIF) pins */
5368 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5369 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5371 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5372 * bus when acting as outputs.
5374 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5375 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5377 /* Start with output sum widgets muted and their output gains at min */
5378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5382 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5383 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5384 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5385 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5386 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5388 /* Unmute Line-out pin widget amp left and right
5389 * (no equiv mixer ctrl)
5391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5392 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5393 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5394 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5395 * inputs. If the pin mode is changed by the user the pin mode control
5396 * will take care of enabling the pin's input/output buffers as needed.
5397 * Therefore there's no need to enable the input buffer at this
5400 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5401 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5403 /* Mute capture amp left and right */
5404 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5405 /* Set ADC connection select to match default mixer setting - mic
5408 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5410 /* Do similar with the second ADC: mute capture input amp and
5411 * set ADC connection to mic to match ALSA's default state.
5413 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5414 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5416 /* Mute all inputs to mixer widget (even unconnected ones) */
5417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5418 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5419 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5429 /* Initialisation sequence for Maxdata Favorit 100XS
5430 * (adapted from Acer init verbs).
5432 static struct hda_verb alc260_favorit100_init_verbs[] = {
5433 /* GPIO 0 enables the output jack.
5434 * Turn this on and rely on the standard mute
5435 * methods whenever the user wants to turn these outputs off.
5437 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5438 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5439 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5440 /* Line/Mic input jack is connected to Mic1 pin */
5441 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5442 /* Ensure all other unused pins are disabled and muted. */
5443 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5444 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5445 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5446 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5447 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5448 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5450 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5453 /* Disable digital (SPDIF) pins */
5454 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5455 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5457 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5458 * bus when acting as outputs.
5460 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5461 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5463 /* Start with output sum widgets muted and their output gains at min */
5464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5468 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5469 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5470 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5471 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5472 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5474 /* Unmute Line-out pin widget amp left and right
5475 * (no equiv mixer ctrl)
5477 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5478 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5479 * inputs. If the pin mode is changed by the user the pin mode control
5480 * will take care of enabling the pin's input/output buffers as needed.
5481 * Therefore there's no need to enable the input buffer at this
5484 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5486 /* Mute capture amp left and right */
5487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5488 /* Set ADC connection select to match default mixer setting - mic
5491 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5493 /* Do similar with the second ADC: mute capture input amp and
5494 * set ADC connection to mic to match ALSA's default state.
5496 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5497 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5499 /* Mute all inputs to mixer widget (even unconnected ones) */
5500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5512 static struct hda_verb alc260_will_verbs[] = {
5513 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5514 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5515 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5516 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5517 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5518 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5522 static struct hda_verb alc260_replacer_672v_verbs[] = {
5523 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5524 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5525 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5527 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5528 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5529 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5531 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5535 /* toggle speaker-output according to the hp-jack state */
5536 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5538 unsigned int present;
5540 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5541 present = snd_hda_codec_read(codec, 0x0f, 0,
5542 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5544 snd_hda_codec_write_cache(codec, 0x01, 0,
5545 AC_VERB_SET_GPIO_DATA, 1);
5546 snd_hda_codec_write_cache(codec, 0x0f, 0,
5547 AC_VERB_SET_PIN_WIDGET_CONTROL,
5550 snd_hda_codec_write_cache(codec, 0x01, 0,
5551 AC_VERB_SET_GPIO_DATA, 0);
5552 snd_hda_codec_write_cache(codec, 0x0f, 0,
5553 AC_VERB_SET_PIN_WIDGET_CONTROL,
5558 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5561 if ((res >> 26) == ALC880_HP_EVENT)
5562 alc260_replacer_672v_automute(codec);
5565 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5566 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5567 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5568 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5570 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5572 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5573 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5574 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5579 /* Test configuration for debugging, modelled after the ALC880 test
5582 #ifdef CONFIG_SND_DEBUG
5583 static hda_nid_t alc260_test_dac_nids[1] = {
5586 static hda_nid_t alc260_test_adc_nids[2] = {
5589 /* For testing the ALC260, each input MUX needs its own definition since
5590 * the signal assignments are different. This assumes that the first ADC
5593 static struct hda_input_mux alc260_test_capture_sources[2] = {
5597 { "MIC1 pin", 0x0 },
5598 { "MIC2 pin", 0x1 },
5599 { "LINE1 pin", 0x2 },
5600 { "LINE2 pin", 0x3 },
5602 { "LINE-OUT pin", 0x5 },
5603 { "HP-OUT pin", 0x6 },
5609 { "MIC1 pin", 0x0 },
5610 { "MIC2 pin", 0x1 },
5611 { "LINE1 pin", 0x2 },
5612 { "LINE2 pin", 0x3 },
5615 { "LINE-OUT pin", 0x6 },
5616 { "HP-OUT pin", 0x7 },
5620 static struct snd_kcontrol_new alc260_test_mixer[] = {
5621 /* Output driver widgets */
5622 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5623 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5624 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5625 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5626 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5627 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5629 /* Modes for retasking pin widgets
5630 * Note: the ALC260 doesn't seem to act on requests to enable mic
5631 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5632 * mention this restriction. At this stage it's not clear whether
5633 * this behaviour is intentional or is a hardware bug in chip
5634 * revisions available at least up until early 2006. Therefore for
5635 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5636 * choices, but if it turns out that the lack of mic bias for these
5637 * NIDs is intentional we could change their modes from
5638 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5640 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5641 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5642 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5643 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5644 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5645 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5647 /* Loopback mixer controls */
5648 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5649 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5650 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5651 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5652 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5653 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5654 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5655 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5656 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5657 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5658 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5659 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5660 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5661 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5663 /* Controls for GPIO pins, assuming they are configured as outputs */
5664 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5665 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5666 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5667 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5669 /* Switches to allow the digital IO pins to be enabled. The datasheet
5670 * is ambigious as to which NID is which; testing on laptops which
5671 * make this output available should provide clarification.
5673 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5674 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5676 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5677 * this output to turn on an external amplifier.
5679 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5680 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5684 static struct hda_verb alc260_test_init_verbs[] = {
5685 /* Enable all GPIOs as outputs with an initial value of 0 */
5686 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5687 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5688 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5690 /* Enable retasking pins as output, initially without power amp */
5691 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5692 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5694 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5695 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5696 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5698 /* Disable digital (SPDIF) pins initially, but users can enable
5699 * them via a mixer switch. In the case of SPDIF-out, this initverb
5700 * payload also sets the generation to 0, output to be in "consumer"
5701 * PCM format, copyright asserted, no pre-emphasis and no validity
5704 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5705 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5707 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5708 * OUT1 sum bus when acting as an output.
5710 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5711 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5712 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5713 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5715 /* Start with output sum widgets muted and their output gains at min */
5716 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5717 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5719 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5723 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5724 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5726 /* Unmute retasking pin widget output buffers since the default
5727 * state appears to be output. As the pin mode is changed by the
5728 * user the pin mode control will take care of enabling the pin's
5729 * input/output buffers as needed.
5731 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5732 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5735 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5736 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5737 /* Also unmute the mono-out pin widget */
5738 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5740 /* Mute capture amp left and right */
5741 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5742 /* Set ADC connection select to match default mixer setting (mic1
5745 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5747 /* Do the same for the second ADC: mute capture input amp and
5748 * set ADC connection to mic1 pin
5750 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5751 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5753 /* Mute all inputs to mixer widget (even unconnected ones) */
5754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5755 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5756 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5757 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5758 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5759 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5760 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5761 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5767 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5768 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5770 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5771 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5774 * for BIOS auto-configuration
5777 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5778 const char *pfx, int *vol_bits)
5781 unsigned long vol_val, sw_val;
5785 if (nid >= 0x0f && nid < 0x11) {
5786 nid_vol = nid - 0x7;
5787 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5788 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5789 } else if (nid == 0x11) {
5790 nid_vol = nid - 0x7;
5791 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5792 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5793 } else if (nid >= 0x12 && nid <= 0x15) {
5795 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5796 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5800 if (!(*vol_bits & (1 << nid_vol))) {
5801 /* first control for the volume widget */
5802 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5803 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5806 *vol_bits |= (1 << nid_vol);
5808 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5809 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5815 /* add playback controls from the parsed DAC table */
5816 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5817 const struct auto_pin_cfg *cfg)
5823 spec->multiout.num_dacs = 1;
5824 spec->multiout.dac_nids = spec->private_dac_nids;
5825 spec->multiout.dac_nids[0] = 0x02;
5827 nid = cfg->line_out_pins[0];
5829 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5834 nid = cfg->speaker_pins[0];
5836 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5841 nid = cfg->hp_pins[0];
5843 err = alc260_add_playback_controls(spec, nid, "Headphone",
5851 /* create playback/capture controls for input pins */
5852 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5853 const struct auto_pin_cfg *cfg)
5855 struct hda_input_mux *imux = &spec->private_imux[0];
5858 for (i = 0; i < AUTO_PIN_LAST; i++) {
5859 if (cfg->input_pins[i] >= 0x12) {
5860 idx = cfg->input_pins[i] - 0x12;
5861 err = new_analog_input(spec, cfg->input_pins[i],
5862 auto_pin_cfg_labels[i], idx,
5866 imux->items[imux->num_items].label =
5867 auto_pin_cfg_labels[i];
5868 imux->items[imux->num_items].index = idx;
5871 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5872 idx = cfg->input_pins[i] - 0x09;
5873 err = new_analog_input(spec, cfg->input_pins[i],
5874 auto_pin_cfg_labels[i], idx,
5878 imux->items[imux->num_items].label =
5879 auto_pin_cfg_labels[i];
5880 imux->items[imux->num_items].index = idx;
5887 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5888 hda_nid_t nid, int pin_type,
5891 alc_set_pin_output(codec, nid, pin_type);
5892 /* need the manual connection? */
5894 int idx = nid - 0x12;
5895 snd_hda_codec_write(codec, idx + 0x0b, 0,
5896 AC_VERB_SET_CONNECT_SEL, sel_idx);
5900 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5902 struct alc_spec *spec = codec->spec;
5905 nid = spec->autocfg.line_out_pins[0];
5907 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5908 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5911 nid = spec->autocfg.speaker_pins[0];
5913 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5915 nid = spec->autocfg.hp_pins[0];
5917 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5920 #define ALC260_PIN_CD_NID 0x16
5921 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5923 struct alc_spec *spec = codec->spec;
5926 for (i = 0; i < AUTO_PIN_LAST; i++) {
5927 hda_nid_t nid = spec->autocfg.input_pins[i];
5929 alc_set_input_pin(codec, nid, i);
5930 if (nid != ALC260_PIN_CD_NID &&
5931 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5932 snd_hda_codec_write(codec, nid, 0,
5933 AC_VERB_SET_AMP_GAIN_MUTE,
5940 * generic initialization of ADC, input mixers and output mixers
5942 static struct hda_verb alc260_volume_init_verbs[] = {
5944 * Unmute ADC0-1 and set the default input to mic-in
5946 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5947 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5948 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5949 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5951 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5953 * Note: PASD motherboards uses the Line In 2 as the input for
5954 * front panel mic (mic 2)
5956 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5957 /* mute analog inputs */
5958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5965 * Set up output mixers (0x08 - 0x0a)
5967 /* set vol=0 to output mixers */
5968 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5970 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5971 /* set up input amps for analog loopback */
5972 /* Amp Indices: DAC = 0, mixer = 1 */
5973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5977 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5978 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5983 static int alc260_parse_auto_config(struct hda_codec *codec)
5985 struct alc_spec *spec = codec->spec;
5987 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5989 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5993 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5996 if (!spec->kctls.list)
5997 return 0; /* can't find valid BIOS pin config */
5998 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
6002 spec->multiout.max_channels = 2;
6004 if (spec->autocfg.dig_outs)
6005 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6006 if (spec->kctls.list)
6007 add_mixer(spec, spec->kctls.list);
6009 add_verb(spec, alc260_volume_init_verbs);
6011 spec->num_mux_defs = 1;
6012 spec->input_mux = &spec->private_imux[0];
6014 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6019 /* additional initialization for auto-configuration model */
6020 static void alc260_auto_init(struct hda_codec *codec)
6022 struct alc_spec *spec = codec->spec;
6023 alc260_auto_init_multi_out(codec);
6024 alc260_auto_init_analog_input(codec);
6025 if (spec->unsol_event)
6026 alc_inithook(codec);
6029 #ifdef CONFIG_SND_HDA_POWER_SAVE
6030 static struct hda_amp_list alc260_loopbacks[] = {
6031 { 0x07, HDA_INPUT, 0 },
6032 { 0x07, HDA_INPUT, 1 },
6033 { 0x07, HDA_INPUT, 2 },
6034 { 0x07, HDA_INPUT, 3 },
6035 { 0x07, HDA_INPUT, 4 },
6041 * ALC260 configurations
6043 static const char *alc260_models[ALC260_MODEL_LAST] = {
6044 [ALC260_BASIC] = "basic",
6046 [ALC260_HP_3013] = "hp-3013",
6047 [ALC260_HP_DC7600] = "hp-dc7600",
6048 [ALC260_FUJITSU_S702X] = "fujitsu",
6049 [ALC260_ACER] = "acer",
6050 [ALC260_WILL] = "will",
6051 [ALC260_REPLACER_672V] = "replacer",
6052 [ALC260_FAVORIT100] = "favorit100",
6053 #ifdef CONFIG_SND_DEBUG
6054 [ALC260_TEST] = "test",
6056 [ALC260_AUTO] = "auto",
6059 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6060 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6061 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6062 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6063 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6064 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
6065 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6066 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6067 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6068 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6069 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6070 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6071 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6072 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6073 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6074 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6075 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6076 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6077 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6078 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6082 static struct alc_config_preset alc260_presets[] = {
6084 .mixers = { alc260_base_output_mixer,
6085 alc260_input_mixer },
6086 .init_verbs = { alc260_init_verbs },
6087 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6088 .dac_nids = alc260_dac_nids,
6089 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6090 .adc_nids = alc260_adc_nids,
6091 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6092 .channel_mode = alc260_modes,
6093 .input_mux = &alc260_capture_source,
6096 .mixers = { alc260_hp_output_mixer,
6097 alc260_input_mixer },
6098 .init_verbs = { alc260_init_verbs,
6099 alc260_hp_unsol_verbs },
6100 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6101 .dac_nids = alc260_dac_nids,
6102 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6103 .adc_nids = alc260_adc_nids_alt,
6104 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6105 .channel_mode = alc260_modes,
6106 .input_mux = &alc260_capture_source,
6107 .unsol_event = alc260_hp_unsol_event,
6108 .init_hook = alc260_hp_automute,
6110 [ALC260_HP_DC7600] = {
6111 .mixers = { alc260_hp_dc7600_mixer,
6112 alc260_input_mixer },
6113 .init_verbs = { alc260_init_verbs,
6114 alc260_hp_dc7600_verbs },
6115 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6116 .dac_nids = alc260_dac_nids,
6117 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6118 .adc_nids = alc260_adc_nids_alt,
6119 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6120 .channel_mode = alc260_modes,
6121 .input_mux = &alc260_capture_source,
6122 .unsol_event = alc260_hp_3012_unsol_event,
6123 .init_hook = alc260_hp_3012_automute,
6125 [ALC260_HP_3013] = {
6126 .mixers = { alc260_hp_3013_mixer,
6127 alc260_input_mixer },
6128 .init_verbs = { alc260_hp_3013_init_verbs,
6129 alc260_hp_3013_unsol_verbs },
6130 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6131 .dac_nids = alc260_dac_nids,
6132 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6133 .adc_nids = alc260_adc_nids_alt,
6134 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6135 .channel_mode = alc260_modes,
6136 .input_mux = &alc260_capture_source,
6137 .unsol_event = alc260_hp_3013_unsol_event,
6138 .init_hook = alc260_hp_3013_automute,
6140 [ALC260_FUJITSU_S702X] = {
6141 .mixers = { alc260_fujitsu_mixer },
6142 .init_verbs = { alc260_fujitsu_init_verbs },
6143 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6144 .dac_nids = alc260_dac_nids,
6145 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6146 .adc_nids = alc260_dual_adc_nids,
6147 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6148 .channel_mode = alc260_modes,
6149 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6150 .input_mux = alc260_fujitsu_capture_sources,
6153 .mixers = { alc260_acer_mixer },
6154 .init_verbs = { alc260_acer_init_verbs },
6155 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6156 .dac_nids = alc260_dac_nids,
6157 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6158 .adc_nids = alc260_dual_adc_nids,
6159 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6160 .channel_mode = alc260_modes,
6161 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6162 .input_mux = alc260_acer_capture_sources,
6164 [ALC260_FAVORIT100] = {
6165 .mixers = { alc260_favorit100_mixer },
6166 .init_verbs = { alc260_favorit100_init_verbs },
6167 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6168 .dac_nids = alc260_dac_nids,
6169 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6170 .adc_nids = alc260_dual_adc_nids,
6171 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6172 .channel_mode = alc260_modes,
6173 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6174 .input_mux = alc260_favorit100_capture_sources,
6177 .mixers = { alc260_will_mixer },
6178 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6179 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6180 .dac_nids = alc260_dac_nids,
6181 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6182 .adc_nids = alc260_adc_nids,
6183 .dig_out_nid = ALC260_DIGOUT_NID,
6184 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6185 .channel_mode = alc260_modes,
6186 .input_mux = &alc260_capture_source,
6188 [ALC260_REPLACER_672V] = {
6189 .mixers = { alc260_replacer_672v_mixer },
6190 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6191 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6192 .dac_nids = alc260_dac_nids,
6193 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6194 .adc_nids = alc260_adc_nids,
6195 .dig_out_nid = ALC260_DIGOUT_NID,
6196 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6197 .channel_mode = alc260_modes,
6198 .input_mux = &alc260_capture_source,
6199 .unsol_event = alc260_replacer_672v_unsol_event,
6200 .init_hook = alc260_replacer_672v_automute,
6202 #ifdef CONFIG_SND_DEBUG
6204 .mixers = { alc260_test_mixer },
6205 .init_verbs = { alc260_test_init_verbs },
6206 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6207 .dac_nids = alc260_test_dac_nids,
6208 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6209 .adc_nids = alc260_test_adc_nids,
6210 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6211 .channel_mode = alc260_modes,
6212 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6213 .input_mux = alc260_test_capture_sources,
6218 static int patch_alc260(struct hda_codec *codec)
6220 struct alc_spec *spec;
6221 int err, board_config;
6223 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6229 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6232 if (board_config < 0) {
6233 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6234 "trying auto-probe from BIOS...\n",
6236 board_config = ALC260_AUTO;
6239 if (board_config == ALC260_AUTO) {
6240 /* automatic parse from the BIOS config */
6241 err = alc260_parse_auto_config(codec);
6247 "hda_codec: Cannot set up configuration "
6248 "from BIOS. Using base mode...\n");
6249 board_config = ALC260_BASIC;
6253 err = snd_hda_attach_beep_device(codec, 0x1);
6259 if (board_config != ALC260_AUTO)
6260 setup_preset(spec, &alc260_presets[board_config]);
6262 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6263 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6265 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6266 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6268 if (!spec->adc_nids && spec->input_mux) {
6269 /* check whether NID 0x04 is valid */
6270 unsigned int wcap = get_wcaps(codec, 0x04);
6271 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6273 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6274 spec->adc_nids = alc260_adc_nids_alt;
6275 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6277 spec->adc_nids = alc260_adc_nids;
6278 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6281 set_capture_mixer(spec);
6282 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6284 spec->vmaster_nid = 0x08;
6286 codec->patch_ops = alc_patch_ops;
6287 if (board_config == ALC260_AUTO)
6288 spec->init_hook = alc260_auto_init;
6289 #ifdef CONFIG_SND_HDA_POWER_SAVE
6290 if (!spec->loopback.amplist)
6291 spec->loopback.amplist = alc260_loopbacks;
6293 codec->proc_widget_hook = print_realtek_coef;
6300 * ALC882/883/885/888/889 support
6302 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6303 * configuration. Each pin widget can choose any input DACs and a mixer.
6304 * Each ADC is connected from a mixer of all inputs. This makes possible
6305 * 6-channel independent captures.
6307 * In addition, an independent DAC for the multi-playback (not used in this
6310 #define ALC882_DIGOUT_NID 0x06
6311 #define ALC882_DIGIN_NID 0x0a
6312 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6313 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
6314 #define ALC1200_DIGOUT_NID 0x10
6317 static struct hda_channel_mode alc882_ch_modes[1] = {
6322 static hda_nid_t alc882_dac_nids[4] = {
6323 /* front, rear, clfe, rear_surr */
6324 0x02, 0x03, 0x04, 0x05
6326 #define alc883_dac_nids alc882_dac_nids
6329 #define alc882_adc_nids alc880_adc_nids
6330 #define alc882_adc_nids_alt alc880_adc_nids_alt
6331 #define alc883_adc_nids alc882_adc_nids_alt
6332 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6333 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6334 #define alc889_adc_nids alc880_adc_nids
6336 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6337 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6338 #define alc883_capsrc_nids alc882_capsrc_nids_alt
6339 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6340 #define alc889_capsrc_nids alc882_capsrc_nids
6343 /* FIXME: should be a matrix-type input source selection */
6345 static struct hda_input_mux alc882_capture_source = {
6349 { "Front Mic", 0x1 },
6355 #define alc883_capture_source alc882_capture_source
6357 static struct hda_input_mux mb5_capture_source = {
6366 static struct hda_input_mux alc883_3stack_6ch_intel = {
6370 { "Front Mic", 0x0 },
6376 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6384 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6394 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6402 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6406 { "Front Mic", 0x1 },
6411 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6419 static struct hda_input_mux alc889A_mb31_capture_source = {
6423 /* Front Mic (0x01) unused */
6425 /* Line 2 (0x03) unused */
6426 /* CD (0x04) unsused? */
6433 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6440 static struct hda_verb alc882_3ST_ch2_init[] = {
6441 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6442 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6443 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6444 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6451 static struct hda_verb alc882_3ST_ch4_init[] = {
6452 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6453 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6454 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6455 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6456 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6463 static struct hda_verb alc882_3ST_ch6_init[] = {
6464 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6465 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6466 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6469 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6473 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6474 { 2, alc882_3ST_ch2_init },
6475 { 4, alc882_3ST_ch4_init },
6476 { 6, alc882_3ST_ch6_init },
6479 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6484 static struct hda_verb alc882_sixstack_ch6_init[] = {
6485 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6486 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6487 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6488 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6495 static struct hda_verb alc882_sixstack_ch8_init[] = {
6496 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6497 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6498 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6499 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6503 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6504 { 6, alc882_sixstack_ch6_init },
6505 { 8, alc882_sixstack_ch8_init },
6509 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6515 static struct hda_verb alc885_mbp_ch2_init[] = {
6516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6517 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6525 static struct hda_verb alc885_mbp_ch6_init[] = {
6526 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6527 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6528 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6529 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6530 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6534 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6535 { 2, alc885_mbp_ch2_init },
6536 { 6, alc885_mbp_ch6_init },
6541 * Speakers/Woofer/HP = Front
6544 static struct hda_verb alc885_mb5_ch2_init[] = {
6545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6552 * Speakers/HP = Front
6556 static struct hda_verb alc885_mb5_ch6_init[] = {
6557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6559 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6563 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6564 { 2, alc885_mb5_ch2_init },
6565 { 6, alc885_mb5_ch6_init },
6572 static struct hda_verb alc883_4ST_ch2_init[] = {
6573 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6574 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6575 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6576 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6577 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6578 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6585 static struct hda_verb alc883_4ST_ch4_init[] = {
6586 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6587 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6588 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6589 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6590 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6591 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6592 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6599 static struct hda_verb alc883_4ST_ch6_init[] = {
6600 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6601 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6602 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6603 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6604 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6605 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6606 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6607 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6614 static struct hda_verb alc883_4ST_ch8_init[] = {
6615 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6616 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6617 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6618 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6619 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6620 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6621 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6622 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6623 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6627 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6628 { 2, alc883_4ST_ch2_init },
6629 { 4, alc883_4ST_ch4_init },
6630 { 6, alc883_4ST_ch6_init },
6631 { 8, alc883_4ST_ch8_init },
6638 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6639 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6640 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6649 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6650 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6651 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6652 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6653 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6654 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6661 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6662 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6663 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6664 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6665 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6666 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6667 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6671 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6672 { 2, alc883_3ST_ch2_intel_init },
6673 { 4, alc883_3ST_ch4_intel_init },
6674 { 6, alc883_3ST_ch6_intel_init },
6680 static struct hda_verb alc883_sixstack_ch6_init[] = {
6681 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6682 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6683 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6684 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6691 static struct hda_verb alc883_sixstack_ch8_init[] = {
6692 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6693 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6694 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6695 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6699 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6700 { 6, alc883_sixstack_ch6_init },
6701 { 8, alc883_sixstack_ch8_init },
6705 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6706 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6708 static struct snd_kcontrol_new alc882_base_mixer[] = {
6709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6710 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6711 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6712 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6713 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6714 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6715 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6716 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6717 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6718 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6719 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6721 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6722 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6723 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6724 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6725 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6727 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6728 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6733 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6734 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6735 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6736 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6737 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6738 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6739 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6741 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6742 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6743 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6747 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6748 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6749 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6750 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6751 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6752 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6753 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6754 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6755 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
6756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6757 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6759 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6760 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6761 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6765 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6766 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6767 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6768 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6769 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6770 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6771 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6773 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6774 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6778 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6779 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6780 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6782 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6783 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6784 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6785 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6787 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6788 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6789 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6790 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6791 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6795 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6796 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6798 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6799 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6800 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6802 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6803 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6804 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6805 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6806 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6807 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6808 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6811 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6815 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6816 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6817 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6819 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6820 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6829 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6832 .name = "Channel Mode",
6833 .info = alc_ch_mode_info,
6834 .get = alc_ch_mode_get,
6835 .put = alc_ch_mode_put,
6840 static struct hda_verb alc882_base_init_verbs[] = {
6841 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6846 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6850 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6852 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6854 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6855 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6856 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6858 /* mute analog input loopbacks */
6859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6861 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6863 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6865 /* Front Pin: output 0 (0x0c) */
6866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6868 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6869 /* Rear Pin: output 1 (0x0d) */
6870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6872 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6873 /* CLFE Pin: output 2 (0x0e) */
6874 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6876 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6877 /* Side Pin: output 3 (0x0f) */
6878 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6879 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6880 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6881 /* Mic (rear) pin: input vref at 80% */
6882 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6883 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6884 /* Front Mic pin: input vref at 80% */
6885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6886 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6887 /* Line In pin: input */
6888 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6889 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6890 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6891 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6892 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6893 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6894 /* CD pin widget for input */
6895 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6897 /* FIXME: use matrix-type input source selection */
6898 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6900 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6905 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6906 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6907 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6908 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6909 /* ADC2: mute amp left and right */
6910 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6911 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6912 /* ADC3: mute amp left and right */
6913 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6914 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6919 static struct hda_verb alc882_adc1_init_verbs[] = {
6920 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6922 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6923 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6924 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6925 /* ADC1: mute amp left and right */
6926 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6927 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6931 static struct hda_verb alc882_eapd_verbs[] = {
6932 /* change to EAPD mode */
6933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6934 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6938 #define alc883_init_verbs alc882_base_init_verbs
6941 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6942 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6943 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6944 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6945 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6946 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6947 /* FIXME: this looks suspicious...
6948 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6949 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6954 static struct hda_verb alc882_macpro_init_verbs[] = {
6955 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6956 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6959 /* Front Pin: output 0 (0x0c) */
6960 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6962 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6963 /* Front Mic pin: input vref at 80% */
6964 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6965 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6966 /* Speaker: output */
6967 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6968 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6969 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6970 /* Headphone output (output 0 - 0x0c) */
6971 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6972 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6973 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6975 /* FIXME: use matrix-type input source selection */
6976 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6977 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6979 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6980 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6981 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6985 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6986 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6990 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6991 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6992 /* ADC1: mute amp left and right */
6993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6994 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6995 /* ADC2: mute amp left and right */
6996 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6997 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6998 /* ADC3: mute amp left and right */
6999 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7000 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7006 static struct hda_verb alc885_mb5_init_verbs[] = {
7008 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7009 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7010 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7011 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7013 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7014 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7015 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7016 /* Surround mixer */
7017 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7025 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7026 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7027 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7028 /* Front Pin (0x0c) */
7029 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7030 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7031 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7032 /* LFE Pin (0x0e) */
7033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7034 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7035 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7038 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7039 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7040 /* Front Mic pin: input vref at 80% */
7041 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7042 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7048 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7049 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7050 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7054 /* Macbook Pro rev3 */
7055 static struct hda_verb alc885_mbp3_init_verbs[] = {
7056 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7057 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7061 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7064 /* Front Pin: output 0 (0x0c) */
7065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7066 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7067 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7068 /* HP Pin: output 0 (0x0d) */
7069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7072 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7073 /* Mic (rear) pin: input vref at 80% */
7074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7076 /* Front Mic pin: input vref at 80% */
7077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7079 /* Line In pin: use output 1 when in LineOut mode */
7080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7082 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7084 /* FIXME: use matrix-type input source selection */
7085 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7086 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7088 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7089 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7092 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7093 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7094 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7095 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7099 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7101 /* ADC1: mute amp left and right */
7102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7103 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7104 /* ADC2: mute amp left and right */
7105 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7107 /* ADC3: mute amp left and right */
7108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7109 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7114 /* iMac 24 mixer. */
7115 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7116 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7117 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7121 /* iMac 24 init verbs. */
7122 static struct hda_verb alc885_imac24_init_verbs[] = {
7123 /* Internal speakers: output 0 (0x0c) */
7124 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7125 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7126 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7127 /* Internal speakers: output 0 (0x0c) */
7128 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7129 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7130 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7131 /* Headphone: output 0 (0x0c) */
7132 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7133 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7134 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7135 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7136 /* Front Mic: input vref at 80% */
7137 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7138 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7142 /* Toggle speaker-output according to the hp-jack state */
7143 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
7145 struct alc_spec *spec = codec->spec;
7147 spec->autocfg.hp_pins[0] = 0x14;
7148 spec->autocfg.speaker_pins[0] = 0x18;
7149 spec->autocfg.speaker_pins[1] = 0x1a;
7150 alc_automute_amp(codec);
7153 static void alc885_mbp3_init_hook(struct hda_codec *codec)
7155 struct alc_spec *spec = codec->spec;
7157 spec->autocfg.hp_pins[0] = 0x15;
7158 spec->autocfg.speaker_pins[0] = 0x14;
7159 alc_automute_amp(codec);
7163 static struct hda_verb alc882_targa_verbs[] = {
7164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7167 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7168 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7170 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7171 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7172 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7178 /* toggle speaker-output according to the hp-jack state */
7179 static void alc882_targa_automute(struct hda_codec *codec)
7181 struct alc_spec *spec = codec->spec;
7182 alc_automute_amp(codec);
7183 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7184 spec->jack_present ? 1 : 3);
7187 static void alc882_targa_init_hook(struct hda_codec *codec)
7189 struct alc_spec *spec = codec->spec;
7191 spec->autocfg.hp_pins[0] = 0x14;
7192 spec->autocfg.speaker_pins[0] = 0x1b;
7193 alc882_targa_automute(codec);
7196 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7198 if ((res >> 26) == ALC880_HP_EVENT)
7199 alc882_targa_automute(codec);
7202 static struct hda_verb alc882_asus_a7j_verbs[] = {
7203 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7204 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7206 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7208 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7210 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7212 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7214 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7215 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7216 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7220 static struct hda_verb alc882_asus_a7m_verbs[] = {
7221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7226 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7228 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7230 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7232 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7233 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7234 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7238 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7240 unsigned int gpiostate, gpiomask, gpiodir;
7242 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7243 AC_VERB_GET_GPIO_DATA, 0);
7246 gpiostate |= (1 << pin);
7248 gpiostate &= ~(1 << pin);
7250 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7251 AC_VERB_GET_GPIO_MASK, 0);
7252 gpiomask |= (1 << pin);
7254 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7255 AC_VERB_GET_GPIO_DIRECTION, 0);
7256 gpiodir |= (1 << pin);
7259 snd_hda_codec_write(codec, codec->afg, 0,
7260 AC_VERB_SET_GPIO_MASK, gpiomask);
7261 snd_hda_codec_write(codec, codec->afg, 0,
7262 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7266 snd_hda_codec_write(codec, codec->afg, 0,
7267 AC_VERB_SET_GPIO_DATA, gpiostate);
7270 /* set up GPIO at initialization */
7271 static void alc885_macpro_init_hook(struct hda_codec *codec)
7273 alc882_gpio_mute(codec, 0, 0);
7274 alc882_gpio_mute(codec, 1, 0);
7277 /* set up GPIO and update auto-muting at initialization */
7278 static void alc885_imac24_init_hook(struct hda_codec *codec)
7280 alc885_macpro_init_hook(codec);
7281 alc885_imac24_automute_init_hook(codec);
7285 * generic initialization of ADC, input mixers and output mixers
7287 static struct hda_verb alc883_auto_init_verbs[] = {
7289 * Unmute ADC0-2 and set the default input to mic-in
7291 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7292 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7293 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7294 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7296 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7298 * Note: PASD motherboards uses the Line In 2 as the input for
7299 * front panel mic (mic 2)
7301 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7302 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7303 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7305 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7309 * Set up output mixers (0x0c - 0x0f)
7311 /* set vol=0 to output mixers */
7312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7314 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7315 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7316 /* set up input amps for analog loopback */
7317 /* Amp Indices: DAC = 0, mixer = 1 */
7318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7320 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7322 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7323 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7324 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7325 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7326 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7327 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7329 /* FIXME: use matrix-type input source selection */
7330 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7345 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7346 static struct hda_verb alc889A_mb31_ch2_init[] = {
7347 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7348 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7354 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7355 static struct hda_verb alc889A_mb31_ch4_init[] = {
7356 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7357 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7358 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7359 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7363 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7364 static struct hda_verb alc889A_mb31_ch5_init[] = {
7365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7367 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7368 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7372 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7373 static struct hda_verb alc889A_mb31_ch6_init[] = {
7374 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7375 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7376 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7381 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7382 { 2, alc889A_mb31_ch2_init },
7383 { 4, alc889A_mb31_ch4_init },
7384 { 5, alc889A_mb31_ch5_init },
7385 { 6, alc889A_mb31_ch6_init },
7388 static struct hda_verb alc883_medion_eapd_verbs[] = {
7389 /* eanable EAPD on medion laptop */
7390 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7391 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7395 #define alc883_base_mixer alc882_base_mixer
7397 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7400 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7401 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7402 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7403 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7404 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7406 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7408 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7409 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7410 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7414 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7416 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7417 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7418 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7421 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7422 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7423 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7424 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7428 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7429 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7430 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7431 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7432 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7434 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7436 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7437 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7438 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7442 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7443 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7444 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7446 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7447 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7448 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7449 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7450 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7451 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7454 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7459 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7460 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7461 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7462 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7463 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7464 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7465 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7466 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7467 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7469 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7470 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7471 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7472 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7474 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7475 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7476 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7477 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7478 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7482 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7483 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7485 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7486 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7487 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7489 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7490 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7491 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7492 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7493 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7494 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7495 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7496 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7498 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7499 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7500 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7501 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7502 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7506 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7507 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7508 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7509 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7510 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7511 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7512 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7513 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7514 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7515 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7516 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7517 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7518 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7519 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7521 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7523 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7524 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7525 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7529 static struct snd_kcontrol_new alc883_targa_mixer[] = {
7530 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7531 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7532 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7533 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7534 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7535 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7536 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7537 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7538 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7539 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7540 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7541 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7542 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7543 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7544 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7549 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
7550 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7551 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7552 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7553 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7554 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7555 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7556 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7558 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7559 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7560 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7564 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7566 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7567 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7568 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7570 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7571 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7572 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7576 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7577 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7578 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7580 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7581 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7583 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7584 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7585 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7589 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7590 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7591 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7592 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7593 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7594 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7596 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7602 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7603 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7604 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7605 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7609 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7614 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
7615 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7616 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7617 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7618 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
7619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7621 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7622 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7629 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7630 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7631 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7632 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7633 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7634 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7635 0x0d, 1, 0x0, HDA_OUTPUT),
7636 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7637 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7638 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7639 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7640 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7641 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7642 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7643 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7644 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7646 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7647 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7648 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7650 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7654 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
7656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7657 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7659 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7660 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
7662 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
7663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
7664 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
7665 /* Output switches */
7666 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
7667 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
7668 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
7670 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7671 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7680 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
7681 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7682 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7685 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7690 static struct hda_bind_ctls alc883_bind_cap_vol = {
7691 .ops = &snd_hda_bind_vol,
7693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7699 static struct hda_bind_ctls alc883_bind_cap_switch = {
7700 .ops = &snd_hda_bind_sw,
7702 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7703 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7708 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7710 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7711 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7712 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7713 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7715 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7720 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7721 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7722 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7725 /* .name = "Capture Source", */
7726 .name = "Input Source",
7728 .info = alc_mux_enum_info,
7729 .get = alc_mux_enum_get,
7730 .put = alc_mux_enum_put,
7735 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7738 .name = "Channel Mode",
7739 .info = alc_ch_mode_info,
7740 .get = alc_ch_mode_get,
7741 .put = alc_ch_mode_put,
7746 /* toggle speaker-output according to the hp-jack state */
7747 static void alc883_mitac_init_hook(struct hda_codec *codec)
7749 struct alc_spec *spec = codec->spec;
7751 spec->autocfg.hp_pins[0] = 0x15;
7752 spec->autocfg.speaker_pins[0] = 0x14;
7753 spec->autocfg.speaker_pins[1] = 0x17;
7754 alc_automute_amp(codec);
7757 /* auto-toggle front mic */
7759 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7761 unsigned int present;
7764 present = snd_hda_codec_read(codec, 0x18, 0,
7765 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7766 bits = present ? HDA_AMP_MUTE : 0;
7767 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7771 static struct hda_verb alc883_mitac_verbs[] = {
7773 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7774 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7776 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7777 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7779 /* enable unsolicited event */
7780 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7781 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7786 static struct hda_verb alc883_clevo_m720_verbs[] = {
7788 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7791 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7794 /* enable unsolicited event */
7795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7801 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7803 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7809 /* enable unsolicited event */
7810 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7815 static struct hda_verb alc883_targa_verbs[] = {
7816 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7817 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7819 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7820 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7822 /* Connect Line-Out side jack (SPDIF) to Side */
7823 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7824 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7825 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7826 /* Connect Mic jack to CLFE */
7827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7829 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
7830 /* Connect Line-in jack to Surround */
7831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7832 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7833 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7834 /* Connect HP out jack to Front */
7835 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7836 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7837 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7839 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7844 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7846 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7851 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7852 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7854 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7859 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7860 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7861 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7862 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7863 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7864 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7868 static struct hda_verb alc883_haier_w66_verbs[] = {
7869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7870 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7874 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7875 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7876 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7881 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7883 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7884 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7885 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7886 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7887 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7888 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7889 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7893 static struct hda_verb alc888_6st_dell_verbs[] = {
7894 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7898 static struct hda_verb alc883_vaiott_verbs[] = {
7900 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7903 /* enable unsolicited event */
7904 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7909 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
7911 struct alc_spec *spec = codec->spec;
7913 spec->autocfg.hp_pins[0] = 0x1b;
7914 spec->autocfg.speaker_pins[0] = 0x14;
7915 spec->autocfg.speaker_pins[1] = 0x16;
7916 spec->autocfg.speaker_pins[2] = 0x18;
7917 alc_automute_amp(codec);
7920 static struct hda_verb alc888_3st_hp_verbs[] = {
7921 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7922 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7923 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7924 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7931 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7932 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7933 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7934 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7935 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7942 static struct hda_verb alc888_3st_hp_4ch_init[] = {
7943 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7944 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7945 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7946 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7947 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
7954 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7955 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7956 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7957 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7958 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7959 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7960 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
7964 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
7965 { 2, alc888_3st_hp_2ch_init },
7966 { 4, alc888_3st_hp_4ch_init },
7967 { 6, alc888_3st_hp_6ch_init },
7970 /* toggle front-jack and RCA according to the hp-jack state */
7971 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7973 unsigned int present;
7975 present = snd_hda_codec_read(codec, 0x1b, 0,
7976 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7977 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7978 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7979 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7980 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7983 /* toggle RCA according to the front-jack state */
7984 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7986 unsigned int present;
7988 present = snd_hda_codec_read(codec, 0x14, 0,
7989 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7990 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7991 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7994 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7997 if ((res >> 26) == ALC880_HP_EVENT)
7998 alc888_lenovo_ms7195_front_automute(codec);
7999 if ((res >> 26) == ALC880_FRONT_EVENT)
8000 alc888_lenovo_ms7195_rca_automute(codec);
8003 static struct hda_verb alc883_medion_md2_verbs[] = {
8004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8007 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8009 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8013 /* toggle speaker-output according to the hp-jack state */
8014 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8016 struct alc_spec *spec = codec->spec;
8018 spec->autocfg.hp_pins[0] = 0x14;
8019 spec->autocfg.speaker_pins[0] = 0x15;
8020 alc_automute_amp(codec);
8023 /* toggle speaker-output according to the hp-jack state */
8024 #define alc883_targa_init_hook alc882_targa_init_hook
8025 #define alc883_targa_unsol_event alc882_targa_unsol_event
8027 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8029 unsigned int present;
8031 present = snd_hda_codec_read(codec, 0x18, 0,
8032 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8033 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8034 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8037 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8039 struct alc_spec *spec = codec->spec;
8041 spec->autocfg.hp_pins[0] = 0x15;
8042 spec->autocfg.speaker_pins[0] = 0x14;
8043 alc_automute_amp(codec);
8044 alc883_clevo_m720_mic_automute(codec);
8047 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8050 switch (res >> 26) {
8051 case ALC880_MIC_EVENT:
8052 alc883_clevo_m720_mic_automute(codec);
8055 alc_automute_amp_unsol_event(codec, res);
8060 /* toggle speaker-output according to the hp-jack state */
8061 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8063 struct alc_spec *spec = codec->spec;
8065 spec->autocfg.hp_pins[0] = 0x14;
8066 spec->autocfg.speaker_pins[0] = 0x15;
8067 alc_automute_amp(codec);
8070 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8072 struct alc_spec *spec = codec->spec;
8074 spec->autocfg.hp_pins[0] = 0x1b;
8075 spec->autocfg.speaker_pins[0] = 0x14;
8076 alc_automute_amp(codec);
8079 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8081 unsigned int present;
8084 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8085 & AC_PINSENSE_PRESENCE;
8086 bits = present ? HDA_AMP_MUTE : 0;
8087 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8088 HDA_AMP_MUTE, bits);
8091 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8093 unsigned int present;
8096 present = snd_hda_codec_read(codec, 0x1b, 0,
8097 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8098 bits = present ? HDA_AMP_MUTE : 0;
8099 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8100 HDA_AMP_MUTE, bits);
8101 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8102 HDA_AMP_MUTE, bits);
8105 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8108 if ((res >> 26) == ALC880_HP_EVENT)
8109 alc883_lenovo_101e_all_automute(codec);
8110 if ((res >> 26) == ALC880_FRONT_EVENT)
8111 alc883_lenovo_101e_ispeaker_automute(codec);
8114 /* toggle speaker-output according to the hp-jack state */
8115 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8117 struct alc_spec *spec = codec->spec;
8119 spec->autocfg.hp_pins[0] = 0x14;
8120 spec->autocfg.speaker_pins[0] = 0x15;
8121 spec->autocfg.speaker_pins[1] = 0x16;
8122 alc_automute_amp(codec);
8125 static struct hda_verb alc883_acer_eapd_verbs[] = {
8126 /* HP Pin: output 0 (0x0c) */
8127 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8128 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8129 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8130 /* Front Pin: output 0 (0x0c) */
8131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8132 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8133 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8134 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8135 /* eanable EAPD on medion laptop */
8136 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8137 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8138 /* enable unsolicited event */
8139 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8143 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8145 struct alc_spec *spec = codec->spec;
8147 spec->autocfg.hp_pins[0] = 0x1b;
8148 spec->autocfg.speaker_pins[0] = 0x14;
8149 spec->autocfg.speaker_pins[1] = 0x15;
8150 spec->autocfg.speaker_pins[2] = 0x16;
8151 spec->autocfg.speaker_pins[3] = 0x17;
8152 alc_automute_amp(codec);
8155 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8157 struct alc_spec *spec = codec->spec;
8159 spec->autocfg.hp_pins[0] = 0x1b;
8160 spec->autocfg.speaker_pins[0] = 0x14;
8161 spec->autocfg.speaker_pins[1] = 0x15;
8162 spec->autocfg.speaker_pins[2] = 0x16;
8163 spec->autocfg.speaker_pins[3] = 0x17;
8164 spec->autocfg.speaker_pins[4] = 0x1a;
8165 alc_automute_amp(codec);
8168 static void alc883_vaiott_init_hook(struct hda_codec *codec)
8170 struct alc_spec *spec = codec->spec;
8172 spec->autocfg.hp_pins[0] = 0x15;
8173 spec->autocfg.speaker_pins[0] = 0x14;
8174 spec->autocfg.speaker_pins[1] = 0x17;
8175 alc_automute_amp(codec);
8178 static struct hda_verb alc888_asus_m90v_verbs[] = {
8179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8180 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8182 /* enable unsolicited event */
8183 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8184 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8188 static void alc883_nb_mic_automute(struct hda_codec *codec)
8190 unsigned int present;
8192 present = snd_hda_codec_read(codec, 0x18, 0,
8193 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8194 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8195 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8196 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8197 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8200 static void alc883_M90V_init_hook(struct hda_codec *codec)
8202 struct alc_spec *spec = codec->spec;
8204 spec->autocfg.hp_pins[0] = 0x1b;
8205 spec->autocfg.speaker_pins[0] = 0x14;
8206 spec->autocfg.speaker_pins[1] = 0x15;
8207 spec->autocfg.speaker_pins[2] = 0x16;
8208 alc_automute_pin(codec);
8211 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8214 switch (res >> 26) {
8215 case ALC880_MIC_EVENT:
8216 alc883_nb_mic_automute(codec);
8219 alc_sku_unsol_event(codec, res);
8224 static void alc883_mode2_inithook(struct hda_codec *codec)
8226 alc883_M90V_init_hook(codec);
8227 alc883_nb_mic_automute(codec);
8230 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8232 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8233 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8235 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8236 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8237 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8238 /* enable unsolicited event */
8239 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8243 static void alc883_eee1601_inithook(struct hda_codec *codec)
8245 struct alc_spec *spec = codec->spec;
8247 spec->autocfg.hp_pins[0] = 0x14;
8248 spec->autocfg.speaker_pins[0] = 0x1b;
8249 alc_automute_pin(codec);
8252 static struct hda_verb alc889A_mb31_verbs[] = {
8253 /* Init rear pin (used as headphone output) */
8254 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8255 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8256 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8257 /* Init line pin (used as output in 4ch and 6ch mode) */
8258 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8259 /* Init line 2 pin (used as headphone out by default) */
8260 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8261 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8265 /* Mute speakers according to the headphone jack state */
8266 static void alc889A_mb31_automute(struct hda_codec *codec)
8268 unsigned int present;
8270 /* Mute only in 2ch or 4ch mode */
8271 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8273 present = snd_hda_codec_read(codec, 0x15, 0,
8274 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8275 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8276 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8277 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8278 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8282 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8284 if ((res >> 26) == ALC880_HP_EVENT)
8285 alc889A_mb31_automute(codec);
8289 #ifdef CONFIG_SND_HDA_POWER_SAVE
8290 #define alc882_loopbacks alc880_loopbacks
8293 /* pcm configuration: identical with ALC880 */
8294 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
8295 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
8296 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
8297 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
8299 static hda_nid_t alc883_slave_dig_outs[] = {
8300 ALC1200_DIGOUT_NID, 0,
8303 static hda_nid_t alc1200_slave_dig_outs[] = {
8304 ALC883_DIGOUT_NID, 0,
8308 * configuration and preset
8310 static const char *alc882_models[ALC882_MODEL_LAST] = {
8311 [ALC882_3ST_DIG] = "3stack-dig",
8312 [ALC882_6ST_DIG] = "6stack-dig",
8313 [ALC882_ARIMA] = "arima",
8314 [ALC882_W2JC] = "w2jc",
8315 [ALC882_TARGA] = "targa",
8316 [ALC882_ASUS_A7J] = "asus-a7j",
8317 [ALC882_ASUS_A7M] = "asus-a7m",
8318 [ALC885_MACPRO] = "macpro",
8319 [ALC885_MB5] = "mb5",
8320 [ALC885_MBP3] = "mbp3",
8321 [ALC885_IMAC24] = "imac24",
8322 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
8323 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8324 [ALC883_3ST_6ch] = "3stack-6ch",
8325 [ALC883_6ST_DIG] = "alc883-6stack-dig",
8326 [ALC883_TARGA_DIG] = "targa-dig",
8327 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8328 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
8329 [ALC883_ACER] = "acer",
8330 [ALC883_ACER_ASPIRE] = "acer-aspire",
8331 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8332 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
8333 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8334 [ALC883_MEDION] = "medion",
8335 [ALC883_MEDION_MD2] = "medion-md2",
8336 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8337 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8338 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8339 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8340 [ALC888_LENOVO_SKY] = "lenovo-sky",
8341 [ALC883_HAIER_W66] = "haier-w66",
8342 [ALC888_3ST_HP] = "3stack-hp",
8343 [ALC888_6ST_DELL] = "6stack-dell",
8344 [ALC883_MITAC] = "mitac",
8345 [ALC883_CLEVO_M720] = "clevo-m720",
8346 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8347 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8348 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8349 [ALC1200_ASUS_P5Q] = "asus-p5q",
8350 [ALC889A_MB31] = "mb31",
8351 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
8352 [ALC882_AUTO] = "auto",
8355 static struct snd_pci_quirk alc882_cfg_tbl[] = {
8356 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8358 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8359 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8360 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8361 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8362 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8363 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8364 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8365 ALC888_ACER_ASPIRE_4930G),
8366 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8367 ALC888_ACER_ASPIRE_4930G),
8368 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8369 ALC888_ACER_ASPIRE_8930G),
8370 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8371 ALC888_ACER_ASPIRE_8930G),
8372 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8373 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
8374 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8375 ALC888_ACER_ASPIRE_6530G),
8376 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8377 ALC888_ACER_ASPIRE_6530G),
8378 /* default Acer -- disabled as it causes more problems.
8379 * model=auto should work fine now
8381 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8383 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8385 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8386 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8387 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8388 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8389 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8390 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8392 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8393 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8394 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
8395 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8396 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8397 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8398 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
8399 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8400 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8401 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8402 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8404 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8405 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8406 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
8407 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8408 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8409 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8410 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8411 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8412 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8414 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8415 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8416 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8417 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
8418 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8419 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8420 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8421 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8422 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8423 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8424 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8425 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8426 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8427 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8428 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
8429 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8430 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8431 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8432 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8433 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8434 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8435 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8436 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8437 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8438 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8439 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8440 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
8441 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8442 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8444 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8445 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8446 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8447 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8448 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8449 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
8450 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8451 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8452 ALC883_FUJITSU_PI2515),
8453 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8454 ALC888_FUJITSU_XA3530),
8455 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8456 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8457 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8458 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8459 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8460 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8461 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8462 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8463 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8465 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8466 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8467 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8468 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8469 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8474 /* codec SSID table for Intel Mac */
8475 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8476 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8477 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8478 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8479 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8480 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8481 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8482 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8483 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8484 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8485 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8486 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8487 /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8488 * no perfect solution yet
8490 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8494 static struct alc_config_preset alc882_presets[] = {
8495 [ALC882_3ST_DIG] = {
8496 .mixers = { alc882_base_mixer },
8497 .init_verbs = { alc882_base_init_verbs,
8498 alc882_adc1_init_verbs },
8499 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8500 .dac_nids = alc882_dac_nids,
8501 .dig_out_nid = ALC882_DIGOUT_NID,
8502 .dig_in_nid = ALC882_DIGIN_NID,
8503 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8504 .channel_mode = alc882_ch_modes,
8506 .input_mux = &alc882_capture_source,
8508 [ALC882_6ST_DIG] = {
8509 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8510 .init_verbs = { alc882_base_init_verbs,
8511 alc882_adc1_init_verbs },
8512 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8513 .dac_nids = alc882_dac_nids,
8514 .dig_out_nid = ALC882_DIGOUT_NID,
8515 .dig_in_nid = ALC882_DIGIN_NID,
8516 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8517 .channel_mode = alc882_sixstack_modes,
8518 .input_mux = &alc882_capture_source,
8521 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8522 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8523 alc882_eapd_verbs },
8524 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8525 .dac_nids = alc882_dac_nids,
8526 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8527 .channel_mode = alc882_sixstack_modes,
8528 .input_mux = &alc882_capture_source,
8531 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8532 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8533 alc882_eapd_verbs, alc880_gpio1_init_verbs },
8534 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8535 .dac_nids = alc882_dac_nids,
8536 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8537 .channel_mode = alc880_threestack_modes,
8539 .input_mux = &alc882_capture_source,
8540 .dig_out_nid = ALC882_DIGOUT_NID,
8543 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8544 .init_verbs = { alc885_mbp3_init_verbs,
8545 alc880_gpio1_init_verbs },
8546 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8547 .dac_nids = alc882_dac_nids,
8548 .channel_mode = alc885_mbp_6ch_modes,
8549 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
8550 .input_mux = &alc882_capture_source,
8551 .dig_out_nid = ALC882_DIGOUT_NID,
8552 .dig_in_nid = ALC882_DIGIN_NID,
8553 .unsol_event = alc_automute_amp_unsol_event,
8554 .init_hook = alc885_mbp3_init_hook,
8557 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8558 .init_verbs = { alc885_mb5_init_verbs,
8559 alc880_gpio1_init_verbs },
8560 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8561 .dac_nids = alc882_dac_nids,
8562 .channel_mode = alc885_mb5_6ch_modes,
8563 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8564 .input_mux = &mb5_capture_source,
8565 .dig_out_nid = ALC882_DIGOUT_NID,
8566 .dig_in_nid = ALC882_DIGIN_NID,
8569 .mixers = { alc882_macpro_mixer },
8570 .init_verbs = { alc882_macpro_init_verbs },
8571 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8572 .dac_nids = alc882_dac_nids,
8573 .dig_out_nid = ALC882_DIGOUT_NID,
8574 .dig_in_nid = ALC882_DIGIN_NID,
8575 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8576 .channel_mode = alc882_ch_modes,
8577 .input_mux = &alc882_capture_source,
8578 .init_hook = alc885_macpro_init_hook,
8581 .mixers = { alc885_imac24_mixer },
8582 .init_verbs = { alc885_imac24_init_verbs },
8583 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8584 .dac_nids = alc882_dac_nids,
8585 .dig_out_nid = ALC882_DIGOUT_NID,
8586 .dig_in_nid = ALC882_DIGIN_NID,
8587 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8588 .channel_mode = alc882_ch_modes,
8589 .input_mux = &alc882_capture_source,
8590 .unsol_event = alc_automute_amp_unsol_event,
8591 .init_hook = alc885_imac24_init_hook,
8594 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8595 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8596 alc880_gpio3_init_verbs, alc882_targa_verbs},
8597 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8598 .dac_nids = alc882_dac_nids,
8599 .dig_out_nid = ALC882_DIGOUT_NID,
8600 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8601 .adc_nids = alc882_adc_nids,
8602 .capsrc_nids = alc882_capsrc_nids,
8603 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8604 .channel_mode = alc882_3ST_6ch_modes,
8606 .input_mux = &alc882_capture_source,
8607 .unsol_event = alc882_targa_unsol_event,
8608 .init_hook = alc882_targa_init_hook,
8610 [ALC882_ASUS_A7J] = {
8611 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8612 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8613 alc882_asus_a7j_verbs},
8614 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8615 .dac_nids = alc882_dac_nids,
8616 .dig_out_nid = ALC882_DIGOUT_NID,
8617 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8618 .adc_nids = alc882_adc_nids,
8619 .capsrc_nids = alc882_capsrc_nids,
8620 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8621 .channel_mode = alc882_3ST_6ch_modes,
8623 .input_mux = &alc882_capture_source,
8625 [ALC882_ASUS_A7M] = {
8626 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8627 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8628 alc882_eapd_verbs, alc880_gpio1_init_verbs,
8629 alc882_asus_a7m_verbs },
8630 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8631 .dac_nids = alc882_dac_nids,
8632 .dig_out_nid = ALC882_DIGOUT_NID,
8633 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8634 .channel_mode = alc880_threestack_modes,
8636 .input_mux = &alc882_capture_source,
8638 [ALC883_3ST_2ch_DIG] = {
8639 .mixers = { alc883_3ST_2ch_mixer },
8640 .init_verbs = { alc883_init_verbs },
8641 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8642 .dac_nids = alc883_dac_nids,
8643 .dig_out_nid = ALC883_DIGOUT_NID,
8644 .dig_in_nid = ALC883_DIGIN_NID,
8645 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8646 .channel_mode = alc883_3ST_2ch_modes,
8647 .input_mux = &alc883_capture_source,
8649 [ALC883_3ST_6ch_DIG] = {
8650 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8651 .init_verbs = { alc883_init_verbs },
8652 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8653 .dac_nids = alc883_dac_nids,
8654 .dig_out_nid = ALC883_DIGOUT_NID,
8655 .dig_in_nid = ALC883_DIGIN_NID,
8656 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8657 .channel_mode = alc883_3ST_6ch_modes,
8659 .input_mux = &alc883_capture_source,
8661 [ALC883_3ST_6ch] = {
8662 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8663 .init_verbs = { alc883_init_verbs },
8664 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8665 .dac_nids = alc883_dac_nids,
8666 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8667 .channel_mode = alc883_3ST_6ch_modes,
8669 .input_mux = &alc883_capture_source,
8671 [ALC883_3ST_6ch_INTEL] = {
8672 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8673 .init_verbs = { alc883_init_verbs },
8674 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8675 .dac_nids = alc883_dac_nids,
8676 .dig_out_nid = ALC883_DIGOUT_NID,
8677 .dig_in_nid = ALC883_DIGIN_NID,
8678 .slave_dig_outs = alc883_slave_dig_outs,
8679 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8680 .channel_mode = alc883_3ST_6ch_intel_modes,
8682 .input_mux = &alc883_3stack_6ch_intel,
8684 [ALC883_6ST_DIG] = {
8685 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8686 .init_verbs = { alc883_init_verbs },
8687 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8688 .dac_nids = alc883_dac_nids,
8689 .dig_out_nid = ALC883_DIGOUT_NID,
8690 .dig_in_nid = ALC883_DIGIN_NID,
8691 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8692 .channel_mode = alc883_sixstack_modes,
8693 .input_mux = &alc883_capture_source,
8695 [ALC883_TARGA_DIG] = {
8696 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
8697 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
8698 alc883_targa_verbs},
8699 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8700 .dac_nids = alc883_dac_nids,
8701 .dig_out_nid = ALC883_DIGOUT_NID,
8702 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8703 .channel_mode = alc883_3ST_6ch_modes,
8705 .input_mux = &alc883_capture_source,
8706 .unsol_event = alc883_targa_unsol_event,
8707 .init_hook = alc883_targa_init_hook,
8709 [ALC883_TARGA_2ch_DIG] = {
8710 .mixers = { alc883_targa_2ch_mixer},
8711 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
8712 alc883_targa_verbs},
8713 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8714 .dac_nids = alc883_dac_nids,
8715 .adc_nids = alc883_adc_nids_alt,
8716 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8717 .dig_out_nid = ALC883_DIGOUT_NID,
8718 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8719 .channel_mode = alc883_3ST_2ch_modes,
8720 .input_mux = &alc883_capture_source,
8721 .unsol_event = alc883_targa_unsol_event,
8722 .init_hook = alc883_targa_init_hook,
8724 [ALC883_TARGA_8ch_DIG] = {
8725 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8726 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
8727 alc883_targa_verbs },
8728 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8729 .dac_nids = alc883_dac_nids,
8730 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8731 .adc_nids = alc883_adc_nids_rev,
8732 .capsrc_nids = alc883_capsrc_nids_rev,
8733 .dig_out_nid = ALC883_DIGOUT_NID,
8734 .dig_in_nid = ALC883_DIGIN_NID,
8735 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
8736 .channel_mode = alc883_4ST_8ch_modes,
8738 .input_mux = &alc883_capture_source,
8739 .unsol_event = alc883_targa_unsol_event,
8740 .init_hook = alc883_targa_init_hook,
8743 .mixers = { alc883_base_mixer },
8744 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8745 * and the headphone jack. Turn this on and rely on the
8746 * standard mute methods whenever the user wants to turn
8747 * these outputs off.
8749 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8750 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8751 .dac_nids = alc883_dac_nids,
8752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8753 .channel_mode = alc883_3ST_2ch_modes,
8754 .input_mux = &alc883_capture_source,
8756 [ALC883_ACER_ASPIRE] = {
8757 .mixers = { alc883_acer_aspire_mixer },
8758 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8760 .dac_nids = alc883_dac_nids,
8761 .dig_out_nid = ALC883_DIGOUT_NID,
8762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8763 .channel_mode = alc883_3ST_2ch_modes,
8764 .input_mux = &alc883_capture_source,
8765 .unsol_event = alc_automute_amp_unsol_event,
8766 .init_hook = alc883_acer_aspire_init_hook,
8768 [ALC888_ACER_ASPIRE_4930G] = {
8769 .mixers = { alc888_base_mixer,
8770 alc883_chmode_mixer },
8771 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8772 alc888_acer_aspire_4930g_verbs },
8773 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8774 .dac_nids = alc883_dac_nids,
8775 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8776 .adc_nids = alc883_adc_nids_rev,
8777 .capsrc_nids = alc883_capsrc_nids_rev,
8778 .dig_out_nid = ALC883_DIGOUT_NID,
8779 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8780 .channel_mode = alc883_3ST_6ch_modes,
8783 ARRAY_SIZE(alc888_2_capture_sources),
8784 .input_mux = alc888_2_capture_sources,
8785 .unsol_event = alc_automute_amp_unsol_event,
8786 .init_hook = alc888_acer_aspire_4930g_init_hook,
8788 [ALC888_ACER_ASPIRE_6530G] = {
8789 .mixers = { alc888_acer_aspire_6530_mixer },
8790 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8791 alc888_acer_aspire_6530g_verbs },
8792 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8793 .dac_nids = alc883_dac_nids,
8794 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8795 .adc_nids = alc883_adc_nids_rev,
8796 .capsrc_nids = alc883_capsrc_nids_rev,
8797 .dig_out_nid = ALC883_DIGOUT_NID,
8798 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8799 .channel_mode = alc883_3ST_2ch_modes,
8801 ARRAY_SIZE(alc888_2_capture_sources),
8802 .input_mux = alc888_acer_aspire_6530_sources,
8803 .unsol_event = alc_automute_amp_unsol_event,
8804 .init_hook = alc888_acer_aspire_6530g_init_hook,
8806 [ALC888_ACER_ASPIRE_8930G] = {
8807 .mixers = { alc888_base_mixer,
8808 alc883_chmode_mixer },
8809 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8810 alc889_acer_aspire_8930g_verbs },
8811 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8812 .dac_nids = alc883_dac_nids,
8813 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
8814 .adc_nids = alc889_adc_nids,
8815 .capsrc_nids = alc889_capsrc_nids,
8816 .dig_out_nid = ALC883_DIGOUT_NID,
8817 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8818 .channel_mode = alc883_3ST_6ch_modes,
8820 .const_channel_count = 6,
8822 ARRAY_SIZE(alc889_capture_sources),
8823 .input_mux = alc889_capture_sources,
8824 .unsol_event = alc_automute_amp_unsol_event,
8825 .init_hook = alc889_acer_aspire_8930g_init_hook,
8828 .mixers = { alc883_fivestack_mixer,
8829 alc883_chmode_mixer },
8830 .init_verbs = { alc883_init_verbs,
8831 alc883_medion_eapd_verbs },
8832 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8833 .dac_nids = alc883_dac_nids,
8834 .adc_nids = alc883_adc_nids_alt,
8835 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8836 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8837 .channel_mode = alc883_sixstack_modes,
8838 .input_mux = &alc883_capture_source,
8840 [ALC883_MEDION_MD2] = {
8841 .mixers = { alc883_medion_md2_mixer},
8842 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8843 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8844 .dac_nids = alc883_dac_nids,
8845 .dig_out_nid = ALC883_DIGOUT_NID,
8846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8847 .channel_mode = alc883_3ST_2ch_modes,
8848 .input_mux = &alc883_capture_source,
8849 .unsol_event = alc_automute_amp_unsol_event,
8850 .init_hook = alc883_medion_md2_init_hook,
8852 [ALC883_LAPTOP_EAPD] = {
8853 .mixers = { alc883_base_mixer },
8854 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8855 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8856 .dac_nids = alc883_dac_nids,
8857 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8858 .channel_mode = alc883_3ST_2ch_modes,
8859 .input_mux = &alc883_capture_source,
8861 [ALC883_CLEVO_M720] = {
8862 .mixers = { alc883_clevo_m720_mixer },
8863 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8864 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8865 .dac_nids = alc883_dac_nids,
8866 .dig_out_nid = ALC883_DIGOUT_NID,
8867 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8868 .channel_mode = alc883_3ST_2ch_modes,
8869 .input_mux = &alc883_capture_source,
8870 .unsol_event = alc883_clevo_m720_unsol_event,
8871 .init_hook = alc883_clevo_m720_init_hook,
8873 [ALC883_LENOVO_101E_2ch] = {
8874 .mixers = { alc883_lenovo_101e_2ch_mixer},
8875 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8876 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8877 .dac_nids = alc883_dac_nids,
8878 .adc_nids = alc883_adc_nids_alt,
8879 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8880 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8881 .channel_mode = alc883_3ST_2ch_modes,
8882 .input_mux = &alc883_lenovo_101e_capture_source,
8883 .unsol_event = alc883_lenovo_101e_unsol_event,
8884 .init_hook = alc883_lenovo_101e_all_automute,
8886 [ALC883_LENOVO_NB0763] = {
8887 .mixers = { alc883_lenovo_nb0763_mixer },
8888 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8889 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8890 .dac_nids = alc883_dac_nids,
8891 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8892 .channel_mode = alc883_3ST_2ch_modes,
8894 .input_mux = &alc883_lenovo_nb0763_capture_source,
8895 .unsol_event = alc_automute_amp_unsol_event,
8896 .init_hook = alc883_medion_md2_init_hook,
8898 [ALC888_LENOVO_MS7195_DIG] = {
8899 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8900 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8901 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8902 .dac_nids = alc883_dac_nids,
8903 .dig_out_nid = ALC883_DIGOUT_NID,
8904 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8905 .channel_mode = alc883_3ST_6ch_modes,
8907 .input_mux = &alc883_capture_source,
8908 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8909 .init_hook = alc888_lenovo_ms7195_front_automute,
8911 [ALC883_HAIER_W66] = {
8912 .mixers = { alc883_targa_2ch_mixer},
8913 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8914 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8915 .dac_nids = alc883_dac_nids,
8916 .dig_out_nid = ALC883_DIGOUT_NID,
8917 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8918 .channel_mode = alc883_3ST_2ch_modes,
8919 .input_mux = &alc883_capture_source,
8920 .unsol_event = alc_automute_amp_unsol_event,
8921 .init_hook = alc883_haier_w66_init_hook,
8924 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8925 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8926 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8927 .dac_nids = alc883_dac_nids,
8928 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8929 .channel_mode = alc888_3st_hp_modes,
8931 .input_mux = &alc883_capture_source,
8932 .unsol_event = alc_automute_amp_unsol_event,
8933 .init_hook = alc888_3st_hp_init_hook,
8935 [ALC888_6ST_DELL] = {
8936 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8937 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8938 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8939 .dac_nids = alc883_dac_nids,
8940 .dig_out_nid = ALC883_DIGOUT_NID,
8941 .dig_in_nid = ALC883_DIGIN_NID,
8942 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8943 .channel_mode = alc883_sixstack_modes,
8944 .input_mux = &alc883_capture_source,
8945 .unsol_event = alc_automute_amp_unsol_event,
8946 .init_hook = alc888_6st_dell_init_hook,
8949 .mixers = { alc883_mitac_mixer },
8950 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8951 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8952 .dac_nids = alc883_dac_nids,
8953 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8954 .channel_mode = alc883_3ST_2ch_modes,
8955 .input_mux = &alc883_capture_source,
8956 .unsol_event = alc_automute_amp_unsol_event,
8957 .init_hook = alc883_mitac_init_hook,
8959 [ALC883_FUJITSU_PI2515] = {
8960 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8961 .init_verbs = { alc883_init_verbs,
8962 alc883_2ch_fujitsu_pi2515_verbs},
8963 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8964 .dac_nids = alc883_dac_nids,
8965 .dig_out_nid = ALC883_DIGOUT_NID,
8966 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8967 .channel_mode = alc883_3ST_2ch_modes,
8968 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8969 .unsol_event = alc_automute_amp_unsol_event,
8970 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
8972 [ALC888_FUJITSU_XA3530] = {
8973 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8974 .init_verbs = { alc883_init_verbs,
8975 alc888_fujitsu_xa3530_verbs },
8976 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8977 .dac_nids = alc883_dac_nids,
8978 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8979 .adc_nids = alc883_adc_nids_rev,
8980 .capsrc_nids = alc883_capsrc_nids_rev,
8981 .dig_out_nid = ALC883_DIGOUT_NID,
8982 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8983 .channel_mode = alc888_4ST_8ch_intel_modes,
8985 ARRAY_SIZE(alc888_2_capture_sources),
8986 .input_mux = alc888_2_capture_sources,
8987 .unsol_event = alc_automute_amp_unsol_event,
8988 .init_hook = alc888_fujitsu_xa3530_init_hook,
8990 [ALC888_LENOVO_SKY] = {
8991 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8992 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8993 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8994 .dac_nids = alc883_dac_nids,
8995 .dig_out_nid = ALC883_DIGOUT_NID,
8996 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8997 .channel_mode = alc883_sixstack_modes,
8999 .input_mux = &alc883_lenovo_sky_capture_source,
9000 .unsol_event = alc_automute_amp_unsol_event,
9001 .init_hook = alc888_lenovo_sky_init_hook,
9003 [ALC888_ASUS_M90V] = {
9004 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9005 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9006 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9007 .dac_nids = alc883_dac_nids,
9008 .dig_out_nid = ALC883_DIGOUT_NID,
9009 .dig_in_nid = ALC883_DIGIN_NID,
9010 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9011 .channel_mode = alc883_3ST_6ch_modes,
9013 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9014 .unsol_event = alc883_mode2_unsol_event,
9015 .init_hook = alc883_mode2_inithook,
9017 [ALC888_ASUS_EEE1601] = {
9018 .mixers = { alc883_asus_eee1601_mixer },
9019 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9020 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9021 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9022 .dac_nids = alc883_dac_nids,
9023 .dig_out_nid = ALC883_DIGOUT_NID,
9024 .dig_in_nid = ALC883_DIGIN_NID,
9025 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9026 .channel_mode = alc883_3ST_2ch_modes,
9028 .input_mux = &alc883_asus_eee1601_capture_source,
9029 .unsol_event = alc_sku_unsol_event,
9030 .init_hook = alc883_eee1601_inithook,
9032 [ALC1200_ASUS_P5Q] = {
9033 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9034 .init_verbs = { alc883_init_verbs },
9035 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9036 .dac_nids = alc883_dac_nids,
9037 .dig_out_nid = ALC1200_DIGOUT_NID,
9038 .dig_in_nid = ALC883_DIGIN_NID,
9039 .slave_dig_outs = alc1200_slave_dig_outs,
9040 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9041 .channel_mode = alc883_sixstack_modes,
9042 .input_mux = &alc883_capture_source,
9045 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9046 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9047 alc880_gpio1_init_verbs },
9048 .adc_nids = alc883_adc_nids,
9049 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9050 .dac_nids = alc883_dac_nids,
9051 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9052 .channel_mode = alc889A_mb31_6ch_modes,
9053 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9054 .input_mux = &alc889A_mb31_capture_source,
9055 .dig_out_nid = ALC883_DIGOUT_NID,
9056 .unsol_event = alc889A_mb31_unsol_event,
9057 .init_hook = alc889A_mb31_automute,
9059 [ALC883_SONY_VAIO_TT] = {
9060 .mixers = { alc883_vaiott_mixer },
9061 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9062 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9063 .dac_nids = alc883_dac_nids,
9064 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9065 .channel_mode = alc883_3ST_2ch_modes,
9066 .input_mux = &alc883_capture_source,
9067 .unsol_event = alc_automute_amp_unsol_event,
9068 .init_hook = alc883_vaiott_init_hook,
9077 PINFIX_ABIT_AW9D_MAX
9080 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9081 { 0x15, 0x01080104 }, /* side */
9082 { 0x16, 0x01011012 }, /* rear */
9083 { 0x17, 0x01016011 }, /* clfe */
9087 static const struct alc_pincfg *alc882_pin_fixes[] = {
9088 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9091 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9092 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9097 * BIOS auto configuration
9099 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9100 hda_nid_t nid, int pin_type,
9104 struct alc_spec *spec = codec->spec;
9107 alc_set_pin_output(codec, nid, pin_type);
9108 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9111 idx = spec->multiout.dac_nids[dac_idx] - 2;
9112 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9116 static void alc882_auto_init_multi_out(struct hda_codec *codec)
9118 struct alc_spec *spec = codec->spec;
9121 for (i = 0; i <= HDA_SIDE; i++) {
9122 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9123 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9125 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9130 static void alc882_auto_init_hp_out(struct hda_codec *codec)
9132 struct alc_spec *spec = codec->spec;
9135 pin = spec->autocfg.hp_pins[0];
9136 if (pin) /* connect to front */
9138 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9139 pin = spec->autocfg.speaker_pins[0];
9141 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9144 static void alc882_auto_init_analog_input(struct hda_codec *codec)
9146 struct alc_spec *spec = codec->spec;
9149 for (i = 0; i < AUTO_PIN_LAST; i++) {
9150 hda_nid_t nid = spec->autocfg.input_pins[i];
9153 alc_set_input_pin(codec, nid, i);
9154 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9155 snd_hda_codec_write(codec, nid, 0,
9156 AC_VERB_SET_AMP_GAIN_MUTE,
9161 static void alc882_auto_init_input_src(struct hda_codec *codec)
9163 struct alc_spec *spec = codec->spec;
9166 for (c = 0; c < spec->num_adc_nids; c++) {
9167 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9168 hda_nid_t nid = spec->capsrc_nids[c];
9169 unsigned int mux_idx;
9170 const struct hda_input_mux *imux;
9171 int conns, mute, idx, item;
9173 conns = snd_hda_get_connections(codec, nid, conn_list,
9174 ARRAY_SIZE(conn_list));
9177 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9178 imux = &spec->input_mux[mux_idx];
9179 for (idx = 0; idx < conns; idx++) {
9180 /* if the current connection is the selected one,
9181 * unmute it as default - otherwise mute it
9183 mute = AMP_IN_MUTE(idx);
9184 for (item = 0; item < imux->num_items; item++) {
9185 if (imux->items[item].index == idx) {
9186 if (spec->cur_mux[c] == item)
9187 mute = AMP_IN_UNMUTE(idx);
9191 /* check if we have a selector or mixer
9192 * we could check for the widget type instead, but
9193 * just check for Amp-In presence (in case of mixer
9194 * without amp-in there is something wrong, this
9195 * function shouldn't be used or capsrc nid is wrong)
9197 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9198 snd_hda_codec_write(codec, nid, 0,
9199 AC_VERB_SET_AMP_GAIN_MUTE,
9201 else if (mute != AMP_IN_MUTE(idx))
9202 snd_hda_codec_write(codec, nid, 0,
9203 AC_VERB_SET_CONNECT_SEL,
9209 /* add mic boosts if needed */
9210 static int alc_auto_add_mic_boost(struct hda_codec *codec)
9212 struct alc_spec *spec = codec->spec;
9216 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9217 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9218 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9220 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9224 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9225 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9226 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9228 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9235 /* almost identical with ALC880 parser... */
9236 static int alc882_parse_auto_config(struct hda_codec *codec)
9238 struct alc_spec *spec = codec->spec;
9239 struct auto_pin_cfg *autocfg = &spec->autocfg;
9242 int err = alc880_parse_auto_config(codec);
9247 return 0; /* no config found */
9249 err = alc_auto_add_mic_boost(codec);
9253 /* hack - override the init verbs */
9254 spec->init_verbs[0] = alc883_auto_init_verbs;
9255 /* if ADC 0x07 is available, initialize it, too */
9256 wcap = get_wcaps(codec, 0x07);
9257 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9258 if (wcap == AC_WID_AUD_IN)
9259 add_verb(spec, alc882_adc1_init_verbs);
9261 /* digital-mic input pin is excluded in alc880_auto_create..()
9262 * because it's under 0x18
9264 if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9265 autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9266 struct hda_input_mux *imux = &spec->private_imux[0];
9267 for (i = 1; i < 3; i++)
9268 memcpy(&spec->private_imux[i],
9269 &spec->private_imux[0],
9270 sizeof(spec->private_imux[0]));
9271 imux->items[imux->num_items].label = "Int DMic";
9272 imux->items[imux->num_items].index = 0x0b;
9274 spec->num_mux_defs = 3;
9275 spec->input_mux = spec->private_imux;
9278 return 1; /* config found */
9281 /* additional initialization for auto-configuration model */
9282 static void alc882_auto_init(struct hda_codec *codec)
9284 struct alc_spec *spec = codec->spec;
9285 alc882_auto_init_multi_out(codec);
9286 alc882_auto_init_hp_out(codec);
9287 alc882_auto_init_analog_input(codec);
9288 alc882_auto_init_input_src(codec);
9289 if (spec->unsol_event)
9290 alc_inithook(codec);
9293 static int patch_alc882(struct hda_codec *codec)
9295 struct alc_spec *spec;
9296 int err, board_config;
9298 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9304 switch (codec->vendor_id) {
9309 /* ALC883 and variants */
9310 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9314 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9318 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9319 board_config = snd_hda_check_board_codec_sid_config(codec,
9320 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9322 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9323 printk(KERN_INFO "hda_codec: Unknown model for %s, "
9324 "trying auto-probe from BIOS...\n",
9326 board_config = ALC882_AUTO;
9329 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9331 if (board_config == ALC882_AUTO) {
9332 /* automatic parse from the BIOS config */
9333 err = alc882_parse_auto_config(codec);
9339 "hda_codec: Cannot set up configuration "
9340 "from BIOS. Using base mode...\n");
9341 board_config = ALC882_3ST_DIG;
9345 err = snd_hda_attach_beep_device(codec, 0x1);
9351 if (board_config != ALC882_AUTO)
9352 setup_preset(spec, &alc882_presets[board_config]);
9354 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9355 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9356 /* FIXME: setup DAC5 */
9357 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9358 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9360 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9361 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9363 if (codec->vendor_id == 0x10ec0888)
9364 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9366 if (!spec->adc_nids && spec->input_mux) {
9368 spec->num_adc_nids = 0;
9369 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9371 hda_nid_t nid = alc882_adc_nids[i];
9372 unsigned int wcap = get_wcaps(codec, nid);
9374 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9375 if (wcap != AC_WID_AUD_IN)
9377 spec->private_adc_nids[spec->num_adc_nids] = nid;
9378 err = snd_hda_get_connections(codec, nid, &cap, 1);
9381 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9382 spec->num_adc_nids++;
9384 spec->adc_nids = spec->private_adc_nids;
9385 spec->capsrc_nids = spec->private_capsrc_nids;
9388 set_capture_mixer(spec);
9389 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9391 spec->vmaster_nid = 0x0c;
9393 codec->patch_ops = alc_patch_ops;
9394 if (board_config == ALC882_AUTO)
9395 spec->init_hook = alc882_auto_init;
9396 #ifdef CONFIG_SND_HDA_POWER_SAVE
9397 if (!spec->loopback.amplist)
9398 spec->loopback.amplist = alc882_loopbacks;
9400 codec->proc_widget_hook = print_realtek_coef;
9410 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9411 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9413 #define alc262_dac_nids alc260_dac_nids
9414 #define alc262_adc_nids alc882_adc_nids
9415 #define alc262_adc_nids_alt alc882_adc_nids_alt
9416 #define alc262_capsrc_nids alc882_capsrc_nids
9417 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9419 #define alc262_modes alc260_modes
9420 #define alc262_capture_source alc882_capture_source
9422 static hda_nid_t alc262_dmic_adc_nids[1] = {
9427 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9429 static struct snd_kcontrol_new alc262_base_mixer[] = {
9430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9431 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9432 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9433 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9434 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9435 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9438 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9439 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9440 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9441 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9442 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9443 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9444 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9445 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9449 /* update HP, line and mono-out pins according to the master switch */
9450 static void alc262_hp_master_update(struct hda_codec *codec)
9452 struct alc_spec *spec = codec->spec;
9453 int val = spec->master_sw;
9456 snd_hda_codec_write_cache(codec, 0x1b, 0,
9457 AC_VERB_SET_PIN_WIDGET_CONTROL,
9459 snd_hda_codec_write_cache(codec, 0x15, 0,
9460 AC_VERB_SET_PIN_WIDGET_CONTROL,
9462 /* mono (speaker) depending on the HP jack sense */
9463 val = val && !spec->jack_present;
9464 snd_hda_codec_write_cache(codec, 0x16, 0,
9465 AC_VERB_SET_PIN_WIDGET_CONTROL,
9469 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9471 struct alc_spec *spec = codec->spec;
9472 unsigned int presence;
9473 presence = snd_hda_codec_read(codec, 0x1b, 0,
9474 AC_VERB_GET_PIN_SENSE, 0);
9475 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9476 alc262_hp_master_update(codec);
9479 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9481 if ((res >> 26) != ALC880_HP_EVENT)
9483 alc262_hp_bpc_automute(codec);
9486 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9488 struct alc_spec *spec = codec->spec;
9489 unsigned int presence;
9490 presence = snd_hda_codec_read(codec, 0x15, 0,
9491 AC_VERB_GET_PIN_SENSE, 0);
9492 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9493 alc262_hp_master_update(codec);
9496 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9499 if ((res >> 26) != ALC880_HP_EVENT)
9501 alc262_hp_wildwest_automute(codec);
9504 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9506 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9507 struct snd_ctl_elem_value *ucontrol)
9509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9510 struct alc_spec *spec = codec->spec;
9511 int val = !!*ucontrol->value.integer.value;
9513 if (val == spec->master_sw)
9515 spec->master_sw = val;
9516 alc262_hp_master_update(codec);
9520 #define ALC262_HP_MASTER_SWITCH \
9522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9523 .name = "Master Playback Switch", \
9524 .info = snd_ctl_boolean_mono_info, \
9525 .get = alc262_hp_master_sw_get, \
9526 .put = alc262_hp_master_sw_put, \
9529 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9530 ALC262_HP_MASTER_SWITCH,
9531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9532 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9533 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9534 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9536 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9538 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9539 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9540 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9541 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9542 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9543 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9544 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9545 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9548 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9549 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9553 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9554 ALC262_HP_MASTER_SWITCH,
9555 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9556 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9559 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9561 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9563 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9564 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9565 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9566 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9567 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9568 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9569 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9573 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9574 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9575 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9576 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9580 /* mute/unmute internal speaker according to the hp jack and mute state */
9581 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9583 struct alc_spec *spec = codec->spec;
9585 spec->autocfg.hp_pins[0] = 0x15;
9586 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9587 alc_automute_amp(codec);
9590 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9591 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9592 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9593 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9596 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9597 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9601 static struct hda_verb alc262_hp_t5735_verbs[] = {
9602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9605 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9609 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9610 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9612 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9613 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9614 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9615 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9619 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9620 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9621 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9622 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9623 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9624 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9625 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9627 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9629 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9633 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9640 /* bind hp and internal speaker mute (with plug check) as master switch */
9641 static void alc262_hippo_master_update(struct hda_codec *codec)
9643 struct alc_spec *spec = codec->spec;
9644 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9645 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9646 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9650 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9651 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9652 HDA_AMP_MUTE, mute);
9653 /* mute internal speaker per jack sense */
9654 if (spec->jack_present)
9655 mute = HDA_AMP_MUTE;
9657 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9658 HDA_AMP_MUTE, mute);
9659 if (speaker_nid && speaker_nid != line_nid)
9660 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9661 HDA_AMP_MUTE, mute);
9664 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9666 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9667 struct snd_ctl_elem_value *ucontrol)
9669 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9670 struct alc_spec *spec = codec->spec;
9671 int val = !!*ucontrol->value.integer.value;
9673 if (val == spec->master_sw)
9675 spec->master_sw = val;
9676 alc262_hippo_master_update(codec);
9680 #define ALC262_HIPPO_MASTER_SWITCH \
9682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9683 .name = "Master Playback Switch", \
9684 .info = snd_ctl_boolean_mono_info, \
9685 .get = alc262_hippo_master_sw_get, \
9686 .put = alc262_hippo_master_sw_put, \
9689 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9690 ALC262_HIPPO_MASTER_SWITCH,
9691 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9692 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9693 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9694 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9695 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9698 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9701 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9706 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9707 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9708 ALC262_HIPPO_MASTER_SWITCH,
9709 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9710 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9714 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9715 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9716 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9717 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9718 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9722 /* mute/unmute internal speaker according to the hp jack and mute state */
9723 static void alc262_hippo_automute(struct hda_codec *codec)
9725 struct alc_spec *spec = codec->spec;
9726 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9727 unsigned int present;
9729 /* need to execute and sync at first */
9730 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9731 present = snd_hda_codec_read(codec, hp_nid, 0,
9732 AC_VERB_GET_PIN_SENSE, 0);
9733 spec->jack_present = (present & 0x80000000) != 0;
9734 alc262_hippo_master_update(codec);
9737 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9739 if ((res >> 26) != ALC880_HP_EVENT)
9741 alc262_hippo_automute(codec);
9744 static void alc262_hippo_init_hook(struct hda_codec *codec)
9746 struct alc_spec *spec = codec->spec;
9748 spec->autocfg.hp_pins[0] = 0x15;
9749 spec->autocfg.speaker_pins[0] = 0x14;
9750 alc262_hippo_automute(codec);
9753 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9755 struct alc_spec *spec = codec->spec;
9757 spec->autocfg.hp_pins[0] = 0x1b;
9758 spec->autocfg.speaker_pins[0] = 0x14;
9759 alc262_hippo_automute(codec);
9763 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9764 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9765 ALC262_HIPPO_MASTER_SWITCH,
9766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9768 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9769 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9773 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9774 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9775 ALC262_HIPPO_MASTER_SWITCH,
9776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9778 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9779 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9780 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9784 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9785 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9786 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9787 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9788 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9789 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9790 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9794 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9795 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9796 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9800 static struct hda_verb alc262_tyan_verbs[] = {
9801 /* Headphone automute */
9802 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9803 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9806 /* P11 AUX_IN, white 4-pin connector */
9807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9808 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9809 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9810 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9815 /* unsolicited event for HP jack sensing */
9816 static void alc262_tyan_init_hook(struct hda_codec *codec)
9818 struct alc_spec *spec = codec->spec;
9820 spec->autocfg.hp_pins[0] = 0x1b;
9821 spec->autocfg.speaker_pins[0] = 0x15;
9822 alc_automute_amp(codec);
9826 #define alc262_capture_mixer alc882_capture_mixer
9827 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9830 * generic initialization of ADC, input mixers and output mixers
9832 static struct hda_verb alc262_init_verbs[] = {
9834 * Unmute ADC0-2 and set the default input to mic-in
9836 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9837 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9838 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9839 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9840 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9841 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9843 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9845 * Note: PASD motherboards uses the Line In 2 as the input for
9846 * front panel mic (mic 2)
9848 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9853 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9856 * Set up output mixers (0x0c - 0x0e)
9858 /* set vol=0 to output mixers */
9859 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9860 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9861 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9862 /* set up input amps for analog loopback */
9863 /* Amp Indices: DAC = 0, mixer = 1 */
9864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9869 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9873 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9881 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9882 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9884 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9885 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9887 /* FIXME: use matrix-type input source selection */
9888 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9889 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9890 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9891 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9895 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9896 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9897 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9898 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9900 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9901 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9902 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9903 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9908 static struct hda_verb alc262_eapd_verbs[] = {
9909 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9910 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9914 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9915 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9916 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9920 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9921 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9922 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9923 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9925 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9926 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9930 static struct hda_verb alc262_sony_unsol_verbs[] = {
9931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9933 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9935 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9940 static struct hda_input_mux alc262_dmic_capture_source = {
9943 { "Int DMic", 0x9 },
9948 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9950 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9957 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9958 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9960 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9961 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9962 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9963 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9964 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9965 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9969 static void alc262_dmic_automute(struct hda_codec *codec)
9971 unsigned int present;
9973 present = snd_hda_codec_read(codec, 0x18, 0,
9974 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9975 snd_hda_codec_write(codec, 0x22, 0,
9976 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9980 /* unsolicited event for HP jack sensing */
9981 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9984 if ((res >> 26) == ALC880_MIC_EVENT)
9985 alc262_dmic_automute(codec);
9987 alc_sku_unsol_event(codec, res);
9990 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9992 struct alc_spec *spec = codec->spec;
9994 spec->autocfg.hp_pins[0] = 0x15;
9995 spec->autocfg.speaker_pins[0] = 0x14;
9996 alc_automute_pin(codec);
9997 alc262_dmic_automute(codec);
10003 * 0x16 = internal speaker
10004 * 0x18 = external mic
10007 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10008 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10009 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10013 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10015 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10020 static struct hda_verb alc262_nec_verbs[] = {
10021 /* Unmute Speaker */
10022 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10025 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10028 /* External mic to headphone */
10029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10030 /* External mic to speaker */
10031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10037 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10038 * 0x1b = port replicator headphone out
10041 #define ALC_HP_EVENT 0x37
10043 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10045 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10051 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10052 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10053 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10057 static struct hda_input_mux alc262_fujitsu_capture_source = {
10061 { "Int Mic", 0x1 },
10066 static struct hda_input_mux alc262_HP_capture_source = {
10070 { "Front Mic", 0x1 },
10077 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10081 { "Front Mic", 0x2 },
10087 /* mute/unmute internal speaker according to the hp jacks and mute state */
10088 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10090 struct alc_spec *spec = codec->spec;
10093 if (force || !spec->sense_updated) {
10094 unsigned int present;
10095 /* need to execute and sync at first */
10096 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10097 /* check laptop HP jack */
10098 present = snd_hda_codec_read(codec, 0x14, 0,
10099 AC_VERB_GET_PIN_SENSE, 0);
10100 /* need to execute and sync at first */
10101 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10102 /* check docking HP jack */
10103 present |= snd_hda_codec_read(codec, 0x1b, 0,
10104 AC_VERB_GET_PIN_SENSE, 0);
10105 if (present & AC_PINSENSE_PRESENCE)
10106 spec->jack_present = 1;
10108 spec->jack_present = 0;
10109 spec->sense_updated = 1;
10111 /* unmute internal speaker only if both HPs are unplugged and
10112 * master switch is on
10114 if (spec->jack_present)
10115 mute = HDA_AMP_MUTE;
10117 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10118 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10119 HDA_AMP_MUTE, mute);
10122 /* unsolicited event for HP jack sensing */
10123 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10126 if ((res >> 26) != ALC_HP_EVENT)
10128 alc262_fujitsu_automute(codec, 1);
10131 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10133 alc262_fujitsu_automute(codec, 1);
10136 /* bind volumes of both NID 0x0c and 0x0d */
10137 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10138 .ops = &snd_hda_bind_vol,
10140 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10141 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10146 /* mute/unmute internal speaker according to the hp jack and mute state */
10147 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10149 struct alc_spec *spec = codec->spec;
10152 if (force || !spec->sense_updated) {
10153 unsigned int present_int_hp;
10154 /* need to execute and sync at first */
10155 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10156 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10157 AC_VERB_GET_PIN_SENSE, 0);
10158 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10159 spec->sense_updated = 1;
10161 if (spec->jack_present) {
10162 /* mute internal speaker */
10163 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10164 HDA_AMP_MUTE, HDA_AMP_MUTE);
10165 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10166 HDA_AMP_MUTE, HDA_AMP_MUTE);
10168 /* unmute internal speaker if necessary */
10169 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10170 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10171 HDA_AMP_MUTE, mute);
10172 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10173 HDA_AMP_MUTE, mute);
10177 /* unsolicited event for HP jack sensing */
10178 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10181 if ((res >> 26) != ALC_HP_EVENT)
10183 alc262_lenovo_3000_automute(codec, 1);
10186 /* bind hp and internal speaker mute (with plug check) */
10187 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10188 struct snd_ctl_elem_value *ucontrol)
10190 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10191 long *valp = ucontrol->value.integer.value;
10194 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10196 valp ? 0 : HDA_AMP_MUTE);
10197 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10199 valp ? 0 : HDA_AMP_MUTE);
10202 alc262_fujitsu_automute(codec, 0);
10206 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10207 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10210 .name = "Master Playback Switch",
10211 .info = snd_hda_mixer_amp_switch_info,
10212 .get = snd_hda_mixer_amp_switch_get,
10213 .put = alc262_fujitsu_master_sw_put,
10214 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10218 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10221 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10222 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10223 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10227 /* bind hp and internal speaker mute (with plug check) */
10228 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10229 struct snd_ctl_elem_value *ucontrol)
10231 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10232 long *valp = ucontrol->value.integer.value;
10235 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10237 valp ? 0 : HDA_AMP_MUTE);
10240 alc262_lenovo_3000_automute(codec, 0);
10244 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10245 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10248 .name = "Master Playback Switch",
10249 .info = snd_hda_mixer_amp_switch_info,
10250 .get = snd_hda_mixer_amp_switch_get,
10251 .put = alc262_lenovo_3000_master_sw_put,
10252 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10254 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10255 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10256 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10258 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10259 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10260 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10261 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10265 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10266 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10267 ALC262_HIPPO_MASTER_SWITCH,
10268 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10269 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10270 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10271 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10272 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10273 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10277 /* additional init verbs for Benq laptops */
10278 static struct hda_verb alc262_EAPD_verbs[] = {
10279 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10280 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10284 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10285 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10286 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10288 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10289 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10293 /* Samsung Q1 Ultra Vista model setup */
10294 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10295 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10296 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10298 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10299 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10300 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10304 static struct hda_verb alc262_ultra_verbs[] = {
10306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10308 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10311 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10312 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10313 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10315 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10317 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10322 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10323 /* ADC, choose mic */
10324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10331 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10332 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10333 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10337 /* mute/unmute internal speaker according to the hp jack and mute state */
10338 static void alc262_ultra_automute(struct hda_codec *codec)
10340 struct alc_spec *spec = codec->spec;
10344 /* auto-mute only when HP is used as HP */
10345 if (!spec->cur_mux[0]) {
10346 unsigned int present;
10347 /* need to execute and sync at first */
10348 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10349 present = snd_hda_codec_read(codec, 0x15, 0,
10350 AC_VERB_GET_PIN_SENSE, 0);
10351 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10352 if (spec->jack_present)
10353 mute = HDA_AMP_MUTE;
10355 /* mute/unmute internal speaker */
10356 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10357 HDA_AMP_MUTE, mute);
10358 /* mute/unmute HP */
10359 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10360 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10363 /* unsolicited event for HP jack sensing */
10364 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10367 if ((res >> 26) != ALC880_HP_EVENT)
10369 alc262_ultra_automute(codec);
10372 static struct hda_input_mux alc262_ultra_capture_source = {
10376 { "Headphone", 0x7 },
10380 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10381 struct snd_ctl_elem_value *ucontrol)
10383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10384 struct alc_spec *spec = codec->spec;
10387 ret = alc_mux_enum_put(kcontrol, ucontrol);
10390 /* reprogram the HP pin as mic or HP according to the input source */
10391 snd_hda_codec_write_cache(codec, 0x15, 0,
10392 AC_VERB_SET_PIN_WIDGET_CONTROL,
10393 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10394 alc262_ultra_automute(codec); /* mute/unmute HP */
10398 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10399 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10400 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10403 .name = "Capture Source",
10404 .info = alc_mux_enum_info,
10405 .get = alc_mux_enum_get,
10406 .put = alc262_ultra_mux_enum_put,
10411 /* add playback controls from the parsed DAC table */
10412 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10413 const struct auto_pin_cfg *cfg)
10418 spec->multiout.num_dacs = 1; /* only use one dac */
10419 spec->multiout.dac_nids = spec->private_dac_nids;
10420 spec->multiout.dac_nids[0] = 2;
10422 nid = cfg->line_out_pins[0];
10424 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10425 "Front Playback Volume",
10426 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10429 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10430 "Front Playback Switch",
10431 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10436 nid = cfg->speaker_pins[0];
10439 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10440 "Speaker Playback Volume",
10441 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10445 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10446 "Speaker Playback Switch",
10447 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10452 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10453 "Speaker Playback Switch",
10454 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10460 nid = cfg->hp_pins[0];
10462 /* spec->multiout.hp_nid = 2; */
10464 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10465 "Headphone Playback Volume",
10466 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10470 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10471 "Headphone Playback Switch",
10472 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10477 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10478 "Headphone Playback Switch",
10479 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10488 static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec,
10489 const struct auto_pin_cfg *cfg)
10493 err = alc880_auto_create_analog_input_ctls(spec, cfg);
10496 /* digital-mic input pin is excluded in alc880_auto_create..()
10497 * because it's under 0x18
10499 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
10500 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
10501 struct hda_input_mux *imux = &spec->private_imux[0];
10502 imux->items[imux->num_items].label = "Int Mic";
10503 imux->items[imux->num_items].index = 0x09;
10511 * generic initialization of ADC, input mixers and output mixers
10513 static struct hda_verb alc262_volume_init_verbs[] = {
10515 * Unmute ADC0-2 and set the default input to mic-in
10517 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10518 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10519 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10520 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10521 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10522 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10524 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10526 * Note: PASD motherboards uses the Line In 2 as the input for
10527 * front panel mic (mic 2)
10529 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10533 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10537 * Set up output mixers (0x0c - 0x0f)
10539 /* set vol=0 to output mixers */
10540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10541 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10542 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10544 /* set up input amps for analog loopback */
10545 /* Amp Indices: DAC = 0, mixer = 1 */
10546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10553 /* FIXME: use matrix-type input source selection */
10554 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10555 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10556 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10557 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10558 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10559 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10563 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10574 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10576 * Unmute ADC0-2 and set the default input to mic-in
10578 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10580 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10581 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10582 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10585 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10587 * Note: PASD motherboards uses the Line In 2 as the input for
10588 * front panel mic (mic 2)
10590 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10591 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10592 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10593 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10594 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10595 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10596 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10597 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10600 * Set up output mixers (0x0c - 0x0e)
10602 /* set vol=0 to output mixers */
10603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10604 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10607 /* set up input amps for analog loopback */
10608 /* Amp Indices: DAC = 0, mixer = 1 */
10609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10611 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10613 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10614 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10616 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10618 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10620 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10623 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10628 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10630 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10636 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10637 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10640 /* FIXME: use matrix-type input source selection */
10641 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10642 /* Input mixer1: only unmute Mic */
10643 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10644 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10645 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10651 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10669 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10673 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10678 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10680 * Unmute ADC0-2 and set the default input to mic-in
10682 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10684 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10685 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10686 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10687 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10689 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10691 * Note: PASD motherboards uses the Line In 2 as the input for front
10692 * panel mic (mic 2)
10694 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10699 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10701 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10702 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10704 * Set up output mixers (0x0c - 0x0e)
10706 /* set vol=0 to output mixers */
10707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10711 /* set up input amps for analog loopback */
10712 /* Amp Indices: DAC = 0, mixer = 1 */
10713 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10714 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10715 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10716 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10717 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10718 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10721 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10722 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10723 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10724 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10725 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10727 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10729 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10732 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10735 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10736 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10737 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10738 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10739 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10740 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10742 /* FIXME: use matrix-type input source selection */
10743 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10744 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10747 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10749 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10750 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10751 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10755 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10756 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10757 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10758 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10759 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10763 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10766 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10769 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10774 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10778 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10780 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10783 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10786 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10787 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10792 #ifdef CONFIG_SND_HDA_POWER_SAVE
10793 #define alc262_loopbacks alc880_loopbacks
10796 /* pcm configuration: identical with ALC880 */
10797 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10798 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10799 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10800 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10803 * BIOS auto configuration
10805 static int alc262_parse_auto_config(struct hda_codec *codec)
10807 struct alc_spec *spec = codec->spec;
10809 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10811 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10815 if (!spec->autocfg.line_outs) {
10816 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10817 spec->multiout.max_channels = 2;
10818 spec->no_analog = 1;
10821 return 0; /* can't find valid BIOS pin config */
10823 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10826 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10830 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10833 if (spec->autocfg.dig_outs) {
10834 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10835 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10837 if (spec->autocfg.dig_in_pin)
10838 spec->dig_in_nid = ALC262_DIGIN_NID;
10840 if (spec->kctls.list)
10841 add_mixer(spec, spec->kctls.list);
10843 add_verb(spec, alc262_volume_init_verbs);
10844 spec->num_mux_defs = 1;
10845 spec->input_mux = &spec->private_imux[0];
10847 err = alc_auto_add_mic_boost(codec);
10851 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10856 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10857 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10858 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10859 #define alc262_auto_init_input_src alc882_auto_init_input_src
10862 /* init callback for auto-configuration model -- overriding the default init */
10863 static void alc262_auto_init(struct hda_codec *codec)
10865 struct alc_spec *spec = codec->spec;
10866 alc262_auto_init_multi_out(codec);
10867 alc262_auto_init_hp_out(codec);
10868 alc262_auto_init_analog_input(codec);
10869 alc262_auto_init_input_src(codec);
10870 if (spec->unsol_event)
10871 alc_inithook(codec);
10875 * configuration and preset
10877 static const char *alc262_models[ALC262_MODEL_LAST] = {
10878 [ALC262_BASIC] = "basic",
10879 [ALC262_HIPPO] = "hippo",
10880 [ALC262_HIPPO_1] = "hippo_1",
10881 [ALC262_FUJITSU] = "fujitsu",
10882 [ALC262_HP_BPC] = "hp-bpc",
10883 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10884 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10885 [ALC262_HP_RP5700] = "hp-rp5700",
10886 [ALC262_BENQ_ED8] = "benq",
10887 [ALC262_BENQ_T31] = "benq-t31",
10888 [ALC262_SONY_ASSAMD] = "sony-assamd",
10889 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10890 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10891 [ALC262_ULTRA] = "ultra",
10892 [ALC262_LENOVO_3000] = "lenovo-3000",
10893 [ALC262_NEC] = "nec",
10894 [ALC262_TYAN] = "tyan",
10895 [ALC262_AUTO] = "auto",
10898 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10899 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10900 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10901 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10903 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10905 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10907 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10908 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10909 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10910 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10911 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10912 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10913 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10914 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10915 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10916 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10917 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10918 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10919 ALC262_HP_TC_T5735),
10920 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10921 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10922 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10923 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10924 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10925 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
10926 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10927 ALC262_SONY_ASSAMD),
10928 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10929 ALC262_TOSHIBA_RX1),
10930 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10931 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10932 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10933 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10934 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10936 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10937 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10938 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10939 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10940 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10944 static struct alc_config_preset alc262_presets[] = {
10946 .mixers = { alc262_base_mixer },
10947 .init_verbs = { alc262_init_verbs },
10948 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10949 .dac_nids = alc262_dac_nids,
10951 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10952 .channel_mode = alc262_modes,
10953 .input_mux = &alc262_capture_source,
10956 .mixers = { alc262_hippo_mixer },
10957 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10958 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10959 .dac_nids = alc262_dac_nids,
10961 .dig_out_nid = ALC262_DIGOUT_NID,
10962 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10963 .channel_mode = alc262_modes,
10964 .input_mux = &alc262_capture_source,
10965 .unsol_event = alc262_hippo_unsol_event,
10966 .init_hook = alc262_hippo_init_hook,
10968 [ALC262_HIPPO_1] = {
10969 .mixers = { alc262_hippo1_mixer },
10970 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10971 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10972 .dac_nids = alc262_dac_nids,
10974 .dig_out_nid = ALC262_DIGOUT_NID,
10975 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10976 .channel_mode = alc262_modes,
10977 .input_mux = &alc262_capture_source,
10978 .unsol_event = alc262_hippo_unsol_event,
10979 .init_hook = alc262_hippo1_init_hook,
10981 [ALC262_FUJITSU] = {
10982 .mixers = { alc262_fujitsu_mixer },
10983 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10984 alc262_fujitsu_unsol_verbs },
10985 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10986 .dac_nids = alc262_dac_nids,
10988 .dig_out_nid = ALC262_DIGOUT_NID,
10989 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10990 .channel_mode = alc262_modes,
10991 .input_mux = &alc262_fujitsu_capture_source,
10992 .unsol_event = alc262_fujitsu_unsol_event,
10993 .init_hook = alc262_fujitsu_init_hook,
10995 [ALC262_HP_BPC] = {
10996 .mixers = { alc262_HP_BPC_mixer },
10997 .init_verbs = { alc262_HP_BPC_init_verbs },
10998 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10999 .dac_nids = alc262_dac_nids,
11001 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11002 .channel_mode = alc262_modes,
11003 .input_mux = &alc262_HP_capture_source,
11004 .unsol_event = alc262_hp_bpc_unsol_event,
11005 .init_hook = alc262_hp_bpc_automute,
11007 [ALC262_HP_BPC_D7000_WF] = {
11008 .mixers = { alc262_HP_BPC_WildWest_mixer },
11009 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11010 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11011 .dac_nids = alc262_dac_nids,
11013 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11014 .channel_mode = alc262_modes,
11015 .input_mux = &alc262_HP_D7000_capture_source,
11016 .unsol_event = alc262_hp_wildwest_unsol_event,
11017 .init_hook = alc262_hp_wildwest_automute,
11019 [ALC262_HP_BPC_D7000_WL] = {
11020 .mixers = { alc262_HP_BPC_WildWest_mixer,
11021 alc262_HP_BPC_WildWest_option_mixer },
11022 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11023 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11024 .dac_nids = alc262_dac_nids,
11026 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11027 .channel_mode = alc262_modes,
11028 .input_mux = &alc262_HP_D7000_capture_source,
11029 .unsol_event = alc262_hp_wildwest_unsol_event,
11030 .init_hook = alc262_hp_wildwest_automute,
11032 [ALC262_HP_TC_T5735] = {
11033 .mixers = { alc262_hp_t5735_mixer },
11034 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11035 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11036 .dac_nids = alc262_dac_nids,
11038 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11039 .channel_mode = alc262_modes,
11040 .input_mux = &alc262_capture_source,
11041 .unsol_event = alc_automute_amp_unsol_event,
11042 .init_hook = alc262_hp_t5735_init_hook,
11044 [ALC262_HP_RP5700] = {
11045 .mixers = { alc262_hp_rp5700_mixer },
11046 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11047 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11048 .dac_nids = alc262_dac_nids,
11049 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11050 .channel_mode = alc262_modes,
11051 .input_mux = &alc262_hp_rp5700_capture_source,
11053 [ALC262_BENQ_ED8] = {
11054 .mixers = { alc262_base_mixer },
11055 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11056 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11057 .dac_nids = alc262_dac_nids,
11059 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11060 .channel_mode = alc262_modes,
11061 .input_mux = &alc262_capture_source,
11063 [ALC262_SONY_ASSAMD] = {
11064 .mixers = { alc262_sony_mixer },
11065 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11066 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11067 .dac_nids = alc262_dac_nids,
11069 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11070 .channel_mode = alc262_modes,
11071 .input_mux = &alc262_capture_source,
11072 .unsol_event = alc262_hippo_unsol_event,
11073 .init_hook = alc262_hippo_init_hook,
11075 [ALC262_BENQ_T31] = {
11076 .mixers = { alc262_benq_t31_mixer },
11077 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11078 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11079 .dac_nids = alc262_dac_nids,
11081 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11082 .channel_mode = alc262_modes,
11083 .input_mux = &alc262_capture_source,
11084 .unsol_event = alc262_hippo_unsol_event,
11085 .init_hook = alc262_hippo_init_hook,
11088 .mixers = { alc262_ultra_mixer },
11089 .cap_mixer = alc262_ultra_capture_mixer,
11090 .init_verbs = { alc262_ultra_verbs },
11091 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11092 .dac_nids = alc262_dac_nids,
11093 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11094 .channel_mode = alc262_modes,
11095 .input_mux = &alc262_ultra_capture_source,
11096 .adc_nids = alc262_adc_nids, /* ADC0 */
11097 .capsrc_nids = alc262_capsrc_nids,
11098 .num_adc_nids = 1, /* single ADC */
11099 .unsol_event = alc262_ultra_unsol_event,
11100 .init_hook = alc262_ultra_automute,
11102 [ALC262_LENOVO_3000] = {
11103 .mixers = { alc262_lenovo_3000_mixer },
11104 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11105 alc262_lenovo_3000_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_fujitsu_capture_source,
11113 .unsol_event = alc262_lenovo_3000_unsol_event,
11116 .mixers = { alc262_nec_mixer },
11117 .init_verbs = { alc262_nec_verbs },
11118 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11119 .dac_nids = alc262_dac_nids,
11121 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11122 .channel_mode = alc262_modes,
11123 .input_mux = &alc262_capture_source,
11125 [ALC262_TOSHIBA_S06] = {
11126 .mixers = { alc262_toshiba_s06_mixer },
11127 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11128 alc262_eapd_verbs },
11129 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11130 .capsrc_nids = alc262_dmic_capsrc_nids,
11131 .dac_nids = alc262_dac_nids,
11132 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11133 .num_adc_nids = 1, /* single ADC */
11134 .dig_out_nid = ALC262_DIGOUT_NID,
11135 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11136 .channel_mode = alc262_modes,
11137 .input_mux = &alc262_dmic_capture_source,
11138 .unsol_event = alc262_toshiba_s06_unsol_event,
11139 .init_hook = alc262_toshiba_s06_init_hook,
11141 [ALC262_TOSHIBA_RX1] = {
11142 .mixers = { alc262_toshiba_rx1_mixer },
11143 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11144 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11145 .dac_nids = alc262_dac_nids,
11147 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11148 .channel_mode = alc262_modes,
11149 .input_mux = &alc262_capture_source,
11150 .unsol_event = alc262_hippo_unsol_event,
11151 .init_hook = alc262_hippo_init_hook,
11154 .mixers = { alc262_tyan_mixer },
11155 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11156 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11157 .dac_nids = alc262_dac_nids,
11159 .dig_out_nid = ALC262_DIGOUT_NID,
11160 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11161 .channel_mode = alc262_modes,
11162 .input_mux = &alc262_capture_source,
11163 .unsol_event = alc_automute_amp_unsol_event,
11164 .init_hook = alc262_tyan_init_hook,
11168 static int patch_alc262(struct hda_codec *codec)
11170 struct alc_spec *spec;
11174 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11178 codec->spec = spec;
11180 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11185 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11186 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11187 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11188 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11192 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11194 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11198 if (board_config < 0) {
11199 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11200 "trying auto-probe from BIOS...\n", codec->chip_name);
11201 board_config = ALC262_AUTO;
11204 if (board_config == ALC262_AUTO) {
11205 /* automatic parse from the BIOS config */
11206 err = alc262_parse_auto_config(codec);
11212 "hda_codec: Cannot set up configuration "
11213 "from BIOS. Using base mode...\n");
11214 board_config = ALC262_BASIC;
11218 if (!spec->no_analog) {
11219 err = snd_hda_attach_beep_device(codec, 0x1);
11226 if (board_config != ALC262_AUTO)
11227 setup_preset(spec, &alc262_presets[board_config]);
11229 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11230 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11232 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11233 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11235 if (!spec->adc_nids && spec->input_mux) {
11237 /* check whether the digital-mic has to be supported */
11238 for (i = 0; i < spec->input_mux->num_items; i++) {
11239 if (spec->input_mux->items[i].index >= 9)
11242 if (i < spec->input_mux->num_items) {
11243 /* use only ADC0 */
11244 spec->adc_nids = alc262_dmic_adc_nids;
11245 spec->num_adc_nids = 1;
11246 spec->capsrc_nids = alc262_dmic_capsrc_nids;
11248 /* all analog inputs */
11249 /* check whether NID 0x07 is valid */
11250 unsigned int wcap = get_wcaps(codec, 0x07);
11253 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11254 if (wcap != AC_WID_AUD_IN) {
11255 spec->adc_nids = alc262_adc_nids_alt;
11256 spec->num_adc_nids =
11257 ARRAY_SIZE(alc262_adc_nids_alt);
11258 spec->capsrc_nids = alc262_capsrc_nids_alt;
11260 spec->adc_nids = alc262_adc_nids;
11261 spec->num_adc_nids =
11262 ARRAY_SIZE(alc262_adc_nids);
11263 spec->capsrc_nids = alc262_capsrc_nids;
11267 if (!spec->cap_mixer && !spec->no_analog)
11268 set_capture_mixer(spec);
11269 if (!spec->no_analog)
11270 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11272 spec->vmaster_nid = 0x0c;
11274 codec->patch_ops = alc_patch_ops;
11275 if (board_config == ALC262_AUTO)
11276 spec->init_hook = alc262_auto_init;
11277 #ifdef CONFIG_SND_HDA_POWER_SAVE
11278 if (!spec->loopback.amplist)
11279 spec->loopback.amplist = alc262_loopbacks;
11281 codec->proc_widget_hook = print_realtek_coef;
11287 * ALC268 channel source setting (2 channel)
11289 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11290 #define alc268_modes alc260_modes
11292 static hda_nid_t alc268_dac_nids[2] = {
11297 static hda_nid_t alc268_adc_nids[2] = {
11302 static hda_nid_t alc268_adc_nids_alt[1] = {
11307 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11309 static struct snd_kcontrol_new alc268_base_mixer[] = {
11310 /* output mixer control */
11311 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11312 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11313 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11315 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11316 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11317 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11321 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11322 /* output mixer control */
11323 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11325 ALC262_HIPPO_MASTER_SWITCH,
11326 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11327 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11328 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11332 /* bind Beep switches of both NID 0x0f and 0x10 */
11333 static struct hda_bind_ctls alc268_bind_beep_sw = {
11334 .ops = &snd_hda_bind_sw,
11336 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11337 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11342 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11343 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11344 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11348 static struct hda_verb alc268_eapd_verbs[] = {
11349 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11350 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11354 /* Toshiba specific */
11355 static struct hda_verb alc268_toshiba_verbs[] = {
11356 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11360 static struct hda_input_mux alc268_acer_lc_capture_source = {
11368 /* Acer specific */
11369 /* bind volumes of both NID 0x02 and 0x03 */
11370 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11371 .ops = &snd_hda_bind_vol,
11373 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11374 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11379 /* mute/unmute internal speaker according to the hp jack and mute state */
11380 static void alc268_acer_automute(struct hda_codec *codec, int force)
11382 struct alc_spec *spec = codec->spec;
11385 if (force || !spec->sense_updated) {
11386 unsigned int present;
11387 present = snd_hda_codec_read(codec, 0x14, 0,
11388 AC_VERB_GET_PIN_SENSE, 0);
11389 spec->jack_present = (present & 0x80000000) != 0;
11390 spec->sense_updated = 1;
11392 if (spec->jack_present)
11393 mute = HDA_AMP_MUTE; /* mute internal speaker */
11394 else /* unmute internal speaker if necessary */
11395 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11396 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11397 HDA_AMP_MUTE, mute);
11401 /* bind hp and internal speaker mute (with plug check) */
11402 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11403 struct snd_ctl_elem_value *ucontrol)
11405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11406 long *valp = ucontrol->value.integer.value;
11409 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11411 valp[0] ? 0 : HDA_AMP_MUTE);
11412 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11414 valp[1] ? 0 : HDA_AMP_MUTE);
11416 alc268_acer_automute(codec, 0);
11420 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11421 /* output mixer control */
11422 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11425 .name = "Master Playback Switch",
11426 .info = snd_hda_mixer_amp_switch_info,
11427 .get = snd_hda_mixer_amp_switch_get,
11428 .put = alc268_acer_master_sw_put,
11429 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11431 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11435 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11436 /* output mixer control */
11437 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11440 .name = "Master Playback Switch",
11441 .info = snd_hda_mixer_amp_switch_info,
11442 .get = snd_hda_mixer_amp_switch_get,
11443 .put = alc268_acer_master_sw_put,
11444 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11446 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11447 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11448 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11452 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11453 /* output mixer control */
11454 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11457 .name = "Master Playback Switch",
11458 .info = snd_hda_mixer_amp_switch_info,
11459 .get = snd_hda_mixer_amp_switch_get,
11460 .put = alc268_acer_master_sw_put,
11461 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11463 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11464 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11468 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11469 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11472 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11473 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11478 static struct hda_verb alc268_acer_verbs[] = {
11479 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11480 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11481 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11483 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11484 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11485 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11489 /* unsolicited event for HP jack sensing */
11490 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11491 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11493 static void alc268_acer_unsol_event(struct hda_codec *codec,
11496 if ((res >> 26) != ALC880_HP_EVENT)
11498 alc268_acer_automute(codec, 1);
11501 static void alc268_acer_init_hook(struct hda_codec *codec)
11503 alc268_acer_automute(codec, 1);
11506 /* toggle speaker-output according to the hp-jack state */
11507 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11509 unsigned int present;
11510 unsigned char bits;
11512 present = snd_hda_codec_read(codec, 0x15, 0,
11513 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11514 bits = present ? AMP_IN_MUTE(0) : 0;
11515 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11516 AMP_IN_MUTE(0), bits);
11517 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11518 AMP_IN_MUTE(0), bits);
11522 static void alc268_acer_mic_automute(struct hda_codec *codec)
11524 unsigned int present;
11526 present = snd_hda_codec_read(codec, 0x18, 0,
11527 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11528 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11529 present ? 0x0 : 0x6);
11532 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11535 if ((res >> 26) == ALC880_HP_EVENT)
11536 alc268_aspire_one_speaker_automute(codec);
11537 if ((res >> 26) == ALC880_MIC_EVENT)
11538 alc268_acer_mic_automute(codec);
11541 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11543 alc268_aspire_one_speaker_automute(codec);
11544 alc268_acer_mic_automute(codec);
11547 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11548 /* output mixer control */
11549 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11550 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11551 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11552 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11554 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11558 static struct hda_verb alc268_dell_verbs[] = {
11559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11560 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11561 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11565 /* mute/unmute internal speaker according to the hp jack and mute state */
11566 static void alc268_dell_init_hook(struct hda_codec *codec)
11568 struct alc_spec *spec = codec->spec;
11570 spec->autocfg.hp_pins[0] = 0x15;
11571 spec->autocfg.speaker_pins[0] = 0x14;
11572 alc_automute_pin(codec);
11575 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11576 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11577 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11578 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11580 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11581 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11582 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11587 static struct hda_verb alc267_quanta_il1_verbs[] = {
11588 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11593 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11595 unsigned int present;
11597 present = snd_hda_codec_read(codec, 0x18, 0,
11598 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11599 snd_hda_codec_write(codec, 0x23, 0,
11600 AC_VERB_SET_CONNECT_SEL,
11601 present ? 0x00 : 0x01);
11604 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11606 struct alc_spec *spec = codec->spec;
11608 spec->autocfg.hp_pins[0] = 0x15;
11609 spec->autocfg.speaker_pins[0] = 0x14;
11610 alc_automute_pin(codec);
11611 alc267_quanta_il1_mic_automute(codec);
11614 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11617 switch (res >> 26) {
11618 case ALC880_MIC_EVENT:
11619 alc267_quanta_il1_mic_automute(codec);
11622 alc_sku_unsol_event(codec, res);
11628 * generic initialization of ADC, input mixers and output mixers
11630 static struct hda_verb alc268_base_init_verbs[] = {
11631 /* Unmute DAC0-1 and set vol = 0 */
11632 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11633 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11636 * Set up output mixers (0x0c - 0x0e)
11638 /* set vol=0 to output mixers */
11639 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11640 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11643 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11647 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11648 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11649 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11650 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11651 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11652 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11654 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11656 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11657 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11658 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11660 /* set PCBEEP vol = 0, mute connections */
11661 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11662 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11663 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11665 /* Unmute Selector 23h,24h and set the default input to mic-in */
11667 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11669 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11676 * generic initialization of ADC, input mixers and output mixers
11678 static struct hda_verb alc268_volume_init_verbs[] = {
11679 /* set output DAC */
11680 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11681 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11683 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11684 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11685 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11686 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11687 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11690 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11691 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11696 /* set PCBEEP vol = 0, mute connections */
11697 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11698 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11699 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11704 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11705 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11706 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11708 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11709 /* The multiple "Capture Source" controls confuse alsamixer
11710 * So call somewhat different..
11712 /* .name = "Capture Source", */
11713 .name = "Input Source",
11715 .info = alc_mux_enum_info,
11716 .get = alc_mux_enum_get,
11717 .put = alc_mux_enum_put,
11722 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11723 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11724 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11725 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11726 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11729 /* The multiple "Capture Source" controls confuse alsamixer
11730 * So call somewhat different..
11732 /* .name = "Capture Source", */
11733 .name = "Input Source",
11735 .info = alc_mux_enum_info,
11736 .get = alc_mux_enum_get,
11737 .put = alc_mux_enum_put,
11742 static struct hda_input_mux alc268_capture_source = {
11746 { "Front Mic", 0x1 },
11752 static struct hda_input_mux alc268_acer_capture_source = {
11756 { "Internal Mic", 0x1 },
11761 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11765 { "Internal Mic", 0x6 },
11770 #ifdef CONFIG_SND_DEBUG
11771 static struct snd_kcontrol_new alc268_test_mixer[] = {
11772 /* Volume widgets */
11773 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11774 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11775 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11776 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11777 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11778 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11779 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11780 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11781 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11782 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11783 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11784 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11785 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11786 /* The below appears problematic on some hardwares */
11787 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11788 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11789 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11790 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11791 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11793 /* Modes for retasking pin widgets */
11794 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11795 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11796 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11797 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11799 /* Controls for GPIO pins, assuming they are configured as outputs */
11800 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11801 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11802 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11803 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11805 /* Switches to allow the digital SPDIF output pin to be enabled.
11806 * The ALC268 does not have an SPDIF input.
11808 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11810 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11811 * this output to turn on an external amplifier.
11813 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11814 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11820 /* create input playback/capture controls for the given pin */
11821 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11822 const char *ctlname, int idx)
11828 sprintf(name, "%s Playback Volume", ctlname);
11840 if (spec->multiout.dac_nids[0] != dac &&
11841 spec->multiout.dac_nids[1] != dac) {
11842 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11843 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
11847 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
11850 sprintf(name, "%s Playback Switch", ctlname);
11852 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11853 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11855 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11856 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
11862 /* add playback controls from the parsed DAC table */
11863 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11864 const struct auto_pin_cfg *cfg)
11869 spec->multiout.dac_nids = spec->private_dac_nids;
11871 nid = cfg->line_out_pins[0];
11874 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11878 err = alc268_new_analog_output(spec, nid, name, 0);
11883 nid = cfg->speaker_pins[0];
11885 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11886 "Speaker Playback Volume",
11887 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11891 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
11895 nid = cfg->hp_pins[0];
11897 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
11902 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11904 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11905 "Mono Playback Switch",
11906 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
11913 /* create playback/capture controls for input pins */
11914 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11915 const struct auto_pin_cfg *cfg)
11917 struct hda_input_mux *imux = &spec->private_imux[0];
11920 for (i = 0; i < AUTO_PIN_LAST; i++) {
11921 switch(cfg->input_pins[i]) {
11923 idx1 = 0; /* Mic 1 */
11926 idx1 = 1; /* Mic 2 */
11929 idx1 = 2; /* Line In */
11936 idx1 = 6; /* digital mics */
11941 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11942 imux->items[imux->num_items].index = idx1;
11948 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11950 struct alc_spec *spec = codec->spec;
11951 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11952 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11953 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11954 unsigned int dac_vol1, dac_vol2;
11957 snd_hda_codec_write(codec, speaker_nid, 0,
11958 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11959 snd_hda_codec_write(codec, 0x0f, 0,
11960 AC_VERB_SET_AMP_GAIN_MUTE,
11962 snd_hda_codec_write(codec, 0x10, 0,
11963 AC_VERB_SET_AMP_GAIN_MUTE,
11966 snd_hda_codec_write(codec, 0x0f, 0,
11967 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11968 snd_hda_codec_write(codec, 0x10, 0,
11969 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11972 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11973 if (line_nid == 0x14)
11974 dac_vol2 = AMP_OUT_ZERO;
11975 else if (line_nid == 0x15)
11976 dac_vol1 = AMP_OUT_ZERO;
11977 if (hp_nid == 0x14)
11978 dac_vol2 = AMP_OUT_ZERO;
11979 else if (hp_nid == 0x15)
11980 dac_vol1 = AMP_OUT_ZERO;
11981 if (line_nid != 0x16 || hp_nid != 0x16 ||
11982 spec->autocfg.line_out_pins[1] != 0x16 ||
11983 spec->autocfg.line_out_pins[2] != 0x16)
11984 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11986 snd_hda_codec_write(codec, 0x02, 0,
11987 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11988 snd_hda_codec_write(codec, 0x03, 0,
11989 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11992 /* pcm configuration: identical with ALC880 */
11993 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11994 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11995 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11996 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11999 * BIOS auto configuration
12001 static int alc268_parse_auto_config(struct hda_codec *codec)
12003 struct alc_spec *spec = codec->spec;
12005 static hda_nid_t alc268_ignore[] = { 0 };
12007 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12011 if (!spec->autocfg.line_outs) {
12012 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12013 spec->multiout.max_channels = 2;
12014 spec->no_analog = 1;
12017 return 0; /* can't find valid BIOS pin config */
12019 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12022 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
12026 spec->multiout.max_channels = 2;
12029 /* digital only support output */
12030 if (spec->autocfg.dig_outs) {
12031 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12032 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12034 if (spec->kctls.list)
12035 add_mixer(spec, spec->kctls.list);
12037 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12038 add_mixer(spec, alc268_beep_mixer);
12040 add_verb(spec, alc268_volume_init_verbs);
12041 spec->num_mux_defs = 1;
12042 spec->input_mux = &spec->private_imux[0];
12044 err = alc_auto_add_mic_boost(codec);
12048 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12053 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12054 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12055 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12057 /* init callback for auto-configuration model -- overriding the default init */
12058 static void alc268_auto_init(struct hda_codec *codec)
12060 struct alc_spec *spec = codec->spec;
12061 alc268_auto_init_multi_out(codec);
12062 alc268_auto_init_hp_out(codec);
12063 alc268_auto_init_mono_speaker_out(codec);
12064 alc268_auto_init_analog_input(codec);
12065 if (spec->unsol_event)
12066 alc_inithook(codec);
12070 * configuration and preset
12072 static const char *alc268_models[ALC268_MODEL_LAST] = {
12073 [ALC267_QUANTA_IL1] = "quanta-il1",
12074 [ALC268_3ST] = "3stack",
12075 [ALC268_TOSHIBA] = "toshiba",
12076 [ALC268_ACER] = "acer",
12077 [ALC268_ACER_DMIC] = "acer-dmic",
12078 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12079 [ALC268_DELL] = "dell",
12080 [ALC268_ZEPTO] = "zepto",
12081 #ifdef CONFIG_SND_DEBUG
12082 [ALC268_TEST] = "test",
12084 [ALC268_AUTO] = "auto",
12087 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12088 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12089 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12090 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12091 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12092 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12093 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12094 ALC268_ACER_ASPIRE_ONE),
12095 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12096 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12097 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12099 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12100 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12101 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12103 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12104 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12105 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12106 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12110 static struct alc_config_preset alc268_presets[] = {
12111 [ALC267_QUANTA_IL1] = {
12112 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12113 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12114 alc267_quanta_il1_verbs },
12115 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12116 .dac_nids = alc268_dac_nids,
12117 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12118 .adc_nids = alc268_adc_nids_alt,
12120 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12121 .channel_mode = alc268_modes,
12122 .input_mux = &alc268_capture_source,
12123 .unsol_event = alc267_quanta_il1_unsol_event,
12124 .init_hook = alc267_quanta_il1_init_hook,
12127 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12128 alc268_beep_mixer },
12129 .init_verbs = { alc268_base_init_verbs },
12130 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12131 .dac_nids = alc268_dac_nids,
12132 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12133 .adc_nids = alc268_adc_nids_alt,
12134 .capsrc_nids = alc268_capsrc_nids,
12136 .dig_out_nid = ALC268_DIGOUT_NID,
12137 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12138 .channel_mode = alc268_modes,
12139 .input_mux = &alc268_capture_source,
12141 [ALC268_TOSHIBA] = {
12142 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12143 alc268_beep_mixer },
12144 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12145 alc268_toshiba_verbs },
12146 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12147 .dac_nids = alc268_dac_nids,
12148 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12149 .adc_nids = alc268_adc_nids_alt,
12150 .capsrc_nids = alc268_capsrc_nids,
12152 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12153 .channel_mode = alc268_modes,
12154 .input_mux = &alc268_capture_source,
12155 .unsol_event = alc268_toshiba_unsol_event,
12156 .init_hook = alc268_toshiba_init_hook,
12159 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12160 alc268_beep_mixer },
12161 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12162 alc268_acer_verbs },
12163 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12164 .dac_nids = alc268_dac_nids,
12165 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12166 .adc_nids = alc268_adc_nids_alt,
12167 .capsrc_nids = alc268_capsrc_nids,
12169 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12170 .channel_mode = alc268_modes,
12171 .input_mux = &alc268_acer_capture_source,
12172 .unsol_event = alc268_acer_unsol_event,
12173 .init_hook = alc268_acer_init_hook,
12175 [ALC268_ACER_DMIC] = {
12176 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12177 alc268_beep_mixer },
12178 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12179 alc268_acer_verbs },
12180 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12181 .dac_nids = alc268_dac_nids,
12182 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12183 .adc_nids = alc268_adc_nids_alt,
12184 .capsrc_nids = alc268_capsrc_nids,
12186 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12187 .channel_mode = alc268_modes,
12188 .input_mux = &alc268_acer_dmic_capture_source,
12189 .unsol_event = alc268_acer_unsol_event,
12190 .init_hook = alc268_acer_init_hook,
12192 [ALC268_ACER_ASPIRE_ONE] = {
12193 .mixers = { alc268_acer_aspire_one_mixer,
12195 alc268_capture_alt_mixer },
12196 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12197 alc268_acer_aspire_one_verbs },
12198 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12199 .dac_nids = alc268_dac_nids,
12200 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12201 .adc_nids = alc268_adc_nids_alt,
12202 .capsrc_nids = alc268_capsrc_nids,
12204 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12205 .channel_mode = alc268_modes,
12206 .input_mux = &alc268_acer_lc_capture_source,
12207 .unsol_event = alc268_acer_lc_unsol_event,
12208 .init_hook = alc268_acer_lc_init_hook,
12211 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12212 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12213 alc268_dell_verbs },
12214 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12215 .dac_nids = alc268_dac_nids,
12217 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12218 .channel_mode = alc268_modes,
12219 .unsol_event = alc_sku_unsol_event,
12220 .init_hook = alc268_dell_init_hook,
12221 .input_mux = &alc268_capture_source,
12224 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12225 alc268_beep_mixer },
12226 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12227 alc268_toshiba_verbs },
12228 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12229 .dac_nids = alc268_dac_nids,
12230 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12231 .adc_nids = alc268_adc_nids_alt,
12232 .capsrc_nids = alc268_capsrc_nids,
12234 .dig_out_nid = ALC268_DIGOUT_NID,
12235 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12236 .channel_mode = alc268_modes,
12237 .input_mux = &alc268_capture_source,
12238 .unsol_event = alc268_toshiba_unsol_event,
12239 .init_hook = alc268_toshiba_init_hook
12241 #ifdef CONFIG_SND_DEBUG
12243 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12244 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12245 alc268_volume_init_verbs },
12246 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12247 .dac_nids = alc268_dac_nids,
12248 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12249 .adc_nids = alc268_adc_nids_alt,
12250 .capsrc_nids = alc268_capsrc_nids,
12252 .dig_out_nid = ALC268_DIGOUT_NID,
12253 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12254 .channel_mode = alc268_modes,
12255 .input_mux = &alc268_capture_source,
12260 static int patch_alc268(struct hda_codec *codec)
12262 struct alc_spec *spec;
12264 int i, has_beep, err;
12266 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12270 codec->spec = spec;
12272 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12276 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12277 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12278 "trying auto-probe from BIOS...\n", codec->chip_name);
12279 board_config = ALC268_AUTO;
12282 if (board_config == ALC268_AUTO) {
12283 /* automatic parse from the BIOS config */
12284 err = alc268_parse_auto_config(codec);
12290 "hda_codec: Cannot set up configuration "
12291 "from BIOS. Using base mode...\n");
12292 board_config = ALC268_3ST;
12296 if (board_config != ALC268_AUTO)
12297 setup_preset(spec, &alc268_presets[board_config]);
12299 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12300 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12301 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12303 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12306 for (i = 0; i < spec->num_mixers; i++) {
12307 if (spec->mixers[i] == alc268_beep_mixer) {
12314 err = snd_hda_attach_beep_device(codec, 0x1);
12319 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12320 /* override the amp caps for beep generator */
12321 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12322 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12323 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12324 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12325 (0 << AC_AMPCAP_MUTE_SHIFT));
12328 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12329 /* check whether NID 0x07 is valid */
12330 unsigned int wcap = get_wcaps(codec, 0x07);
12334 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12335 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12336 spec->adc_nids = alc268_adc_nids_alt;
12337 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12338 add_mixer(spec, alc268_capture_alt_mixer);
12340 spec->adc_nids = alc268_adc_nids;
12341 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12342 add_mixer(spec, alc268_capture_mixer);
12344 spec->capsrc_nids = alc268_capsrc_nids;
12345 /* set default input source */
12346 for (i = 0; i < spec->num_adc_nids; i++)
12347 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12348 0, AC_VERB_SET_CONNECT_SEL,
12349 spec->input_mux->items[0].index);
12352 spec->vmaster_nid = 0x02;
12354 codec->patch_ops = alc_patch_ops;
12355 if (board_config == ALC268_AUTO)
12356 spec->init_hook = alc268_auto_init;
12358 codec->proc_widget_hook = print_realtek_coef;
12364 * ALC269 channel source setting (2 channel)
12366 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12368 #define alc269_dac_nids alc260_dac_nids
12370 static hda_nid_t alc269_adc_nids[1] = {
12375 static hda_nid_t alc269_capsrc_nids[1] = {
12379 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12383 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12391 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12399 #define alc269_modes alc260_modes
12400 #define alc269_capture_source alc880_lg_lw_capture_source
12402 static struct snd_kcontrol_new alc269_base_mixer[] = {
12403 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12404 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12405 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12406 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12407 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12408 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12409 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12410 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12412 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12414 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12418 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12419 /* output mixer control */
12420 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12422 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12423 .name = "Master Playback Switch",
12424 .info = snd_hda_mixer_amp_switch_info,
12425 .get = snd_hda_mixer_amp_switch_get,
12426 .put = alc268_acer_master_sw_put,
12427 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12430 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12433 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12434 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12438 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12439 /* output mixer control */
12440 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12443 .name = "Master Playback Switch",
12444 .info = snd_hda_mixer_amp_switch_info,
12445 .get = snd_hda_mixer_amp_switch_get,
12446 .put = alc268_acer_master_sw_put,
12447 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12450 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12451 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12452 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12453 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12454 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12455 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12456 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12457 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12461 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12462 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12463 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12465 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12469 /* capture mixer elements */
12470 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12471 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12472 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12473 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12478 #define alc269_fujitsu_mixer alc269_eeepc_mixer
12480 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12481 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12482 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12484 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12486 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12490 static struct hda_verb alc269_lifebook_verbs[] = {
12491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12492 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12493 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12495 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12498 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12499 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12500 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12504 /* toggle speaker-output according to the hp-jack state */
12505 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12507 unsigned int present;
12508 unsigned char bits;
12510 present = snd_hda_codec_read(codec, 0x15, 0,
12511 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12512 bits = present ? AMP_IN_MUTE(0) : 0;
12513 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12514 AMP_IN_MUTE(0), bits);
12515 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12516 AMP_IN_MUTE(0), bits);
12518 snd_hda_codec_write(codec, 0x20, 0,
12519 AC_VERB_SET_COEF_INDEX, 0x0c);
12520 snd_hda_codec_write(codec, 0x20, 0,
12521 AC_VERB_SET_PROC_COEF, 0x680);
12523 snd_hda_codec_write(codec, 0x20, 0,
12524 AC_VERB_SET_COEF_INDEX, 0x0c);
12525 snd_hda_codec_write(codec, 0x20, 0,
12526 AC_VERB_SET_PROC_COEF, 0x480);
12529 /* toggle speaker-output according to the hp-jacks state */
12530 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12532 unsigned int present;
12533 unsigned char bits;
12535 /* Check laptop headphone socket */
12536 present = snd_hda_codec_read(codec, 0x15, 0,
12537 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12539 /* Check port replicator headphone socket */
12540 present |= snd_hda_codec_read(codec, 0x1a, 0,
12541 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12543 bits = present ? AMP_IN_MUTE(0) : 0;
12544 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12545 AMP_IN_MUTE(0), bits);
12546 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12547 AMP_IN_MUTE(0), bits);
12549 snd_hda_codec_write(codec, 0x20, 0,
12550 AC_VERB_SET_COEF_INDEX, 0x0c);
12551 snd_hda_codec_write(codec, 0x20, 0,
12552 AC_VERB_SET_PROC_COEF, 0x680);
12554 snd_hda_codec_write(codec, 0x20, 0,
12555 AC_VERB_SET_COEF_INDEX, 0x0c);
12556 snd_hda_codec_write(codec, 0x20, 0,
12557 AC_VERB_SET_PROC_COEF, 0x480);
12560 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12562 unsigned int present;
12564 present = snd_hda_codec_read(codec, 0x18, 0,
12565 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12566 snd_hda_codec_write(codec, 0x23, 0,
12567 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12570 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12572 unsigned int present_laptop;
12573 unsigned int present_dock;
12575 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12576 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12578 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12579 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12581 /* Laptop mic port overrides dock mic port, design decision */
12583 snd_hda_codec_write(codec, 0x23, 0,
12584 AC_VERB_SET_CONNECT_SEL, 0x3);
12585 if (present_laptop)
12586 snd_hda_codec_write(codec, 0x23, 0,
12587 AC_VERB_SET_CONNECT_SEL, 0x0);
12588 if (!present_dock && !present_laptop)
12589 snd_hda_codec_write(codec, 0x23, 0,
12590 AC_VERB_SET_CONNECT_SEL, 0x1);
12593 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12596 if ((res >> 26) == ALC880_HP_EVENT)
12597 alc269_quanta_fl1_speaker_automute(codec);
12598 if ((res >> 26) == ALC880_MIC_EVENT)
12599 alc269_quanta_fl1_mic_automute(codec);
12602 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12605 if ((res >> 26) == ALC880_HP_EVENT)
12606 alc269_lifebook_speaker_automute(codec);
12607 if ((res >> 26) == ALC880_MIC_EVENT)
12608 alc269_lifebook_mic_autoswitch(codec);
12611 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12613 alc269_quanta_fl1_speaker_automute(codec);
12614 alc269_quanta_fl1_mic_automute(codec);
12617 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12619 alc269_lifebook_speaker_automute(codec);
12620 alc269_lifebook_mic_autoswitch(codec);
12623 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12625 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12626 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12627 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12628 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12629 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12630 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12634 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12635 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12636 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12637 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12639 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12640 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12644 /* toggle speaker-output according to the hp-jack state */
12645 static void alc269_speaker_automute(struct hda_codec *codec)
12647 unsigned int present;
12648 unsigned char bits;
12650 present = snd_hda_codec_read(codec, 0x15, 0,
12651 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12652 bits = present ? AMP_IN_MUTE(0) : 0;
12653 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12654 AMP_IN_MUTE(0), bits);
12655 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12656 AMP_IN_MUTE(0), bits);
12659 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12661 unsigned int present;
12663 present = snd_hda_codec_read(codec, 0x18, 0,
12664 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12665 snd_hda_codec_write(codec, 0x23, 0,
12666 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12669 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12671 unsigned int present;
12673 present = snd_hda_codec_read(codec, 0x18, 0,
12674 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12675 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12676 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12677 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12678 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12681 /* unsolicited event for HP jack sensing */
12682 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12685 if ((res >> 26) == ALC880_HP_EVENT)
12686 alc269_speaker_automute(codec);
12688 if ((res >> 26) == ALC880_MIC_EVENT)
12689 alc269_eeepc_dmic_automute(codec);
12692 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12694 alc269_speaker_automute(codec);
12695 alc269_eeepc_dmic_automute(codec);
12698 /* unsolicited event for HP jack sensing */
12699 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12702 if ((res >> 26) == ALC880_HP_EVENT)
12703 alc269_speaker_automute(codec);
12705 if ((res >> 26) == ALC880_MIC_EVENT)
12706 alc269_eeepc_amic_automute(codec);
12709 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12711 alc269_speaker_automute(codec);
12712 alc269_eeepc_amic_automute(codec);
12716 * generic initialization of ADC, input mixers and output mixers
12718 static struct hda_verb alc269_init_verbs[] = {
12720 * Unmute ADC0 and set the default input to mic-in
12722 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12724 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12725 * analog-loopback mixer widget
12726 * Note: PASD motherboards uses the Line In 2 as the input for
12727 * front panel mic (mic 2)
12729 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12730 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12732 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12733 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12734 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12737 * Set up output mixers (0x0c - 0x0e)
12739 /* set vol=0 to output mixers */
12740 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12741 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12743 /* set up input amps for analog loopback */
12744 /* Amp Indices: DAC = 0, mixer = 1 */
12745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12754 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12755 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12757 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12758 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12762 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12763 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12765 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12766 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12768 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12769 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12771 /* FIXME: use matrix-type input source selection */
12772 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12773 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12780 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12781 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12785 /* add playback controls from the parsed DAC table */
12786 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12787 const struct auto_pin_cfg *cfg)
12792 spec->multiout.num_dacs = 1; /* only use one dac */
12793 spec->multiout.dac_nids = spec->private_dac_nids;
12794 spec->multiout.dac_nids[0] = 2;
12796 nid = cfg->line_out_pins[0];
12798 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12799 "Front Playback Volume",
12800 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12803 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12804 "Front Playback Switch",
12805 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12810 nid = cfg->speaker_pins[0];
12812 if (!cfg->line_out_pins[0]) {
12813 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12814 "Speaker Playback Volume",
12815 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12821 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12822 "Speaker Playback Switch",
12823 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12828 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12829 "Speaker Playback Switch",
12830 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12836 nid = cfg->hp_pins[0];
12838 /* spec->multiout.hp_nid = 2; */
12839 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12840 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12841 "Headphone Playback Volume",
12842 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12848 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12849 "Headphone Playback Switch",
12850 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12855 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12856 "Headphone Playback Switch",
12857 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12866 #define alc269_auto_create_analog_input_ctls \
12867 alc262_auto_create_analog_input_ctls
12869 #ifdef CONFIG_SND_HDA_POWER_SAVE
12870 #define alc269_loopbacks alc880_loopbacks
12873 /* pcm configuration: identical with ALC880 */
12874 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12875 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12876 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12877 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12879 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12883 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12884 /* NID is set in alc_build_pcms */
12886 .open = alc880_playback_pcm_open,
12887 .prepare = alc880_playback_pcm_prepare,
12888 .cleanup = alc880_playback_pcm_cleanup
12892 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12896 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12897 /* NID is set in alc_build_pcms */
12901 * BIOS auto configuration
12903 static int alc269_parse_auto_config(struct hda_codec *codec)
12905 struct alc_spec *spec = codec->spec;
12907 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12909 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12914 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12917 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12921 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12923 if (spec->autocfg.dig_outs)
12924 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12926 if (spec->kctls.list)
12927 add_mixer(spec, spec->kctls.list);
12929 add_verb(spec, alc269_init_verbs);
12930 spec->num_mux_defs = 1;
12931 spec->input_mux = &spec->private_imux[0];
12932 /* set default input source */
12933 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12934 0, AC_VERB_SET_CONNECT_SEL,
12935 spec->input_mux->items[0].index);
12937 err = alc_auto_add_mic_boost(codec);
12941 if (!spec->cap_mixer && !spec->no_analog)
12942 set_capture_mixer(spec);
12944 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12949 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12950 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12951 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12954 /* init callback for auto-configuration model -- overriding the default init */
12955 static void alc269_auto_init(struct hda_codec *codec)
12957 struct alc_spec *spec = codec->spec;
12958 alc269_auto_init_multi_out(codec);
12959 alc269_auto_init_hp_out(codec);
12960 alc269_auto_init_analog_input(codec);
12961 if (spec->unsol_event)
12962 alc_inithook(codec);
12966 * configuration and preset
12968 static const char *alc269_models[ALC269_MODEL_LAST] = {
12969 [ALC269_BASIC] = "basic",
12970 [ALC269_QUANTA_FL1] = "quanta",
12971 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12972 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12973 [ALC269_FUJITSU] = "fujitsu",
12974 [ALC269_LIFEBOOK] = "lifebook"
12977 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12978 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12979 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12980 ALC269_ASUS_EEEPC_P703),
12981 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12982 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12983 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12984 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12985 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12986 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12987 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12988 ALC269_ASUS_EEEPC_P901),
12989 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12990 ALC269_ASUS_EEEPC_P901),
12991 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12992 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12993 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12997 static struct alc_config_preset alc269_presets[] = {
12999 .mixers = { alc269_base_mixer },
13000 .init_verbs = { alc269_init_verbs },
13001 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13002 .dac_nids = alc269_dac_nids,
13004 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13005 .channel_mode = alc269_modes,
13006 .input_mux = &alc269_capture_source,
13008 [ALC269_QUANTA_FL1] = {
13009 .mixers = { alc269_quanta_fl1_mixer },
13010 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13011 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13012 .dac_nids = alc269_dac_nids,
13014 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13015 .channel_mode = alc269_modes,
13016 .input_mux = &alc269_capture_source,
13017 .unsol_event = alc269_quanta_fl1_unsol_event,
13018 .init_hook = alc269_quanta_fl1_init_hook,
13020 [ALC269_ASUS_EEEPC_P703] = {
13021 .mixers = { alc269_eeepc_mixer },
13022 .cap_mixer = alc269_epc_capture_mixer,
13023 .init_verbs = { alc269_init_verbs,
13024 alc269_eeepc_amic_init_verbs },
13025 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13026 .dac_nids = alc269_dac_nids,
13028 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13029 .channel_mode = alc269_modes,
13030 .input_mux = &alc269_eeepc_amic_capture_source,
13031 .unsol_event = alc269_eeepc_amic_unsol_event,
13032 .init_hook = alc269_eeepc_amic_inithook,
13034 [ALC269_ASUS_EEEPC_P901] = {
13035 .mixers = { alc269_eeepc_mixer },
13036 .cap_mixer = alc269_epc_capture_mixer,
13037 .init_verbs = { alc269_init_verbs,
13038 alc269_eeepc_dmic_init_verbs },
13039 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13040 .dac_nids = alc269_dac_nids,
13042 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13043 .channel_mode = alc269_modes,
13044 .input_mux = &alc269_eeepc_dmic_capture_source,
13045 .unsol_event = alc269_eeepc_dmic_unsol_event,
13046 .init_hook = alc269_eeepc_dmic_inithook,
13048 [ALC269_FUJITSU] = {
13049 .mixers = { alc269_fujitsu_mixer },
13050 .cap_mixer = alc269_epc_capture_mixer,
13051 .init_verbs = { alc269_init_verbs,
13052 alc269_eeepc_dmic_init_verbs },
13053 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13054 .dac_nids = alc269_dac_nids,
13056 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13057 .channel_mode = alc269_modes,
13058 .input_mux = &alc269_eeepc_dmic_capture_source,
13059 .unsol_event = alc269_eeepc_dmic_unsol_event,
13060 .init_hook = alc269_eeepc_dmic_inithook,
13062 [ALC269_LIFEBOOK] = {
13063 .mixers = { alc269_lifebook_mixer },
13064 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13065 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13066 .dac_nids = alc269_dac_nids,
13068 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13069 .channel_mode = alc269_modes,
13070 .input_mux = &alc269_capture_source,
13071 .unsol_event = alc269_lifebook_unsol_event,
13072 .init_hook = alc269_lifebook_init_hook,
13076 static int patch_alc269(struct hda_codec *codec)
13078 struct alc_spec *spec;
13082 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13086 codec->spec = spec;
13088 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13090 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13094 if (board_config < 0) {
13095 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13096 "trying auto-probe from BIOS...\n", codec->chip_name);
13097 board_config = ALC269_AUTO;
13100 if (board_config == ALC269_AUTO) {
13101 /* automatic parse from the BIOS config */
13102 err = alc269_parse_auto_config(codec);
13108 "hda_codec: Cannot set up configuration "
13109 "from BIOS. Using base mode...\n");
13110 board_config = ALC269_BASIC;
13114 err = snd_hda_attach_beep_device(codec, 0x1);
13120 if (board_config != ALC269_AUTO)
13121 setup_preset(spec, &alc269_presets[board_config]);
13123 if (codec->subsystem_id == 0x17aa3bf8) {
13124 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13125 * fix the sample rate of analog I/O to 44.1kHz
13127 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13128 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13130 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13131 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13133 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13134 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13136 spec->adc_nids = alc269_adc_nids;
13137 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13138 spec->capsrc_nids = alc269_capsrc_nids;
13139 if (!spec->cap_mixer)
13140 set_capture_mixer(spec);
13141 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13143 codec->patch_ops = alc_patch_ops;
13144 if (board_config == ALC269_AUTO)
13145 spec->init_hook = alc269_auto_init;
13146 #ifdef CONFIG_SND_HDA_POWER_SAVE
13147 if (!spec->loopback.amplist)
13148 spec->loopback.amplist = alc269_loopbacks;
13150 codec->proc_widget_hook = print_realtek_coef;
13156 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13160 * set the path ways for 2 channel output
13161 * need to set the codec line out and mic 1 pin widgets to inputs
13163 static struct hda_verb alc861_threestack_ch2_init[] = {
13164 /* set pin widget 1Ah (line in) for input */
13165 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13166 /* set pin widget 18h (mic1/2) for input, for mic also enable
13169 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13171 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13173 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13174 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13180 * need to set the codec line out and mic 1 pin widgets to outputs
13182 static struct hda_verb alc861_threestack_ch6_init[] = {
13183 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13184 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13185 /* set pin widget 18h (mic1) for output (CLFE)*/
13186 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13188 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13189 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13191 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13193 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13194 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13199 static struct hda_channel_mode alc861_threestack_modes[2] = {
13200 { 2, alc861_threestack_ch2_init },
13201 { 6, alc861_threestack_ch6_init },
13203 /* Set mic1 as input and unmute the mixer */
13204 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13205 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13206 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13209 /* Set mic1 as output and mute mixer */
13210 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13211 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13212 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13216 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13217 { 2, alc861_uniwill_m31_ch2_init },
13218 { 4, alc861_uniwill_m31_ch4_init },
13221 /* Set mic1 and line-in as input and unmute the mixer */
13222 static struct hda_verb alc861_asus_ch2_init[] = {
13223 /* set pin widget 1Ah (line in) for input */
13224 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13225 /* set pin widget 18h (mic1/2) for input, for mic also enable
13228 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13230 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13232 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13233 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13237 /* Set mic1 nad line-in as output and mute mixer */
13238 static struct hda_verb alc861_asus_ch6_init[] = {
13239 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13240 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13241 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13242 /* set pin widget 18h (mic1) for output (CLFE)*/
13243 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13244 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13245 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13246 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13248 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13250 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13251 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13256 static struct hda_channel_mode alc861_asus_modes[2] = {
13257 { 2, alc861_asus_ch2_init },
13258 { 6, alc861_asus_ch6_init },
13263 static struct snd_kcontrol_new alc861_base_mixer[] = {
13264 /* output mixer control */
13265 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13266 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13267 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13268 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13269 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13271 /*Input mixer control */
13272 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13273 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13274 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13275 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13276 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13277 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13279 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13280 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13281 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13286 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13287 /* output mixer control */
13288 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13289 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13290 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13291 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13292 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13294 /* Input mixer control */
13295 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13297 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13298 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13299 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13300 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13302 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13303 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13308 .name = "Channel Mode",
13309 .info = alc_ch_mode_info,
13310 .get = alc_ch_mode_get,
13311 .put = alc_ch_mode_put,
13312 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13317 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13318 /* output mixer control */
13319 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13321 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13326 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13327 /* output mixer control */
13328 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13329 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13330 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13331 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13332 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13334 /* Input mixer control */
13335 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13336 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13337 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13338 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13339 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13340 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13342 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13343 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13344 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13347 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13348 .name = "Channel Mode",
13349 .info = alc_ch_mode_info,
13350 .get = alc_ch_mode_get,
13351 .put = alc_ch_mode_put,
13352 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13357 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13358 /* output mixer control */
13359 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13360 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13361 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13362 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13363 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13365 /* Input mixer control */
13366 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13368 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13369 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13370 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13371 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13373 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13374 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13378 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13379 .name = "Channel Mode",
13380 .info = alc_ch_mode_info,
13381 .get = alc_ch_mode_get,
13382 .put = alc_ch_mode_put,
13383 .private_value = ARRAY_SIZE(alc861_asus_modes),
13388 /* additional mixer */
13389 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13390 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13391 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13396 * generic initialization of ADC, input mixers and output mixers
13398 static struct hda_verb alc861_base_init_verbs[] = {
13400 * Unmute ADC0 and set the default input to mic-in
13402 /* port-A for surround (rear panel) */
13403 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13404 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13405 /* port-B for mic-in (rear panel) with vref */
13406 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13407 /* port-C for line-in (rear panel) */
13408 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13409 /* port-D for Front */
13410 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13411 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13412 /* port-E for HP out (front panel) */
13413 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13414 /* route front PCM to HP */
13415 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13416 /* port-F for mic-in (front panel) with vref */
13417 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13418 /* port-G for CLFE (rear panel) */
13419 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13420 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13421 /* port-H for side (rear panel) */
13422 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13423 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13425 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13426 /* route front mic to ADC1*/
13427 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13428 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13430 /* Unmute DAC0~3 & spdif out*/
13431 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13432 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13433 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13434 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13435 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13437 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13438 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13439 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13440 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13441 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13443 /* Unmute Stereo Mixer 15 */
13444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13449 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13451 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13452 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13454 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13456 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13457 /* hp used DAC 3 (Front) */
13458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13459 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13464 static struct hda_verb alc861_threestack_init_verbs[] = {
13466 * Unmute ADC0 and set the default input to mic-in
13468 /* port-A for surround (rear panel) */
13469 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13470 /* port-B for mic-in (rear panel) with vref */
13471 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13472 /* port-C for line-in (rear panel) */
13473 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13474 /* port-D for Front */
13475 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13476 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13477 /* port-E for HP out (front panel) */
13478 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13479 /* route front PCM to HP */
13480 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13481 /* port-F for mic-in (front panel) with vref */
13482 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13483 /* port-G for CLFE (rear panel) */
13484 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13485 /* port-H for side (rear panel) */
13486 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13488 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13489 /* route front mic to ADC1*/
13490 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13492 /* Unmute DAC0~3 & spdif out*/
13493 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13494 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13495 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13496 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13499 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13500 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13501 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13502 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13503 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13505 /* Unmute Stereo Mixer 15 */
13506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13511 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13512 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13513 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13514 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13515 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13516 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13517 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13518 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13519 /* hp used DAC 3 (Front) */
13520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13521 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13525 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13527 * Unmute ADC0 and set the default input to mic-in
13529 /* port-A for surround (rear panel) */
13530 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13531 /* port-B for mic-in (rear panel) with vref */
13532 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13533 /* port-C for line-in (rear panel) */
13534 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13535 /* port-D for Front */
13536 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13537 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13538 /* port-E for HP out (front panel) */
13539 /* this has to be set to VREF80 */
13540 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13541 /* route front PCM to HP */
13542 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13543 /* port-F for mic-in (front panel) with vref */
13544 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13545 /* port-G for CLFE (rear panel) */
13546 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13547 /* port-H for side (rear panel) */
13548 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13550 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13551 /* route front mic to ADC1*/
13552 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13553 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13554 /* Unmute DAC0~3 & spdif out*/
13555 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13556 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13557 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13558 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13559 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13561 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13562 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13563 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13564 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13565 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13567 /* Unmute Stereo Mixer 15 */
13568 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13573 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13574 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13575 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13576 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13577 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13578 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13579 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13580 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13581 /* hp used DAC 3 (Front) */
13582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13587 static struct hda_verb alc861_asus_init_verbs[] = {
13589 * Unmute ADC0 and set the default input to mic-in
13591 /* port-A for surround (rear panel)
13592 * according to codec#0 this is the HP jack
13594 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13595 /* route front PCM to HP */
13596 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13597 /* port-B for mic-in (rear panel) with vref */
13598 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13599 /* port-C for line-in (rear panel) */
13600 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13601 /* port-D for Front */
13602 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13603 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13604 /* port-E for HP out (front panel) */
13605 /* this has to be set to VREF80 */
13606 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13607 /* route front PCM to HP */
13608 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13609 /* port-F for mic-in (front panel) with vref */
13610 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13611 /* port-G for CLFE (rear panel) */
13612 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13613 /* port-H for side (rear panel) */
13614 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13616 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13617 /* route front mic to ADC1*/
13618 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13620 /* Unmute DAC0~3 & spdif out*/
13621 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13622 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13623 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13624 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13626 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13627 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13628 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13629 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13630 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13632 /* Unmute Stereo Mixer 15 */
13633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13635 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13640 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13641 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13645 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13646 /* hp used DAC 3 (Front) */
13647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13652 /* additional init verbs for ASUS laptops */
13653 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13654 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13655 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13660 * generic initialization of ADC, input mixers and output mixers
13662 static struct hda_verb alc861_auto_init_verbs[] = {
13664 * Unmute ADC0 and set the default input to mic-in
13666 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13669 /* Unmute DAC0~3 & spdif out*/
13670 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13671 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13672 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13673 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13676 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13677 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13678 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13679 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13680 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13682 /* Unmute Stereo Mixer 15 */
13683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13688 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13690 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13691 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13701 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13702 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13703 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13704 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13706 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13711 static struct hda_verb alc861_toshiba_init_verbs[] = {
13712 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13717 /* toggle speaker-output according to the hp-jack state */
13718 static void alc861_toshiba_automute(struct hda_codec *codec)
13720 unsigned int present;
13722 present = snd_hda_codec_read(codec, 0x0f, 0,
13723 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13724 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13725 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13726 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13727 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13730 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13733 if ((res >> 26) == ALC880_HP_EVENT)
13734 alc861_toshiba_automute(codec);
13737 /* pcm configuration: identical with ALC880 */
13738 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13739 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13740 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13741 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13744 #define ALC861_DIGOUT_NID 0x07
13746 static struct hda_channel_mode alc861_8ch_modes[1] = {
13750 static hda_nid_t alc861_dac_nids[4] = {
13751 /* front, surround, clfe, side */
13752 0x03, 0x06, 0x05, 0x04
13755 static hda_nid_t alc660_dac_nids[3] = {
13756 /* front, clfe, surround */
13760 static hda_nid_t alc861_adc_nids[1] = {
13765 static struct hda_input_mux alc861_capture_source = {
13769 { "Front Mic", 0x3 },
13776 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
13778 struct alc_spec *spec = codec->spec;
13779 hda_nid_t mix, srcs[5];
13782 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
13784 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
13787 for (i = 0; i < num; i++) {
13789 type = (get_wcaps(codec, srcs[i]) & AC_WCAP_TYPE)
13790 >> AC_WCAP_TYPE_SHIFT;
13791 if (type != AC_WID_AUD_OUT)
13793 for (j = 0; j < spec->multiout.num_dacs; j++)
13794 if (spec->multiout.dac_nids[j] == srcs[i])
13796 if (j >= spec->multiout.num_dacs)
13802 /* fill in the dac_nids table from the parsed pin configuration */
13803 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
13804 const struct auto_pin_cfg *cfg)
13806 struct alc_spec *spec = codec->spec;
13808 hda_nid_t nid, dac;
13810 spec->multiout.dac_nids = spec->private_dac_nids;
13811 for (i = 0; i < cfg->line_outs; i++) {
13812 nid = cfg->line_out_pins[i];
13813 dac = alc861_look_for_dac(codec, nid);
13816 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13821 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
13822 hda_nid_t nid, unsigned int chs)
13825 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
13826 return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
13827 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
13830 /* add playback controls from the parsed DAC table */
13831 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
13832 const struct auto_pin_cfg *cfg)
13834 struct alc_spec *spec = codec->spec;
13835 static const char *chname[4] = {
13836 "Front", "Surround", NULL /*CLFE*/, "Side"
13841 if (cfg->line_outs == 1) {
13842 const char *pfx = NULL;
13845 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13848 nid = spec->multiout.dac_nids[0];
13849 return alc861_create_out_sw(codec, pfx, nid, 3);
13853 for (i = 0; i < cfg->line_outs; i++) {
13854 nid = spec->multiout.dac_nids[i];
13859 err = alc861_create_out_sw(codec, "Center", nid, 1);
13862 err = alc861_create_out_sw(codec, "LFE", nid, 2);
13866 err = alc861_create_out_sw(codec, chname[i], nid, 3);
13874 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
13876 struct alc_spec *spec = codec->spec;
13883 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13884 nid = alc861_look_for_dac(codec, pin);
13886 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
13889 spec->multiout.hp_nid = nid;
13895 /* create playback/capture controls for input pins */
13896 static int alc861_auto_create_analog_input_ctls(struct hda_codec *codec,
13897 const struct auto_pin_cfg *cfg)
13899 struct alc_spec *spec = codec->spec;
13900 struct hda_input_mux *imux = &spec->private_imux[0];
13901 int i, err, idx, idx1;
13903 for (i = 0; i < AUTO_PIN_LAST; i++) {
13904 switch (cfg->input_pins[i]) {
13907 idx = 2; /* Line In */
13911 idx = 2; /* Line In */
13915 idx = 1; /* Mic In */
13919 idx = 1; /* Mic In */
13929 err = new_analog_input(spec, cfg->input_pins[i],
13930 auto_pin_cfg_labels[i], idx, 0x15);
13934 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13935 imux->items[imux->num_items].index = idx1;
13941 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13943 int pin_type, hda_nid_t dac)
13945 hda_nid_t mix, srcs[5];
13948 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13950 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13952 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
13954 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
13957 for (i = 0; i < num; i++) {
13959 if (srcs[i] == dac || srcs[i] == 0x15)
13960 mute = AMP_IN_UNMUTE(i);
13962 mute = AMP_IN_MUTE(i);
13963 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13968 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13970 struct alc_spec *spec = codec->spec;
13973 for (i = 0; i < spec->autocfg.line_outs; i++) {
13974 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13975 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13977 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13978 spec->multiout.dac_nids[i]);
13982 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13984 struct alc_spec *spec = codec->spec;
13987 pin = spec->autocfg.hp_pins[0];
13989 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13990 spec->multiout.hp_nid);
13991 pin = spec->autocfg.speaker_pins[0];
13993 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT,
13994 spec->multiout.dac_nids[0]);
13997 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13999 struct alc_spec *spec = codec->spec;
14002 for (i = 0; i < AUTO_PIN_LAST; i++) {
14003 hda_nid_t nid = spec->autocfg.input_pins[i];
14004 if (nid >= 0x0c && nid <= 0x11)
14005 alc_set_input_pin(codec, nid, i);
14009 /* parse the BIOS configuration and set up the alc_spec */
14010 /* return 1 if successful, 0 if the proper config is not found,
14011 * or a negative error code
14013 static int alc861_parse_auto_config(struct hda_codec *codec)
14015 struct alc_spec *spec = codec->spec;
14017 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14019 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14023 if (!spec->autocfg.line_outs)
14024 return 0; /* can't find valid BIOS pin config */
14026 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14029 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14032 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14035 err = alc861_auto_create_analog_input_ctls(codec, &spec->autocfg);
14039 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14041 if (spec->autocfg.dig_outs)
14042 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14044 if (spec->kctls.list)
14045 add_mixer(spec, spec->kctls.list);
14047 add_verb(spec, alc861_auto_init_verbs);
14049 spec->num_mux_defs = 1;
14050 spec->input_mux = &spec->private_imux[0];
14052 spec->adc_nids = alc861_adc_nids;
14053 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14054 set_capture_mixer(spec);
14056 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14061 /* additional initialization for auto-configuration model */
14062 static void alc861_auto_init(struct hda_codec *codec)
14064 struct alc_spec *spec = codec->spec;
14065 alc861_auto_init_multi_out(codec);
14066 alc861_auto_init_hp_out(codec);
14067 alc861_auto_init_analog_input(codec);
14068 if (spec->unsol_event)
14069 alc_inithook(codec);
14072 #ifdef CONFIG_SND_HDA_POWER_SAVE
14073 static struct hda_amp_list alc861_loopbacks[] = {
14074 { 0x15, HDA_INPUT, 0 },
14075 { 0x15, HDA_INPUT, 1 },
14076 { 0x15, HDA_INPUT, 2 },
14077 { 0x15, HDA_INPUT, 3 },
14084 * configuration and preset
14086 static const char *alc861_models[ALC861_MODEL_LAST] = {
14087 [ALC861_3ST] = "3stack",
14088 [ALC660_3ST] = "3stack-660",
14089 [ALC861_3ST_DIG] = "3stack-dig",
14090 [ALC861_6ST_DIG] = "6stack-dig",
14091 [ALC861_UNIWILL_M31] = "uniwill-m31",
14092 [ALC861_TOSHIBA] = "toshiba",
14093 [ALC861_ASUS] = "asus",
14094 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14095 [ALC861_AUTO] = "auto",
14098 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14099 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14100 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14101 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14102 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14103 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14104 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14105 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14106 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14107 * Any other models that need this preset?
14109 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14110 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14111 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14112 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14113 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14114 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14115 /* FIXME: the below seems conflict */
14116 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14117 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14118 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14122 static struct alc_config_preset alc861_presets[] = {
14124 .mixers = { alc861_3ST_mixer },
14125 .init_verbs = { alc861_threestack_init_verbs },
14126 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14127 .dac_nids = alc861_dac_nids,
14128 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14129 .channel_mode = alc861_threestack_modes,
14131 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14132 .adc_nids = alc861_adc_nids,
14133 .input_mux = &alc861_capture_source,
14135 [ALC861_3ST_DIG] = {
14136 .mixers = { alc861_base_mixer },
14137 .init_verbs = { alc861_threestack_init_verbs },
14138 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14139 .dac_nids = alc861_dac_nids,
14140 .dig_out_nid = ALC861_DIGOUT_NID,
14141 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14142 .channel_mode = alc861_threestack_modes,
14144 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14145 .adc_nids = alc861_adc_nids,
14146 .input_mux = &alc861_capture_source,
14148 [ALC861_6ST_DIG] = {
14149 .mixers = { alc861_base_mixer },
14150 .init_verbs = { alc861_base_init_verbs },
14151 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14152 .dac_nids = alc861_dac_nids,
14153 .dig_out_nid = ALC861_DIGOUT_NID,
14154 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14155 .channel_mode = alc861_8ch_modes,
14156 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14157 .adc_nids = alc861_adc_nids,
14158 .input_mux = &alc861_capture_source,
14161 .mixers = { alc861_3ST_mixer },
14162 .init_verbs = { alc861_threestack_init_verbs },
14163 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14164 .dac_nids = alc660_dac_nids,
14165 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14166 .channel_mode = alc861_threestack_modes,
14168 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14169 .adc_nids = alc861_adc_nids,
14170 .input_mux = &alc861_capture_source,
14172 [ALC861_UNIWILL_M31] = {
14173 .mixers = { alc861_uniwill_m31_mixer },
14174 .init_verbs = { alc861_uniwill_m31_init_verbs },
14175 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14176 .dac_nids = alc861_dac_nids,
14177 .dig_out_nid = ALC861_DIGOUT_NID,
14178 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14179 .channel_mode = alc861_uniwill_m31_modes,
14181 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14182 .adc_nids = alc861_adc_nids,
14183 .input_mux = &alc861_capture_source,
14185 [ALC861_TOSHIBA] = {
14186 .mixers = { alc861_toshiba_mixer },
14187 .init_verbs = { alc861_base_init_verbs,
14188 alc861_toshiba_init_verbs },
14189 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14190 .dac_nids = alc861_dac_nids,
14191 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14192 .channel_mode = alc883_3ST_2ch_modes,
14193 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14194 .adc_nids = alc861_adc_nids,
14195 .input_mux = &alc861_capture_source,
14196 .unsol_event = alc861_toshiba_unsol_event,
14197 .init_hook = alc861_toshiba_automute,
14200 .mixers = { alc861_asus_mixer },
14201 .init_verbs = { alc861_asus_init_verbs },
14202 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14203 .dac_nids = alc861_dac_nids,
14204 .dig_out_nid = ALC861_DIGOUT_NID,
14205 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14206 .channel_mode = alc861_asus_modes,
14209 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14210 .adc_nids = alc861_adc_nids,
14211 .input_mux = &alc861_capture_source,
14213 [ALC861_ASUS_LAPTOP] = {
14214 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14215 .init_verbs = { alc861_asus_init_verbs,
14216 alc861_asus_laptop_init_verbs },
14217 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14218 .dac_nids = alc861_dac_nids,
14219 .dig_out_nid = ALC861_DIGOUT_NID,
14220 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14221 .channel_mode = alc883_3ST_2ch_modes,
14223 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14224 .adc_nids = alc861_adc_nids,
14225 .input_mux = &alc861_capture_source,
14230 static int patch_alc861(struct hda_codec *codec)
14232 struct alc_spec *spec;
14236 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14240 codec->spec = spec;
14242 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14246 if (board_config < 0) {
14247 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14248 "trying auto-probe from BIOS...\n", codec->chip_name);
14249 board_config = ALC861_AUTO;
14252 if (board_config == ALC861_AUTO) {
14253 /* automatic parse from the BIOS config */
14254 err = alc861_parse_auto_config(codec);
14260 "hda_codec: Cannot set up configuration "
14261 "from BIOS. Using base mode...\n");
14262 board_config = ALC861_3ST_DIG;
14266 err = snd_hda_attach_beep_device(codec, 0x23);
14272 if (board_config != ALC861_AUTO)
14273 setup_preset(spec, &alc861_presets[board_config]);
14275 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14276 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14278 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14279 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14281 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14283 spec->vmaster_nid = 0x03;
14285 codec->patch_ops = alc_patch_ops;
14286 if (board_config == ALC861_AUTO)
14287 spec->init_hook = alc861_auto_init;
14288 #ifdef CONFIG_SND_HDA_POWER_SAVE
14289 if (!spec->loopback.amplist)
14290 spec->loopback.amplist = alc861_loopbacks;
14292 codec->proc_widget_hook = print_realtek_coef;
14298 * ALC861-VD support
14302 * In addition, an independent DAC
14304 #define ALC861VD_DIGOUT_NID 0x06
14306 static hda_nid_t alc861vd_dac_nids[4] = {
14307 /* front, surr, clfe, side surr */
14308 0x02, 0x03, 0x04, 0x05
14311 /* dac_nids for ALC660vd are in a different order - according to
14312 * Realtek's driver.
14313 * This should probably result in a different mixer for 6stack models
14314 * of ALC660vd codecs, but for now there is only 3stack mixer
14315 * - and it is the same as in 861vd.
14316 * adc_nids in ALC660vd are (is) the same as in 861vd
14318 static hda_nid_t alc660vd_dac_nids[3] = {
14319 /* front, rear, clfe, rear_surr */
14323 static hda_nid_t alc861vd_adc_nids[1] = {
14328 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14331 /* FIXME: should be a matrix-type input source selection */
14332 static struct hda_input_mux alc861vd_capture_source = {
14336 { "Front Mic", 0x1 },
14342 static struct hda_input_mux alc861vd_dallas_capture_source = {
14345 { "Ext Mic", 0x0 },
14346 { "Int Mic", 0x1 },
14350 static struct hda_input_mux alc861vd_hp_capture_source = {
14353 { "Front Mic", 0x0 },
14354 { "ATAPI Mic", 0x1 },
14361 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14368 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14369 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14370 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14371 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14372 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14379 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14380 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14381 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14382 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14383 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14387 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14388 { 6, alc861vd_6stack_ch6_init },
14389 { 8, alc861vd_6stack_ch8_init },
14392 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14394 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14395 .name = "Channel Mode",
14396 .info = alc_ch_mode_info,
14397 .get = alc_ch_mode_get,
14398 .put = alc_ch_mode_put,
14403 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14404 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14406 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14407 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14408 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14410 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14411 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14415 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14418 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14420 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14421 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14423 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14425 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14429 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14430 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14431 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14433 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14434 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14436 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14437 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14442 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14443 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14444 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14448 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14450 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14452 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14453 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14454 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14456 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14457 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14465 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14466 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14467 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14468 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14470 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14472 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14474 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14476 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14477 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14478 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14486 /* Pin assignment: Speaker=0x14, HP = 0x15,
14487 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14489 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14490 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14491 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14492 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14493 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14494 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14495 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14496 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14497 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14498 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14499 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14503 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14504 * Front Mic=0x18, ATAPI Mic = 0x19,
14506 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14507 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14508 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14509 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14510 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14511 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14513 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14514 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14520 * generic initialization of ADC, input mixers and output mixers
14522 static struct hda_verb alc861vd_volume_init_verbs[] = {
14524 * Unmute ADC0 and set the default input to mic-in
14526 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14529 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14530 * the analog-loopback mixer widget
14532 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14533 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14535 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14536 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14537 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14539 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14540 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14546 * Set up output mixers (0x02 - 0x05)
14548 /* set vol=0 to output mixers */
14549 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14550 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14551 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14552 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14554 /* set up input amps for analog loopback */
14555 /* Amp Indices: DAC = 0, mixer = 1 */
14556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14562 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14569 * 3-stack pin configuration:
14570 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14572 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14574 * Set pin mode and muting
14576 /* set front pin widgets 0x14 for output */
14577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14578 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14579 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14581 /* Mic (rear) pin: input vref at 80% */
14582 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14584 /* Front Mic pin: input vref at 80% */
14585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14587 /* Line In pin: input */
14588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14590 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14593 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14594 /* CD pin widget for input */
14595 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14601 * 6-stack pin configuration:
14603 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14605 * Set pin mode and muting
14607 /* set front pin widgets 0x14 for output */
14608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14609 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14610 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14612 /* Rear Pin: output 1 (0x0d) */
14613 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14616 /* CLFE Pin: output 2 (0x0e) */
14617 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14618 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14619 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14620 /* Side Pin: output 3 (0x0f) */
14621 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14623 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14625 /* Mic (rear) pin: input vref at 80% */
14626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14628 /* Front Mic pin: input vref at 80% */
14629 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14630 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14631 /* Line In pin: input */
14632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14633 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14634 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14635 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14636 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14637 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14638 /* CD pin widget for input */
14639 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14644 static struct hda_verb alc861vd_eapd_verbs[] = {
14645 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14649 static struct hda_verb alc660vd_eapd_verbs[] = {
14650 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14651 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14655 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14658 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14659 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14660 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14664 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14666 unsigned int present;
14667 unsigned char bits;
14669 present = snd_hda_codec_read(codec, 0x18, 0,
14670 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14671 bits = present ? HDA_AMP_MUTE : 0;
14672 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14673 HDA_AMP_MUTE, bits);
14676 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14678 struct alc_spec *spec = codec->spec;
14680 spec->autocfg.hp_pins[0] = 0x1b;
14681 spec->autocfg.speaker_pins[0] = 0x14;
14682 alc_automute_amp(codec);
14683 alc861vd_lenovo_mic_automute(codec);
14686 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14689 switch (res >> 26) {
14690 case ALC880_MIC_EVENT:
14691 alc861vd_lenovo_mic_automute(codec);
14694 alc_automute_amp_unsol_event(codec, res);
14699 static struct hda_verb alc861vd_dallas_verbs[] = {
14700 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14701 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14702 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14703 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14707 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14710 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14711 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14712 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14714 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14715 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14718 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14720 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14721 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14723 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14724 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14725 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14726 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14727 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14728 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14729 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14730 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14732 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14734 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14735 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14737 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14739 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14744 /* toggle speaker-output according to the hp-jack state */
14745 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14747 struct alc_spec *spec = codec->spec;
14749 spec->autocfg.hp_pins[0] = 0x15;
14750 spec->autocfg.speaker_pins[0] = 0x14;
14751 alc_automute_amp(codec);
14754 #ifdef CONFIG_SND_HDA_POWER_SAVE
14755 #define alc861vd_loopbacks alc880_loopbacks
14758 /* pcm configuration: identical with ALC880 */
14759 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14760 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14761 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14762 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14765 * configuration and preset
14767 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14768 [ALC660VD_3ST] = "3stack-660",
14769 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14770 [ALC660VD_ASUS_V1S] = "asus-v1s",
14771 [ALC861VD_3ST] = "3stack",
14772 [ALC861VD_3ST_DIG] = "3stack-digout",
14773 [ALC861VD_6ST_DIG] = "6stack-digout",
14774 [ALC861VD_LENOVO] = "lenovo",
14775 [ALC861VD_DALLAS] = "dallas",
14776 [ALC861VD_HP] = "hp",
14777 [ALC861VD_AUTO] = "auto",
14780 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14781 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14782 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14783 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14784 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14785 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14786 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14787 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14788 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14789 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14790 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14791 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14792 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14793 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14794 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14795 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14799 static struct alc_config_preset alc861vd_presets[] = {
14801 .mixers = { alc861vd_3st_mixer },
14802 .init_verbs = { alc861vd_volume_init_verbs,
14803 alc861vd_3stack_init_verbs },
14804 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14805 .dac_nids = alc660vd_dac_nids,
14806 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14807 .channel_mode = alc861vd_3stack_2ch_modes,
14808 .input_mux = &alc861vd_capture_source,
14810 [ALC660VD_3ST_DIG] = {
14811 .mixers = { alc861vd_3st_mixer },
14812 .init_verbs = { alc861vd_volume_init_verbs,
14813 alc861vd_3stack_init_verbs },
14814 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14815 .dac_nids = alc660vd_dac_nids,
14816 .dig_out_nid = ALC861VD_DIGOUT_NID,
14817 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14818 .channel_mode = alc861vd_3stack_2ch_modes,
14819 .input_mux = &alc861vd_capture_source,
14822 .mixers = { alc861vd_3st_mixer },
14823 .init_verbs = { alc861vd_volume_init_verbs,
14824 alc861vd_3stack_init_verbs },
14825 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14826 .dac_nids = alc861vd_dac_nids,
14827 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14828 .channel_mode = alc861vd_3stack_2ch_modes,
14829 .input_mux = &alc861vd_capture_source,
14831 [ALC861VD_3ST_DIG] = {
14832 .mixers = { alc861vd_3st_mixer },
14833 .init_verbs = { alc861vd_volume_init_verbs,
14834 alc861vd_3stack_init_verbs },
14835 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14836 .dac_nids = alc861vd_dac_nids,
14837 .dig_out_nid = ALC861VD_DIGOUT_NID,
14838 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14839 .channel_mode = alc861vd_3stack_2ch_modes,
14840 .input_mux = &alc861vd_capture_source,
14842 [ALC861VD_6ST_DIG] = {
14843 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14844 .init_verbs = { alc861vd_volume_init_verbs,
14845 alc861vd_6stack_init_verbs },
14846 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14847 .dac_nids = alc861vd_dac_nids,
14848 .dig_out_nid = ALC861VD_DIGOUT_NID,
14849 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14850 .channel_mode = alc861vd_6stack_modes,
14851 .input_mux = &alc861vd_capture_source,
14853 [ALC861VD_LENOVO] = {
14854 .mixers = { alc861vd_lenovo_mixer },
14855 .init_verbs = { alc861vd_volume_init_verbs,
14856 alc861vd_3stack_init_verbs,
14857 alc861vd_eapd_verbs,
14858 alc861vd_lenovo_unsol_verbs },
14859 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14860 .dac_nids = alc660vd_dac_nids,
14861 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14862 .channel_mode = alc861vd_3stack_2ch_modes,
14863 .input_mux = &alc861vd_capture_source,
14864 .unsol_event = alc861vd_lenovo_unsol_event,
14865 .init_hook = alc861vd_lenovo_init_hook,
14867 [ALC861VD_DALLAS] = {
14868 .mixers = { alc861vd_dallas_mixer },
14869 .init_verbs = { alc861vd_dallas_verbs },
14870 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14871 .dac_nids = alc861vd_dac_nids,
14872 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14873 .channel_mode = alc861vd_3stack_2ch_modes,
14874 .input_mux = &alc861vd_dallas_capture_source,
14875 .unsol_event = alc_automute_amp_unsol_event,
14876 .init_hook = alc861vd_dallas_init_hook,
14879 .mixers = { alc861vd_hp_mixer },
14880 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14881 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14882 .dac_nids = alc861vd_dac_nids,
14883 .dig_out_nid = ALC861VD_DIGOUT_NID,
14884 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14885 .channel_mode = alc861vd_3stack_2ch_modes,
14886 .input_mux = &alc861vd_hp_capture_source,
14887 .unsol_event = alc_automute_amp_unsol_event,
14888 .init_hook = alc861vd_dallas_init_hook,
14890 [ALC660VD_ASUS_V1S] = {
14891 .mixers = { alc861vd_lenovo_mixer },
14892 .init_verbs = { alc861vd_volume_init_verbs,
14893 alc861vd_3stack_init_verbs,
14894 alc861vd_eapd_verbs,
14895 alc861vd_lenovo_unsol_verbs },
14896 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14897 .dac_nids = alc660vd_dac_nids,
14898 .dig_out_nid = ALC861VD_DIGOUT_NID,
14899 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14900 .channel_mode = alc861vd_3stack_2ch_modes,
14901 .input_mux = &alc861vd_capture_source,
14902 .unsol_event = alc861vd_lenovo_unsol_event,
14903 .init_hook = alc861vd_lenovo_init_hook,
14908 * BIOS auto configuration
14910 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14911 hda_nid_t nid, int pin_type, int dac_idx)
14913 alc_set_pin_output(codec, nid, pin_type);
14916 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14918 struct alc_spec *spec = codec->spec;
14921 for (i = 0; i <= HDA_SIDE; i++) {
14922 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14923 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14925 alc861vd_auto_set_output_and_unmute(codec, nid,
14931 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14933 struct alc_spec *spec = codec->spec;
14936 pin = spec->autocfg.hp_pins[0];
14937 if (pin) /* connect to front and use dac 0 */
14938 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14939 pin = spec->autocfg.speaker_pins[0];
14941 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14944 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14945 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14947 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14949 struct alc_spec *spec = codec->spec;
14952 for (i = 0; i < AUTO_PIN_LAST; i++) {
14953 hda_nid_t nid = spec->autocfg.input_pins[i];
14954 if (alc861vd_is_input_pin(nid)) {
14955 alc_set_input_pin(codec, nid, i);
14956 if (nid != ALC861VD_PIN_CD_NID &&
14957 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14958 snd_hda_codec_write(codec, nid, 0,
14959 AC_VERB_SET_AMP_GAIN_MUTE,
14965 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14967 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14968 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14970 /* add playback controls from the parsed DAC table */
14971 /* Based on ALC880 version. But ALC861VD has separate,
14972 * different NIDs for mute/unmute switch and volume control */
14973 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14974 const struct auto_pin_cfg *cfg)
14977 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14978 hda_nid_t nid_v, nid_s;
14981 for (i = 0; i < cfg->line_outs; i++) {
14982 if (!spec->multiout.dac_nids[i])
14984 nid_v = alc861vd_idx_to_mixer_vol(
14986 spec->multiout.dac_nids[i]));
14987 nid_s = alc861vd_idx_to_mixer_switch(
14989 spec->multiout.dac_nids[i]));
14993 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14994 "Center Playback Volume",
14995 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14999 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15000 "LFE Playback Volume",
15001 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15005 err = add_control(spec, ALC_CTL_BIND_MUTE,
15006 "Center Playback Switch",
15007 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15011 err = add_control(spec, ALC_CTL_BIND_MUTE,
15012 "LFE Playback Switch",
15013 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15018 sprintf(name, "%s Playback Volume", chname[i]);
15019 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15020 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15024 sprintf(name, "%s Playback Switch", chname[i]);
15025 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15026 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15035 /* add playback controls for speaker and HP outputs */
15036 /* Based on ALC880 version. But ALC861VD has separate,
15037 * different NIDs for mute/unmute switch and volume control */
15038 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15039 hda_nid_t pin, const char *pfx)
15041 hda_nid_t nid_v, nid_s;
15048 if (alc880_is_fixed_pin(pin)) {
15049 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15050 /* specify the DAC as the extra output */
15051 if (!spec->multiout.hp_nid)
15052 spec->multiout.hp_nid = nid_v;
15054 spec->multiout.extra_out_nid[0] = nid_v;
15055 /* control HP volume/switch on the output mixer amp */
15056 nid_v = alc861vd_idx_to_mixer_vol(
15057 alc880_fixed_pin_idx(pin));
15058 nid_s = alc861vd_idx_to_mixer_switch(
15059 alc880_fixed_pin_idx(pin));
15061 sprintf(name, "%s Playback Volume", pfx);
15062 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15063 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15066 sprintf(name, "%s Playback Switch", pfx);
15067 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15068 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15071 } else if (alc880_is_multi_pin(pin)) {
15072 /* set manual connection */
15073 /* we have only a switch on HP-out PIN */
15074 sprintf(name, "%s Playback Switch", pfx);
15075 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15076 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15083 /* parse the BIOS configuration and set up the alc_spec
15084 * return 1 if successful, 0 if the proper config is not found,
15085 * or a negative error code
15086 * Based on ALC880 version - had to change it to override
15087 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15088 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15090 struct alc_spec *spec = codec->spec;
15092 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15094 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15098 if (!spec->autocfg.line_outs)
15099 return 0; /* can't find valid BIOS pin config */
15101 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15104 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15107 err = alc861vd_auto_create_extra_out(spec,
15108 spec->autocfg.speaker_pins[0],
15112 err = alc861vd_auto_create_extra_out(spec,
15113 spec->autocfg.hp_pins[0],
15117 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15121 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15123 if (spec->autocfg.dig_outs)
15124 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15126 if (spec->kctls.list)
15127 add_mixer(spec, spec->kctls.list);
15129 add_verb(spec, alc861vd_volume_init_verbs);
15131 spec->num_mux_defs = 1;
15132 spec->input_mux = &spec->private_imux[0];
15134 err = alc_auto_add_mic_boost(codec);
15138 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15143 /* additional initialization for auto-configuration model */
15144 static void alc861vd_auto_init(struct hda_codec *codec)
15146 struct alc_spec *spec = codec->spec;
15147 alc861vd_auto_init_multi_out(codec);
15148 alc861vd_auto_init_hp_out(codec);
15149 alc861vd_auto_init_analog_input(codec);
15150 alc861vd_auto_init_input_src(codec);
15151 if (spec->unsol_event)
15152 alc_inithook(codec);
15155 static int patch_alc861vd(struct hda_codec *codec)
15157 struct alc_spec *spec;
15158 int err, board_config;
15160 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15164 codec->spec = spec;
15166 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15170 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15171 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15172 "trying auto-probe from BIOS...\n", codec->chip_name);
15173 board_config = ALC861VD_AUTO;
15176 if (board_config == ALC861VD_AUTO) {
15177 /* automatic parse from the BIOS config */
15178 err = alc861vd_parse_auto_config(codec);
15184 "hda_codec: Cannot set up configuration "
15185 "from BIOS. Using base mode...\n");
15186 board_config = ALC861VD_3ST;
15190 err = snd_hda_attach_beep_device(codec, 0x23);
15196 if (board_config != ALC861VD_AUTO)
15197 setup_preset(spec, &alc861vd_presets[board_config]);
15199 if (codec->vendor_id == 0x10ec0660) {
15200 /* always turn on EAPD */
15201 add_verb(spec, alc660vd_eapd_verbs);
15204 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15205 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15207 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15208 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15210 spec->adc_nids = alc861vd_adc_nids;
15211 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15212 spec->capsrc_nids = alc861vd_capsrc_nids;
15214 set_capture_mixer(spec);
15215 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15217 spec->vmaster_nid = 0x02;
15219 codec->patch_ops = alc_patch_ops;
15221 if (board_config == ALC861VD_AUTO)
15222 spec->init_hook = alc861vd_auto_init;
15223 #ifdef CONFIG_SND_HDA_POWER_SAVE
15224 if (!spec->loopback.amplist)
15225 spec->loopback.amplist = alc861vd_loopbacks;
15227 codec->proc_widget_hook = print_realtek_coef;
15235 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15236 * configuration. Each pin widget can choose any input DACs and a mixer.
15237 * Each ADC is connected from a mixer of all inputs. This makes possible
15238 * 6-channel independent captures.
15240 * In addition, an independent DAC for the multi-playback (not used in this
15243 #define ALC662_DIGOUT_NID 0x06
15244 #define ALC662_DIGIN_NID 0x0a
15246 static hda_nid_t alc662_dac_nids[4] = {
15247 /* front, rear, clfe, rear_surr */
15251 static hda_nid_t alc272_dac_nids[2] = {
15255 static hda_nid_t alc662_adc_nids[1] = {
15260 static hda_nid_t alc272_adc_nids[1] = {
15265 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15266 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15270 /* FIXME: should be a matrix-type input source selection */
15271 static struct hda_input_mux alc662_capture_source = {
15275 { "Front Mic", 0x1 },
15281 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15289 static struct hda_input_mux alc662_eeepc_capture_source = {
15297 static struct hda_input_mux alc663_capture_source = {
15301 { "Front Mic", 0x1 },
15306 static struct hda_input_mux alc663_m51va_capture_source = {
15309 { "Ext-Mic", 0x0 },
15314 #if 1 /* set to 0 for testing other input sources below */
15315 static struct hda_input_mux alc272_nc10_capture_source = {
15318 { "Autoselect Mic", 0x0 },
15319 { "Internal Mic", 0x1 },
15323 static struct hda_input_mux alc272_nc10_capture_source = {
15326 { "Autoselect Mic", 0x0 },
15327 { "Internal Mic", 0x1 },
15328 { "In-0x02", 0x2 },
15329 { "In-0x03", 0x3 },
15330 { "In-0x04", 0x4 },
15331 { "In-0x05", 0x5 },
15332 { "In-0x06", 0x6 },
15333 { "In-0x07", 0x7 },
15334 { "In-0x08", 0x8 },
15335 { "In-0x09", 0x9 },
15336 { "In-0x0a", 0x0a },
15337 { "In-0x0b", 0x0b },
15338 { "In-0x0c", 0x0c },
15339 { "In-0x0d", 0x0d },
15340 { "In-0x0e", 0x0e },
15341 { "In-0x0f", 0x0f },
15349 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15356 static struct hda_verb alc662_3ST_ch2_init[] = {
15357 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15358 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15359 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15360 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15367 static struct hda_verb alc662_3ST_ch6_init[] = {
15368 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15369 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15370 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15371 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15372 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15373 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15377 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15378 { 2, alc662_3ST_ch2_init },
15379 { 6, alc662_3ST_ch6_init },
15385 static struct hda_verb alc662_sixstack_ch6_init[] = {
15386 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15387 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15388 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15395 static struct hda_verb alc662_sixstack_ch8_init[] = {
15396 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15397 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15398 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15402 static struct hda_channel_mode alc662_5stack_modes[2] = {
15403 { 2, alc662_sixstack_ch6_init },
15404 { 6, alc662_sixstack_ch8_init },
15407 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15408 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15411 static struct snd_kcontrol_new alc662_base_mixer[] = {
15412 /* output mixer control */
15413 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15415 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15416 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15418 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15419 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15420 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15421 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15423 /*Input mixer control */
15424 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15425 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15426 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15427 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15428 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15429 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15430 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15431 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15435 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15436 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15437 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15438 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15441 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15442 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15443 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15444 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15445 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15446 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15450 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15451 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15453 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15455 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15456 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15457 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15458 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15459 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15461 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15466 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15467 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15471 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15472 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15473 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15474 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15475 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15476 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15477 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15478 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15484 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15485 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15486 ALC262_HIPPO_MASTER_SWITCH,
15488 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15489 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15490 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15492 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15493 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15494 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15498 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15499 ALC262_HIPPO_MASTER_SWITCH,
15500 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15501 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15503 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15504 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15505 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15506 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15512 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15513 .ops = &snd_hda_bind_vol,
15515 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15516 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15521 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15522 .ops = &snd_hda_bind_sw,
15524 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15525 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15530 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15531 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15532 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15538 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15539 .ops = &snd_hda_bind_sw,
15541 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15542 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15543 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15548 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15549 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15550 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15553 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15554 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15559 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15560 .ops = &snd_hda_bind_sw,
15562 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15563 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15564 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15569 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15570 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15571 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15574 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15575 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15579 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15583 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15585 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15586 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15590 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15591 .ops = &snd_hda_bind_vol,
15593 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15594 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15599 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15600 .ops = &snd_hda_bind_sw,
15602 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15603 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15608 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15609 HDA_BIND_VOL("Master Playback Volume",
15610 &alc663_asus_two_bind_master_vol),
15611 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15613 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15619 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15620 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15621 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15622 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15629 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15630 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15631 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15632 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15633 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15638 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15639 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15643 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15644 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15645 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15646 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15650 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15651 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15652 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15653 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15657 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15660 .name = "Channel Mode",
15661 .info = alc_ch_mode_info,
15662 .get = alc_ch_mode_get,
15663 .put = alc_ch_mode_put,
15668 static struct hda_verb alc662_init_verbs[] = {
15669 /* ADC: mute amp left and right */
15670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15671 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15672 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15674 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15675 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15676 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15677 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15678 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15687 /* Front Pin: output 0 (0x0c) */
15688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15689 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15691 /* Rear Pin: output 1 (0x0d) */
15692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15695 /* CLFE Pin: output 2 (0x0e) */
15696 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15697 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15699 /* Mic (rear) pin: input vref at 80% */
15700 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15702 /* Front Mic pin: input vref at 80% */
15703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15705 /* Line In pin: input */
15706 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15708 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15711 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15712 /* CD pin widget for input */
15713 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15715 /* FIXME: use matrix-type input source selection */
15716 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15721 /* always trun on EAPD */
15722 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15723 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15728 static struct hda_verb alc662_sue_init_verbs[] = {
15729 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15730 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15734 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15735 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15736 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15740 /* Set Unsolicited Event*/
15741 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15742 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15743 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15748 * generic initialization of ADC, input mixers and output mixers
15750 static struct hda_verb alc662_auto_init_verbs[] = {
15752 * Unmute ADC and set the default input to mic-in
15754 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15759 * Note: PASD motherboards uses the Line In 2 as the input for front
15760 * panel mic (mic 2)
15762 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15763 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15764 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15765 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15770 * Set up output mixers (0x0c - 0x0f)
15772 /* set vol=0 to output mixers */
15773 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15774 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15775 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15777 /* set up input amps for analog loopback */
15778 /* Amp Indices: DAC = 0, mixer = 1 */
15779 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15781 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787 /* FIXME: use matrix-type input source selection */
15788 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795 /* additional verbs for ALC663 */
15796 static struct hda_verb alc663_auto_init_verbs[] = {
15797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15802 static struct hda_verb alc663_m51va_init_verbs[] = {
15803 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15804 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15805 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15806 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15807 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15808 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15810 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15811 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15815 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15816 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15817 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15821 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15822 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15826 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15827 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15828 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15830 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15834 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15838 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15839 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15840 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15841 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15842 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15843 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15844 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15845 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15849 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15850 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15851 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15852 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15853 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15860 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15865 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15866 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15868 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15872 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15875 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15876 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15877 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15881 static struct hda_verb alc663_g71v_init_verbs[] = {
15882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15883 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15884 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15886 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15887 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15888 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15890 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15892 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15896 static struct hda_verb alc663_g50v_init_verbs[] = {
15897 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15898 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15899 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15901 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15902 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15906 static struct hda_verb alc662_ecs_init_verbs[] = {
15907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15908 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15909 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15910 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15914 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15915 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15916 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15917 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15924 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15925 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15929 static struct hda_verb alc272_dell_init_verbs[] = {
15930 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15931 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15933 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15934 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15935 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15936 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15939 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15940 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15944 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15945 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15946 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15950 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15951 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15952 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15956 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15958 unsigned int present;
15959 unsigned char bits;
15961 present = snd_hda_codec_read(codec, 0x14, 0,
15962 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15963 bits = present ? HDA_AMP_MUTE : 0;
15964 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15965 HDA_AMP_MUTE, bits);
15968 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15970 unsigned int present;
15971 unsigned char bits;
15973 present = snd_hda_codec_read(codec, 0x1b, 0,
15974 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15975 bits = present ? HDA_AMP_MUTE : 0;
15976 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15977 HDA_AMP_MUTE, bits);
15978 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15979 HDA_AMP_MUTE, bits);
15982 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15985 if ((res >> 26) == ALC880_HP_EVENT)
15986 alc662_lenovo_101e_all_automute(codec);
15987 if ((res >> 26) == ALC880_FRONT_EVENT)
15988 alc662_lenovo_101e_ispeaker_automute(codec);
15991 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15993 unsigned int present;
15995 present = snd_hda_codec_read(codec, 0x18, 0,
15996 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15997 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15998 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15999 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16000 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16001 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16002 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16003 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16004 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16007 /* unsolicited event for HP jack sensing */
16008 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16011 if ((res >> 26) == ALC880_MIC_EVENT)
16012 alc662_eeepc_mic_automute(codec);
16014 alc262_hippo_unsol_event(codec, res);
16017 static void alc662_eeepc_inithook(struct hda_codec *codec)
16019 alc262_hippo1_init_hook(codec);
16020 alc662_eeepc_mic_automute(codec);
16023 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16025 struct alc_spec *spec = codec->spec;
16027 spec->autocfg.hp_pins[0] = 0x14;
16028 spec->autocfg.speaker_pins[0] = 0x1b;
16029 alc262_hippo_master_update(codec);
16032 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16034 unsigned int present;
16035 unsigned char bits;
16037 present = snd_hda_codec_read(codec, 0x21, 0,
16038 AC_VERB_GET_PIN_SENSE, 0)
16039 & AC_PINSENSE_PRESENCE;
16040 bits = present ? HDA_AMP_MUTE : 0;
16041 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16042 AMP_IN_MUTE(0), bits);
16043 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16044 AMP_IN_MUTE(0), bits);
16047 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16049 unsigned int present;
16050 unsigned char bits;
16052 present = snd_hda_codec_read(codec, 0x21, 0,
16053 AC_VERB_GET_PIN_SENSE, 0)
16054 & AC_PINSENSE_PRESENCE;
16055 bits = present ? HDA_AMP_MUTE : 0;
16056 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16057 AMP_IN_MUTE(0), bits);
16058 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16059 AMP_IN_MUTE(0), bits);
16060 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16061 AMP_IN_MUTE(0), bits);
16062 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16063 AMP_IN_MUTE(0), bits);
16066 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16068 unsigned int present;
16069 unsigned char bits;
16071 present = snd_hda_codec_read(codec, 0x15, 0,
16072 AC_VERB_GET_PIN_SENSE, 0)
16073 & AC_PINSENSE_PRESENCE;
16074 bits = present ? HDA_AMP_MUTE : 0;
16075 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16076 AMP_IN_MUTE(0), bits);
16077 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16078 AMP_IN_MUTE(0), bits);
16079 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16080 AMP_IN_MUTE(0), bits);
16081 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16082 AMP_IN_MUTE(0), bits);
16085 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16087 unsigned int present;
16088 unsigned char bits;
16090 present = snd_hda_codec_read(codec, 0x1b, 0,
16091 AC_VERB_GET_PIN_SENSE, 0)
16092 & AC_PINSENSE_PRESENCE;
16093 bits = present ? 0 : PIN_OUT;
16094 snd_hda_codec_write(codec, 0x14, 0,
16095 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16098 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16100 unsigned int present1, present2;
16102 present1 = snd_hda_codec_read(codec, 0x21, 0,
16103 AC_VERB_GET_PIN_SENSE, 0)
16104 & AC_PINSENSE_PRESENCE;
16105 present2 = snd_hda_codec_read(codec, 0x15, 0,
16106 AC_VERB_GET_PIN_SENSE, 0)
16107 & AC_PINSENSE_PRESENCE;
16109 if (present1 || present2) {
16110 snd_hda_codec_write_cache(codec, 0x14, 0,
16111 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16113 snd_hda_codec_write_cache(codec, 0x14, 0,
16114 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16118 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16120 unsigned int present1, present2;
16122 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16123 AC_VERB_GET_PIN_SENSE, 0)
16124 & AC_PINSENSE_PRESENCE;
16125 present2 = snd_hda_codec_read(codec, 0x15, 0,
16126 AC_VERB_GET_PIN_SENSE, 0)
16127 & AC_PINSENSE_PRESENCE;
16129 if (present1 || present2) {
16130 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16131 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16132 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16133 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16135 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16136 AMP_IN_MUTE(0), 0);
16137 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16138 AMP_IN_MUTE(0), 0);
16142 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16144 unsigned int present;
16146 present = snd_hda_codec_read(codec, 0x18, 0,
16147 AC_VERB_GET_PIN_SENSE, 0)
16148 & AC_PINSENSE_PRESENCE;
16149 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16150 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16151 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16152 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16153 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16154 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16155 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16156 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16159 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16162 switch (res >> 26) {
16163 case ALC880_HP_EVENT:
16164 alc663_m51va_speaker_automute(codec);
16166 case ALC880_MIC_EVENT:
16167 alc663_m51va_mic_automute(codec);
16172 static void alc663_m51va_inithook(struct hda_codec *codec)
16174 alc663_m51va_speaker_automute(codec);
16175 alc663_m51va_mic_automute(codec);
16178 /* ***************** Mode1 ******************************/
16179 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16182 switch (res >> 26) {
16183 case ALC880_HP_EVENT:
16184 alc663_m51va_speaker_automute(codec);
16186 case ALC880_MIC_EVENT:
16187 alc662_eeepc_mic_automute(codec);
16192 static void alc663_mode1_inithook(struct hda_codec *codec)
16194 alc663_m51va_speaker_automute(codec);
16195 alc662_eeepc_mic_automute(codec);
16197 /* ***************** Mode2 ******************************/
16198 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16201 switch (res >> 26) {
16202 case ALC880_HP_EVENT:
16203 alc662_f5z_speaker_automute(codec);
16205 case ALC880_MIC_EVENT:
16206 alc662_eeepc_mic_automute(codec);
16211 static void alc662_mode2_inithook(struct hda_codec *codec)
16213 alc662_f5z_speaker_automute(codec);
16214 alc662_eeepc_mic_automute(codec);
16216 /* ***************** Mode3 ******************************/
16217 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16220 switch (res >> 26) {
16221 case ALC880_HP_EVENT:
16222 alc663_two_hp_m1_speaker_automute(codec);
16224 case ALC880_MIC_EVENT:
16225 alc662_eeepc_mic_automute(codec);
16230 static void alc663_mode3_inithook(struct hda_codec *codec)
16232 alc663_two_hp_m1_speaker_automute(codec);
16233 alc662_eeepc_mic_automute(codec);
16235 /* ***************** Mode4 ******************************/
16236 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16239 switch (res >> 26) {
16240 case ALC880_HP_EVENT:
16241 alc663_21jd_two_speaker_automute(codec);
16243 case ALC880_MIC_EVENT:
16244 alc662_eeepc_mic_automute(codec);
16249 static void alc663_mode4_inithook(struct hda_codec *codec)
16251 alc663_21jd_two_speaker_automute(codec);
16252 alc662_eeepc_mic_automute(codec);
16254 /* ***************** Mode5 ******************************/
16255 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16258 switch (res >> 26) {
16259 case ALC880_HP_EVENT:
16260 alc663_15jd_two_speaker_automute(codec);
16262 case ALC880_MIC_EVENT:
16263 alc662_eeepc_mic_automute(codec);
16268 static void alc663_mode5_inithook(struct hda_codec *codec)
16270 alc663_15jd_two_speaker_automute(codec);
16271 alc662_eeepc_mic_automute(codec);
16273 /* ***************** Mode6 ******************************/
16274 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16277 switch (res >> 26) {
16278 case ALC880_HP_EVENT:
16279 alc663_two_hp_m2_speaker_automute(codec);
16281 case ALC880_MIC_EVENT:
16282 alc662_eeepc_mic_automute(codec);
16287 static void alc663_mode6_inithook(struct hda_codec *codec)
16289 alc663_two_hp_m2_speaker_automute(codec);
16290 alc662_eeepc_mic_automute(codec);
16293 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16295 unsigned int present;
16296 unsigned char bits;
16298 present = snd_hda_codec_read(codec, 0x21, 0,
16299 AC_VERB_GET_PIN_SENSE, 0)
16300 & AC_PINSENSE_PRESENCE;
16301 bits = present ? HDA_AMP_MUTE : 0;
16302 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16303 HDA_AMP_MUTE, bits);
16304 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16305 HDA_AMP_MUTE, bits);
16308 static void alc663_g71v_front_automute(struct hda_codec *codec)
16310 unsigned int present;
16311 unsigned char bits;
16313 present = snd_hda_codec_read(codec, 0x15, 0,
16314 AC_VERB_GET_PIN_SENSE, 0)
16315 & AC_PINSENSE_PRESENCE;
16316 bits = present ? HDA_AMP_MUTE : 0;
16317 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16318 HDA_AMP_MUTE, bits);
16321 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16324 switch (res >> 26) {
16325 case ALC880_HP_EVENT:
16326 alc663_g71v_hp_automute(codec);
16328 case ALC880_FRONT_EVENT:
16329 alc663_g71v_front_automute(codec);
16331 case ALC880_MIC_EVENT:
16332 alc662_eeepc_mic_automute(codec);
16337 static void alc663_g71v_inithook(struct hda_codec *codec)
16339 alc663_g71v_front_automute(codec);
16340 alc663_g71v_hp_automute(codec);
16341 alc662_eeepc_mic_automute(codec);
16344 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16347 switch (res >> 26) {
16348 case ALC880_HP_EVENT:
16349 alc663_m51va_speaker_automute(codec);
16351 case ALC880_MIC_EVENT:
16352 alc662_eeepc_mic_automute(codec);
16357 static void alc663_g50v_inithook(struct hda_codec *codec)
16359 alc663_m51va_speaker_automute(codec);
16360 alc662_eeepc_mic_automute(codec);
16363 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16364 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16365 ALC262_HIPPO_MASTER_SWITCH,
16367 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16368 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16369 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16371 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16372 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16373 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16377 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16378 /* Master Playback automatically created from Speaker and Headphone */
16379 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16380 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16381 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16384 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16385 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16386 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16388 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16389 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16390 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16394 #ifdef CONFIG_SND_HDA_POWER_SAVE
16395 #define alc662_loopbacks alc880_loopbacks
16399 /* pcm configuration: identical with ALC880 */
16400 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16401 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16402 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16403 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16406 * configuration and preset
16408 static const char *alc662_models[ALC662_MODEL_LAST] = {
16409 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16410 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16411 [ALC662_3ST_6ch] = "3stack-6ch",
16412 [ALC662_5ST_DIG] = "6stack-dig",
16413 [ALC662_LENOVO_101E] = "lenovo-101e",
16414 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16415 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16416 [ALC662_ECS] = "ecs",
16417 [ALC663_ASUS_M51VA] = "m51va",
16418 [ALC663_ASUS_G71V] = "g71v",
16419 [ALC663_ASUS_H13] = "h13",
16420 [ALC663_ASUS_G50V] = "g50v",
16421 [ALC663_ASUS_MODE1] = "asus-mode1",
16422 [ALC662_ASUS_MODE2] = "asus-mode2",
16423 [ALC663_ASUS_MODE3] = "asus-mode3",
16424 [ALC663_ASUS_MODE4] = "asus-mode4",
16425 [ALC663_ASUS_MODE5] = "asus-mode5",
16426 [ALC663_ASUS_MODE6] = "asus-mode6",
16427 [ALC272_DELL] = "dell",
16428 [ALC272_DELL_ZM1] = "dell-zm1",
16429 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16430 [ALC662_AUTO] = "auto",
16433 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16434 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16435 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16436 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16437 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16438 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16439 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16440 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16441 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16442 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16443 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16444 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16445 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16446 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16447 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16448 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16449 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16450 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16451 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16452 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16453 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16454 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16455 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16456 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16457 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16458 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16459 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16460 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16461 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16462 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16463 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16464 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16465 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16466 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16467 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16468 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16469 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16470 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16471 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16472 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16473 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16474 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16475 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16476 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16477 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16478 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16479 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16480 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16481 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16482 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16483 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16484 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16485 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16486 ALC662_3ST_6ch_DIG),
16487 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16488 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16489 ALC662_3ST_6ch_DIG),
16490 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16491 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16492 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16493 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16494 ALC662_3ST_6ch_DIG),
16495 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16500 static struct alc_config_preset alc662_presets[] = {
16501 [ALC662_3ST_2ch_DIG] = {
16502 .mixers = { alc662_3ST_2ch_mixer },
16503 .init_verbs = { alc662_init_verbs },
16504 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16505 .dac_nids = alc662_dac_nids,
16506 .dig_out_nid = ALC662_DIGOUT_NID,
16507 .dig_in_nid = ALC662_DIGIN_NID,
16508 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16509 .channel_mode = alc662_3ST_2ch_modes,
16510 .input_mux = &alc662_capture_source,
16512 [ALC662_3ST_6ch_DIG] = {
16513 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16514 .init_verbs = { alc662_init_verbs },
16515 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16516 .dac_nids = alc662_dac_nids,
16517 .dig_out_nid = ALC662_DIGOUT_NID,
16518 .dig_in_nid = ALC662_DIGIN_NID,
16519 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16520 .channel_mode = alc662_3ST_6ch_modes,
16522 .input_mux = &alc662_capture_source,
16524 [ALC662_3ST_6ch] = {
16525 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16526 .init_verbs = { alc662_init_verbs },
16527 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16528 .dac_nids = alc662_dac_nids,
16529 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16530 .channel_mode = alc662_3ST_6ch_modes,
16532 .input_mux = &alc662_capture_source,
16534 [ALC662_5ST_DIG] = {
16535 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16536 .init_verbs = { alc662_init_verbs },
16537 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16538 .dac_nids = alc662_dac_nids,
16539 .dig_out_nid = ALC662_DIGOUT_NID,
16540 .dig_in_nid = ALC662_DIGIN_NID,
16541 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16542 .channel_mode = alc662_5stack_modes,
16543 .input_mux = &alc662_capture_source,
16545 [ALC662_LENOVO_101E] = {
16546 .mixers = { alc662_lenovo_101e_mixer },
16547 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16548 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16549 .dac_nids = alc662_dac_nids,
16550 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16551 .channel_mode = alc662_3ST_2ch_modes,
16552 .input_mux = &alc662_lenovo_101e_capture_source,
16553 .unsol_event = alc662_lenovo_101e_unsol_event,
16554 .init_hook = alc662_lenovo_101e_all_automute,
16556 [ALC662_ASUS_EEEPC_P701] = {
16557 .mixers = { alc662_eeepc_p701_mixer },
16558 .init_verbs = { alc662_init_verbs,
16559 alc662_eeepc_sue_init_verbs },
16560 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16561 .dac_nids = alc662_dac_nids,
16562 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16563 .channel_mode = alc662_3ST_2ch_modes,
16564 .input_mux = &alc662_eeepc_capture_source,
16565 .unsol_event = alc662_eeepc_unsol_event,
16566 .init_hook = alc662_eeepc_inithook,
16568 [ALC662_ASUS_EEEPC_EP20] = {
16569 .mixers = { alc662_eeepc_ep20_mixer,
16570 alc662_chmode_mixer },
16571 .init_verbs = { alc662_init_verbs,
16572 alc662_eeepc_ep20_sue_init_verbs },
16573 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16574 .dac_nids = alc662_dac_nids,
16575 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16576 .channel_mode = alc662_3ST_6ch_modes,
16577 .input_mux = &alc662_lenovo_101e_capture_source,
16578 .unsol_event = alc662_eeepc_unsol_event,
16579 .init_hook = alc662_eeepc_ep20_inithook,
16582 .mixers = { alc662_ecs_mixer },
16583 .init_verbs = { alc662_init_verbs,
16584 alc662_ecs_init_verbs },
16585 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16586 .dac_nids = alc662_dac_nids,
16587 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16588 .channel_mode = alc662_3ST_2ch_modes,
16589 .input_mux = &alc662_eeepc_capture_source,
16590 .unsol_event = alc662_eeepc_unsol_event,
16591 .init_hook = alc662_eeepc_inithook,
16593 [ALC663_ASUS_M51VA] = {
16594 .mixers = { alc663_m51va_mixer },
16595 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16596 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16597 .dac_nids = alc662_dac_nids,
16598 .dig_out_nid = ALC662_DIGOUT_NID,
16599 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16600 .channel_mode = alc662_3ST_2ch_modes,
16601 .input_mux = &alc663_m51va_capture_source,
16602 .unsol_event = alc663_m51va_unsol_event,
16603 .init_hook = alc663_m51va_inithook,
16605 [ALC663_ASUS_G71V] = {
16606 .mixers = { alc663_g71v_mixer },
16607 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16608 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16609 .dac_nids = alc662_dac_nids,
16610 .dig_out_nid = ALC662_DIGOUT_NID,
16611 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16612 .channel_mode = alc662_3ST_2ch_modes,
16613 .input_mux = &alc662_eeepc_capture_source,
16614 .unsol_event = alc663_g71v_unsol_event,
16615 .init_hook = alc663_g71v_inithook,
16617 [ALC663_ASUS_H13] = {
16618 .mixers = { alc663_m51va_mixer },
16619 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16620 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16621 .dac_nids = alc662_dac_nids,
16622 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16623 .channel_mode = alc662_3ST_2ch_modes,
16624 .input_mux = &alc663_m51va_capture_source,
16625 .unsol_event = alc663_m51va_unsol_event,
16626 .init_hook = alc663_m51va_inithook,
16628 [ALC663_ASUS_G50V] = {
16629 .mixers = { alc663_g50v_mixer },
16630 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16631 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16632 .dac_nids = alc662_dac_nids,
16633 .dig_out_nid = ALC662_DIGOUT_NID,
16634 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16635 .channel_mode = alc662_3ST_6ch_modes,
16636 .input_mux = &alc663_capture_source,
16637 .unsol_event = alc663_g50v_unsol_event,
16638 .init_hook = alc663_g50v_inithook,
16640 [ALC663_ASUS_MODE1] = {
16641 .mixers = { alc663_m51va_mixer },
16642 .cap_mixer = alc662_auto_capture_mixer,
16643 .init_verbs = { alc662_init_verbs,
16644 alc663_21jd_amic_init_verbs },
16645 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16647 .dac_nids = alc662_dac_nids,
16648 .dig_out_nid = ALC662_DIGOUT_NID,
16649 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16650 .channel_mode = alc662_3ST_2ch_modes,
16651 .input_mux = &alc662_eeepc_capture_source,
16652 .unsol_event = alc663_mode1_unsol_event,
16653 .init_hook = alc663_mode1_inithook,
16655 [ALC662_ASUS_MODE2] = {
16656 .mixers = { alc662_1bjd_mixer },
16657 .cap_mixer = alc662_auto_capture_mixer,
16658 .init_verbs = { alc662_init_verbs,
16659 alc662_1bjd_amic_init_verbs },
16660 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16661 .dac_nids = alc662_dac_nids,
16662 .dig_out_nid = ALC662_DIGOUT_NID,
16663 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16664 .channel_mode = alc662_3ST_2ch_modes,
16665 .input_mux = &alc662_eeepc_capture_source,
16666 .unsol_event = alc662_mode2_unsol_event,
16667 .init_hook = alc662_mode2_inithook,
16669 [ALC663_ASUS_MODE3] = {
16670 .mixers = { alc663_two_hp_m1_mixer },
16671 .cap_mixer = alc662_auto_capture_mixer,
16672 .init_verbs = { alc662_init_verbs,
16673 alc663_two_hp_amic_m1_init_verbs },
16674 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16676 .dac_nids = alc662_dac_nids,
16677 .dig_out_nid = ALC662_DIGOUT_NID,
16678 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16679 .channel_mode = alc662_3ST_2ch_modes,
16680 .input_mux = &alc662_eeepc_capture_source,
16681 .unsol_event = alc663_mode3_unsol_event,
16682 .init_hook = alc663_mode3_inithook,
16684 [ALC663_ASUS_MODE4] = {
16685 .mixers = { alc663_asus_21jd_clfe_mixer },
16686 .cap_mixer = alc662_auto_capture_mixer,
16687 .init_verbs = { alc662_init_verbs,
16688 alc663_21jd_amic_init_verbs},
16689 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16691 .dac_nids = alc662_dac_nids,
16692 .dig_out_nid = ALC662_DIGOUT_NID,
16693 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16694 .channel_mode = alc662_3ST_2ch_modes,
16695 .input_mux = &alc662_eeepc_capture_source,
16696 .unsol_event = alc663_mode4_unsol_event,
16697 .init_hook = alc663_mode4_inithook,
16699 [ALC663_ASUS_MODE5] = {
16700 .mixers = { alc663_asus_15jd_clfe_mixer },
16701 .cap_mixer = alc662_auto_capture_mixer,
16702 .init_verbs = { alc662_init_verbs,
16703 alc663_15jd_amic_init_verbs },
16704 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16706 .dac_nids = alc662_dac_nids,
16707 .dig_out_nid = ALC662_DIGOUT_NID,
16708 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16709 .channel_mode = alc662_3ST_2ch_modes,
16710 .input_mux = &alc662_eeepc_capture_source,
16711 .unsol_event = alc663_mode5_unsol_event,
16712 .init_hook = alc663_mode5_inithook,
16714 [ALC663_ASUS_MODE6] = {
16715 .mixers = { alc663_two_hp_m2_mixer },
16716 .cap_mixer = alc662_auto_capture_mixer,
16717 .init_verbs = { alc662_init_verbs,
16718 alc663_two_hp_amic_m2_init_verbs },
16719 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16721 .dac_nids = alc662_dac_nids,
16722 .dig_out_nid = ALC662_DIGOUT_NID,
16723 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16724 .channel_mode = alc662_3ST_2ch_modes,
16725 .input_mux = &alc662_eeepc_capture_source,
16726 .unsol_event = alc663_mode6_unsol_event,
16727 .init_hook = alc663_mode6_inithook,
16730 .mixers = { alc663_m51va_mixer },
16731 .cap_mixer = alc272_auto_capture_mixer,
16732 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16733 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16734 .dac_nids = alc662_dac_nids,
16735 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16736 .adc_nids = alc272_adc_nids,
16737 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16738 .capsrc_nids = alc272_capsrc_nids,
16739 .channel_mode = alc662_3ST_2ch_modes,
16740 .input_mux = &alc663_m51va_capture_source,
16741 .unsol_event = alc663_m51va_unsol_event,
16742 .init_hook = alc663_m51va_inithook,
16744 [ALC272_DELL_ZM1] = {
16745 .mixers = { alc663_m51va_mixer },
16746 .cap_mixer = alc662_auto_capture_mixer,
16747 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16748 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16749 .dac_nids = alc662_dac_nids,
16750 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16751 .adc_nids = alc662_adc_nids,
16752 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16753 .capsrc_nids = alc662_capsrc_nids,
16754 .channel_mode = alc662_3ST_2ch_modes,
16755 .input_mux = &alc663_m51va_capture_source,
16756 .unsol_event = alc663_m51va_unsol_event,
16757 .init_hook = alc663_m51va_inithook,
16759 [ALC272_SAMSUNG_NC10] = {
16760 .mixers = { alc272_nc10_mixer },
16761 .init_verbs = { alc662_init_verbs,
16762 alc663_21jd_amic_init_verbs },
16763 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16764 .dac_nids = alc272_dac_nids,
16765 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16766 .channel_mode = alc662_3ST_2ch_modes,
16767 .input_mux = &alc272_nc10_capture_source,
16768 .unsol_event = alc663_mode4_unsol_event,
16769 .init_hook = alc663_mode4_inithook,
16775 * BIOS auto configuration
16778 /* add playback controls from the parsed DAC table */
16779 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16780 const struct auto_pin_cfg *cfg)
16783 static const char *chname[4] = {
16784 "Front", "Surround", NULL /*CLFE*/, "Side"
16789 for (i = 0; i < cfg->line_outs; i++) {
16790 if (!spec->multiout.dac_nids[i])
16792 nid = alc880_idx_to_dac(i);
16795 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16796 "Center Playback Volume",
16797 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16801 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16802 "LFE Playback Volume",
16803 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16807 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16808 "Center Playback Switch",
16809 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16813 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16814 "LFE Playback Switch",
16815 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16820 sprintf(name, "%s Playback Volume", chname[i]);
16821 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16822 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16826 sprintf(name, "%s Playback Switch", chname[i]);
16827 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16828 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16837 /* add playback controls for speaker and HP outputs */
16838 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16849 /* ALC663 has a mono output pin on 0x17 */
16850 sprintf(name, "%s Playback Switch", pfx);
16851 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16852 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16856 if (alc880_is_fixed_pin(pin)) {
16857 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16858 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16859 /* specify the DAC as the extra output */
16860 if (!spec->multiout.hp_nid)
16861 spec->multiout.hp_nid = nid;
16863 spec->multiout.extra_out_nid[0] = nid;
16864 /* control HP volume/switch on the output mixer amp */
16865 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16866 sprintf(name, "%s Playback Volume", pfx);
16867 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16868 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16871 sprintf(name, "%s Playback Switch", pfx);
16872 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16873 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16876 } else if (alc880_is_multi_pin(pin)) {
16877 /* set manual connection */
16878 /* we have only a switch on HP-out PIN */
16879 sprintf(name, "%s Playback Switch", pfx);
16880 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16881 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16888 /* return the index of the src widget from the connection list of the nid.
16889 * return -1 if not found
16891 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16894 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16897 conns = snd_hda_get_connections(codec, nid, conn_list,
16898 ARRAY_SIZE(conn_list));
16901 for (i = 0; i < conns; i++)
16902 if (conn_list[i] == src)
16907 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16909 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16910 return (pincap & AC_PINCAP_IN) != 0;
16913 /* create playback/capture controls for input pins */
16914 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16915 const struct auto_pin_cfg *cfg)
16917 struct alc_spec *spec = codec->spec;
16918 struct hda_input_mux *imux = &spec->private_imux[0];
16921 for (i = 0; i < AUTO_PIN_LAST; i++) {
16922 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16923 idx = alc662_input_pin_idx(codec, 0x0b,
16924 cfg->input_pins[i]);
16926 err = new_analog_input(spec, cfg->input_pins[i],
16927 auto_pin_cfg_labels[i],
16932 idx = alc662_input_pin_idx(codec, 0x22,
16933 cfg->input_pins[i]);
16935 imux->items[imux->num_items].label =
16936 auto_pin_cfg_labels[i];
16937 imux->items[imux->num_items].index = idx;
16945 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16946 hda_nid_t nid, int pin_type,
16949 alc_set_pin_output(codec, nid, pin_type);
16950 /* need the manual connection? */
16951 if (alc880_is_multi_pin(nid)) {
16952 struct alc_spec *spec = codec->spec;
16953 int idx = alc880_multi_pin_idx(nid);
16954 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16955 AC_VERB_SET_CONNECT_SEL,
16956 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16960 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16962 struct alc_spec *spec = codec->spec;
16965 for (i = 0; i <= HDA_SIDE; i++) {
16966 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16967 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16969 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16974 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16976 struct alc_spec *spec = codec->spec;
16979 pin = spec->autocfg.hp_pins[0];
16980 if (pin) /* connect to front */
16982 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16983 pin = spec->autocfg.speaker_pins[0];
16985 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16988 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16990 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16992 struct alc_spec *spec = codec->spec;
16995 for (i = 0; i < AUTO_PIN_LAST; i++) {
16996 hda_nid_t nid = spec->autocfg.input_pins[i];
16997 if (alc662_is_input_pin(codec, nid)) {
16998 alc_set_input_pin(codec, nid, i);
16999 if (nid != ALC662_PIN_CD_NID &&
17000 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17001 snd_hda_codec_write(codec, nid, 0,
17002 AC_VERB_SET_AMP_GAIN_MUTE,
17008 #define alc662_auto_init_input_src alc882_auto_init_input_src
17010 static int alc662_parse_auto_config(struct hda_codec *codec)
17012 struct alc_spec *spec = codec->spec;
17014 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17016 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17020 if (!spec->autocfg.line_outs)
17021 return 0; /* can't find valid BIOS pin config */
17023 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17026 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17029 err = alc662_auto_create_extra_out(spec,
17030 spec->autocfg.speaker_pins[0],
17034 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17038 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17042 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17044 if (spec->autocfg.dig_outs)
17045 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17047 if (spec->kctls.list)
17048 add_mixer(spec, spec->kctls.list);
17050 spec->num_mux_defs = 1;
17051 spec->input_mux = &spec->private_imux[0];
17053 add_verb(spec, alc662_auto_init_verbs);
17054 if (codec->vendor_id == 0x10ec0663)
17055 add_verb(spec, alc663_auto_init_verbs);
17057 err = alc_auto_add_mic_boost(codec);
17061 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17066 /* additional initialization for auto-configuration model */
17067 static void alc662_auto_init(struct hda_codec *codec)
17069 struct alc_spec *spec = codec->spec;
17070 alc662_auto_init_multi_out(codec);
17071 alc662_auto_init_hp_out(codec);
17072 alc662_auto_init_analog_input(codec);
17073 alc662_auto_init_input_src(codec);
17074 if (spec->unsol_event)
17075 alc_inithook(codec);
17078 static int patch_alc662(struct hda_codec *codec)
17080 struct alc_spec *spec;
17081 int err, board_config;
17083 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17087 codec->spec = spec;
17089 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17091 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17094 if (board_config < 0) {
17095 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17096 "trying auto-probe from BIOS...\n", codec->chip_name);
17097 board_config = ALC662_AUTO;
17100 if (board_config == ALC662_AUTO) {
17101 /* automatic parse from the BIOS config */
17102 err = alc662_parse_auto_config(codec);
17108 "hda_codec: Cannot set up configuration "
17109 "from BIOS. Using base mode...\n");
17110 board_config = ALC662_3ST_2ch_DIG;
17114 err = snd_hda_attach_beep_device(codec, 0x1);
17120 if (board_config != ALC662_AUTO)
17121 setup_preset(spec, &alc662_presets[board_config]);
17123 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17124 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17126 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17127 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17129 spec->adc_nids = alc662_adc_nids;
17130 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17131 spec->capsrc_nids = alc662_capsrc_nids;
17133 if (!spec->cap_mixer)
17134 set_capture_mixer(spec);
17135 if (codec->vendor_id == 0x10ec0662)
17136 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17138 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17140 spec->vmaster_nid = 0x02;
17142 codec->patch_ops = alc_patch_ops;
17143 if (board_config == ALC662_AUTO)
17144 spec->init_hook = alc662_auto_init;
17145 #ifdef CONFIG_SND_HDA_POWER_SAVE
17146 if (!spec->loopback.amplist)
17147 spec->loopback.amplist = alc662_loopbacks;
17149 codec->proc_widget_hook = print_realtek_coef;
17157 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17158 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17159 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17160 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17161 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17162 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17163 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17164 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17165 .patch = patch_alc861 },
17166 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17167 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17168 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17169 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17170 .patch = patch_alc882 },
17171 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17172 .patch = patch_alc662 },
17173 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17174 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17175 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17176 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17177 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17178 .patch = patch_alc882 },
17179 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17180 .patch = patch_alc882 },
17181 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17182 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17183 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17184 .patch = patch_alc882 },
17185 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17186 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17187 {} /* terminator */
17190 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17192 MODULE_LICENSE("GPL");
17193 MODULE_DESCRIPTION("Realtek HD-audio codec");
17195 static struct hda_codec_preset_list realtek_list = {
17196 .preset = snd_hda_preset_realtek,
17197 .owner = THIS_MODULE,
17200 static int __init patch_realtek_init(void)
17202 return snd_hda_add_codec_preset(&realtek_list);
17205 static void __exit patch_realtek_exit(void)
17207 snd_hda_delete_codec_preset(&realtek_list);
17210 module_init(patch_realtek_init)
17211 module_exit(patch_realtek_exit)