2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
222 ALC883_TARGA_2ch_DIG,
225 ALC888_ACER_ASPIRE_4930G,
229 ALC883_LENOVO_101E_2ch,
230 ALC883_LENOVO_NB0763,
231 ALC888_LENOVO_MS7195_DIG,
238 ALC883_FUJITSU_PI2515,
239 ALC888_FUJITSU_XA3530,
240 ALC883_3ST_6ch_INTEL,
249 /* styles of capture selection */
251 CAPT_MUX = 0, /* only mux based */
252 CAPT_MIX, /* only mixer based */
253 CAPT_1MUX_MIX, /* first mux and other mixers */
257 #define GPIO_MASK 0x03
259 /* extra amp-initialization sequence types */
269 /* codec parameterization */
270 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
271 unsigned int num_mixers;
272 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
273 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
275 const struct hda_verb *init_verbs[5]; /* initialization verbs
279 unsigned int num_init_verbs;
281 char stream_name_analog[16]; /* analog PCM stream */
282 struct hda_pcm_stream *stream_analog_playback;
283 struct hda_pcm_stream *stream_analog_capture;
284 struct hda_pcm_stream *stream_analog_alt_playback;
285 struct hda_pcm_stream *stream_analog_alt_capture;
287 char stream_name_digital[16]; /* digital PCM stream */
288 struct hda_pcm_stream *stream_digital_playback;
289 struct hda_pcm_stream *stream_digital_capture;
292 struct hda_multi_out multiout; /* playback set-up
293 * max_channels, dacs must be set
294 * dig_out_nid and hp_nid are optional
296 hda_nid_t alt_dac_nid;
297 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
301 unsigned int num_adc_nids;
303 hda_nid_t *capsrc_nids;
304 hda_nid_t dig_in_nid; /* digital-in NID; optional */
305 int capture_style; /* capture style (CAPT_*) */
308 unsigned int num_mux_defs;
309 const struct hda_input_mux *input_mux;
310 unsigned int cur_mux[3];
313 const struct hda_channel_mode *channel_mode;
314 int num_channel_mode;
317 /* PCM information */
318 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
320 /* dynamic controls, init_verbs and input_mux */
321 struct auto_pin_cfg autocfg;
322 struct snd_array kctls;
323 struct hda_input_mux private_imux[3];
324 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
327 void (*init_hook)(struct hda_codec *codec);
328 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
330 /* for pin sensing */
331 unsigned int sense_updated: 1;
332 unsigned int jack_present: 1;
333 unsigned int master_sw: 1;
336 unsigned int no_analog :1; /* digital I/O only */
339 /* for virtual master */
340 hda_nid_t vmaster_nid;
341 #ifdef CONFIG_SND_HDA_POWER_SAVE
342 struct hda_loopback_check loopback;
347 unsigned int pll_coef_idx, pll_coef_bit;
351 * configuration template - to be copied to the spec instance
353 struct alc_config_preset {
354 struct snd_kcontrol_new *mixers[5]; /* should be identical size
357 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
358 const struct hda_verb *init_verbs[5];
359 unsigned int num_dacs;
361 hda_nid_t dig_out_nid; /* optional */
362 hda_nid_t hp_nid; /* optional */
363 hda_nid_t *slave_dig_outs;
364 unsigned int num_adc_nids;
366 hda_nid_t *capsrc_nids;
367 hda_nid_t dig_in_nid;
368 unsigned int num_channel_mode;
369 const struct hda_channel_mode *channel_mode;
371 unsigned int num_mux_defs;
372 const struct hda_input_mux *input_mux;
373 void (*unsol_event)(struct hda_codec *, unsigned int);
374 void (*init_hook)(struct hda_codec *);
375 #ifdef CONFIG_SND_HDA_POWER_SAVE
376 struct hda_amp_list *loopbacks;
384 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
385 struct snd_ctl_elem_info *uinfo)
387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
388 struct alc_spec *spec = codec->spec;
389 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
390 if (mux_idx >= spec->num_mux_defs)
392 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
395 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol)
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct alc_spec *spec = codec->spec;
400 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
402 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
406 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
407 struct snd_ctl_elem_value *ucontrol)
409 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
410 struct alc_spec *spec = codec->spec;
411 const struct hda_input_mux *imux;
412 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
413 unsigned int mux_idx;
414 hda_nid_t nid = spec->capsrc_nids ?
415 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
417 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
418 imux = &spec->input_mux[mux_idx];
420 if (spec->capture_style &&
421 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
422 /* Matrix-mixer style (e.g. ALC882) */
423 unsigned int *cur_val = &spec->cur_mux[adc_idx];
426 idx = ucontrol->value.enumerated.item[0];
427 if (idx >= imux->num_items)
428 idx = imux->num_items - 1;
431 for (i = 0; i < imux->num_items; i++) {
432 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
433 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
434 imux->items[i].index,
440 /* MUX style (e.g. ALC880) */
441 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
442 &spec->cur_mux[adc_idx]);
447 * channel mode setting
449 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
450 struct snd_ctl_elem_info *uinfo)
452 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
453 struct alc_spec *spec = codec->spec;
454 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
455 spec->num_channel_mode);
458 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
463 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
464 spec->num_channel_mode,
465 spec->multiout.max_channels);
468 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 struct alc_spec *spec = codec->spec;
473 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
474 spec->num_channel_mode,
475 &spec->multiout.max_channels);
476 if (err >= 0 && spec->need_dac_fix)
477 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
482 * Control the mode of pin widget settings via the mixer. "pc" is used
483 * instead of "%" to avoid consequences of accidently treating the % as
484 * being part of a format specifier. Maximum allowed length of a value is
485 * 63 characters plus NULL terminator.
487 * Note: some retasking pin complexes seem to ignore requests for input
488 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
489 * are requested. Therefore order this list so that this behaviour will not
490 * cause problems when mixer clients move through the enum sequentially.
491 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
494 static char *alc_pin_mode_names[] = {
495 "Mic 50pc bias", "Mic 80pc bias",
496 "Line in", "Line out", "Headphone out",
498 static unsigned char alc_pin_mode_values[] = {
499 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
501 /* The control can present all 5 options, or it can limit the options based
502 * in the pin being assumed to be exclusively an input or an output pin. In
503 * addition, "input" pins may or may not process the mic bias option
504 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
505 * accept requests for bias as of chip versions up to March 2006) and/or
506 * wiring in the computer.
508 #define ALC_PIN_DIR_IN 0x00
509 #define ALC_PIN_DIR_OUT 0x01
510 #define ALC_PIN_DIR_INOUT 0x02
511 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
512 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
514 /* Info about the pin modes supported by the different pin direction modes.
515 * For each direction the minimum and maximum values are given.
517 static signed char alc_pin_mode_dir_info[5][2] = {
518 { 0, 2 }, /* ALC_PIN_DIR_IN */
519 { 3, 4 }, /* ALC_PIN_DIR_OUT */
520 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
521 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
522 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
524 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
525 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
526 #define alc_pin_mode_n_items(_dir) \
527 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
529 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
530 struct snd_ctl_elem_info *uinfo)
532 unsigned int item_num = uinfo->value.enumerated.item;
533 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
535 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
537 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
539 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
540 item_num = alc_pin_mode_min(dir);
541 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
545 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
546 struct snd_ctl_elem_value *ucontrol)
549 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
550 hda_nid_t nid = kcontrol->private_value & 0xffff;
551 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
552 long *valp = ucontrol->value.integer.value;
553 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
554 AC_VERB_GET_PIN_WIDGET_CONTROL,
557 /* Find enumerated value for current pinctl setting */
558 i = alc_pin_mode_min(dir);
559 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
561 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
565 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
566 struct snd_ctl_elem_value *ucontrol)
569 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
570 hda_nid_t nid = kcontrol->private_value & 0xffff;
571 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
572 long val = *ucontrol->value.integer.value;
573 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
574 AC_VERB_GET_PIN_WIDGET_CONTROL,
577 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
578 val = alc_pin_mode_min(dir);
580 change = pinctl != alc_pin_mode_values[val];
582 /* Set pin mode to that requested */
583 snd_hda_codec_write_cache(codec, nid, 0,
584 AC_VERB_SET_PIN_WIDGET_CONTROL,
585 alc_pin_mode_values[val]);
587 /* Also enable the retasking pin's input/output as required
588 * for the requested pin mode. Enum values of 2 or less are
591 * Dynamically switching the input/output buffers probably
592 * reduces noise slightly (particularly on input) so we'll
593 * do it. However, having both input and output buffers
594 * enabled simultaneously doesn't seem to be problematic if
595 * this turns out to be necessary in the future.
598 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
599 HDA_AMP_MUTE, HDA_AMP_MUTE);
600 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
603 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
604 HDA_AMP_MUTE, HDA_AMP_MUTE);
605 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
612 #define ALC_PIN_MODE(xname, nid, dir) \
613 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
614 .info = alc_pin_mode_info, \
615 .get = alc_pin_mode_get, \
616 .put = alc_pin_mode_put, \
617 .private_value = nid | (dir<<16) }
619 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
620 * together using a mask with more than one bit set. This control is
621 * currently used only by the ALC260 test model. At this stage they are not
622 * needed for any "production" models.
624 #ifdef CONFIG_SND_DEBUG
625 #define alc_gpio_data_info snd_ctl_boolean_mono_info
627 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
631 hda_nid_t nid = kcontrol->private_value & 0xffff;
632 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
633 long *valp = ucontrol->value.integer.value;
634 unsigned int val = snd_hda_codec_read(codec, nid, 0,
635 AC_VERB_GET_GPIO_DATA, 0x00);
637 *valp = (val & mask) != 0;
640 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_value *ucontrol)
644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
645 hda_nid_t nid = kcontrol->private_value & 0xffff;
646 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
647 long val = *ucontrol->value.integer.value;
648 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
649 AC_VERB_GET_GPIO_DATA,
652 /* Set/unset the masked GPIO bit(s) as needed */
653 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
658 snd_hda_codec_write_cache(codec, nid, 0,
659 AC_VERB_SET_GPIO_DATA, gpio_data);
663 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
664 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
665 .info = alc_gpio_data_info, \
666 .get = alc_gpio_data_get, \
667 .put = alc_gpio_data_put, \
668 .private_value = nid | (mask<<16) }
669 #endif /* CONFIG_SND_DEBUG */
671 /* A switch control to allow the enabling of the digital IO pins on the
672 * ALC260. This is incredibly simplistic; the intention of this control is
673 * to provide something in the test model allowing digital outputs to be
674 * identified if present. If models are found which can utilise these
675 * outputs a more complete mixer control can be devised for those models if
678 #ifdef CONFIG_SND_DEBUG
679 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
681 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
682 struct snd_ctl_elem_value *ucontrol)
684 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
685 hda_nid_t nid = kcontrol->private_value & 0xffff;
686 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
687 long *valp = ucontrol->value.integer.value;
688 unsigned int val = snd_hda_codec_read(codec, nid, 0,
689 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
691 *valp = (val & mask) != 0;
694 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
695 struct snd_ctl_elem_value *ucontrol)
698 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
699 hda_nid_t nid = kcontrol->private_value & 0xffff;
700 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
701 long val = *ucontrol->value.integer.value;
702 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
703 AC_VERB_GET_DIGI_CONVERT_1,
706 /* Set/unset the masked control bit(s) as needed */
707 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
712 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
717 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
718 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
719 .info = alc_spdif_ctrl_info, \
720 .get = alc_spdif_ctrl_get, \
721 .put = alc_spdif_ctrl_put, \
722 .private_value = nid | (mask<<16) }
723 #endif /* CONFIG_SND_DEBUG */
725 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
726 * Again, this is only used in the ALC26x test models to help identify when
727 * the EAPD line must be asserted for features to work.
729 #ifdef CONFIG_SND_DEBUG
730 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
732 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_value *ucontrol)
735 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
736 hda_nid_t nid = kcontrol->private_value & 0xffff;
737 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
738 long *valp = ucontrol->value.integer.value;
739 unsigned int val = snd_hda_codec_read(codec, nid, 0,
740 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
742 *valp = (val & mask) != 0;
746 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
747 struct snd_ctl_elem_value *ucontrol)
750 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
751 hda_nid_t nid = kcontrol->private_value & 0xffff;
752 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
753 long val = *ucontrol->value.integer.value;
754 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
755 AC_VERB_GET_EAPD_BTLENABLE,
758 /* Set/unset the masked control bit(s) as needed */
759 change = (!val ? 0 : mask) != (ctrl_data & mask);
764 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
770 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
771 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
772 .info = alc_eapd_ctrl_info, \
773 .get = alc_eapd_ctrl_get, \
774 .put = alc_eapd_ctrl_put, \
775 .private_value = nid | (mask<<16) }
776 #endif /* CONFIG_SND_DEBUG */
779 * set up the input pin config (depending on the given auto-pin type)
781 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
784 unsigned int val = PIN_IN;
786 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
788 pincap = snd_hda_query_pin_caps(codec, nid);
789 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
790 if (pincap & AC_PINCAP_VREF_80)
792 else if (pincap & AC_PINCAP_VREF_50)
794 else if (pincap & AC_PINCAP_VREF_100)
796 else if (pincap & AC_PINCAP_VREF_GRD)
799 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
804 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
806 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
808 spec->mixers[spec->num_mixers++] = mix;
811 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
813 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
815 spec->init_verbs[spec->num_init_verbs++] = verb;
818 #ifdef CONFIG_PROC_FS
822 static void print_realtek_coef(struct snd_info_buffer *buffer,
823 struct hda_codec *codec, hda_nid_t nid)
829 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
830 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
831 coeff = snd_hda_codec_read(codec, nid, 0,
832 AC_VERB_GET_COEF_INDEX, 0);
833 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
836 #define print_realtek_coef NULL
840 * set up from the preset table
842 static void setup_preset(struct alc_spec *spec,
843 const struct alc_config_preset *preset)
847 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
848 add_mixer(spec, preset->mixers[i]);
849 spec->cap_mixer = preset->cap_mixer;
850 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
852 add_verb(spec, preset->init_verbs[i]);
854 spec->channel_mode = preset->channel_mode;
855 spec->num_channel_mode = preset->num_channel_mode;
856 spec->need_dac_fix = preset->need_dac_fix;
858 spec->multiout.max_channels = spec->channel_mode[0].channels;
860 spec->multiout.num_dacs = preset->num_dacs;
861 spec->multiout.dac_nids = preset->dac_nids;
862 spec->multiout.dig_out_nid = preset->dig_out_nid;
863 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
864 spec->multiout.hp_nid = preset->hp_nid;
866 spec->num_mux_defs = preset->num_mux_defs;
867 if (!spec->num_mux_defs)
868 spec->num_mux_defs = 1;
869 spec->input_mux = preset->input_mux;
871 spec->num_adc_nids = preset->num_adc_nids;
872 spec->adc_nids = preset->adc_nids;
873 spec->capsrc_nids = preset->capsrc_nids;
874 spec->dig_in_nid = preset->dig_in_nid;
876 spec->unsol_event = preset->unsol_event;
877 spec->init_hook = preset->init_hook;
878 #ifdef CONFIG_SND_HDA_POWER_SAVE
879 spec->loopback.amplist = preset->loopbacks;
883 /* Enable GPIO mask and set output */
884 static struct hda_verb alc_gpio1_init_verbs[] = {
885 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
887 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
891 static struct hda_verb alc_gpio2_init_verbs[] = {
892 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
893 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
894 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
898 static struct hda_verb alc_gpio3_init_verbs[] = {
899 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
900 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
901 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
906 * Fix hardware PLL issue
907 * On some codecs, the analog PLL gating control must be off while
908 * the default value is 1.
910 static void alc_fix_pll(struct hda_codec *codec)
912 struct alc_spec *spec = codec->spec;
917 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
919 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
920 AC_VERB_GET_PROC_COEF, 0);
921 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
923 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
924 val & ~(1 << spec->pll_coef_bit));
927 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
928 unsigned int coef_idx, unsigned int coef_bit)
930 struct alc_spec *spec = codec->spec;
932 spec->pll_coef_idx = coef_idx;
933 spec->pll_coef_bit = coef_bit;
937 static void alc_automute_pin(struct hda_codec *codec)
939 struct alc_spec *spec = codec->spec;
940 unsigned int present;
941 unsigned int nid = spec->autocfg.hp_pins[0];
944 /* need to execute and sync at first */
945 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
946 present = snd_hda_codec_read(codec, nid, 0,
947 AC_VERB_GET_PIN_SENSE, 0);
948 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
949 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
950 nid = spec->autocfg.speaker_pins[i];
953 snd_hda_codec_write(codec, nid, 0,
954 AC_VERB_SET_PIN_WIDGET_CONTROL,
955 spec->jack_present ? 0 : PIN_OUT);
959 #if 0 /* it's broken in some acses -- temporarily disabled */
960 static void alc_mic_automute(struct hda_codec *codec)
962 struct alc_spec *spec = codec->spec;
963 unsigned int present;
964 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
965 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
966 unsigned int mix_nid = spec->capsrc_nids[0];
967 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
969 capsrc_idx_mic = mic_nid - 0x18;
970 capsrc_idx_fmic = fmic_nid - 0x18;
971 present = snd_hda_codec_read(codec, mic_nid, 0,
972 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
973 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
974 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
975 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
976 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
977 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
978 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
981 #define alc_mic_automute(codec) do {} while(0) /* NOP */
982 #endif /* disabled */
984 /* unsolicited event for HP jack sensing */
985 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
987 if (codec->vendor_id == 0x10ec0880)
992 case ALC880_HP_EVENT:
993 alc_automute_pin(codec);
995 case ALC880_MIC_EVENT:
996 alc_mic_automute(codec);
1001 static void alc_inithook(struct hda_codec *codec)
1003 alc_automute_pin(codec);
1004 alc_mic_automute(codec);
1007 /* additional initialization for ALC888 variants */
1008 static void alc888_coef_init(struct hda_codec *codec)
1012 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1013 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1014 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1015 if ((tmp & 0xf0) == 0x20)
1017 snd_hda_codec_read(codec, 0x20, 0,
1018 AC_VERB_SET_PROC_COEF, 0x830);
1021 snd_hda_codec_read(codec, 0x20, 0,
1022 AC_VERB_SET_PROC_COEF, 0x3030);
1025 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1030 case ALC_INIT_GPIO1:
1031 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1033 case ALC_INIT_GPIO2:
1034 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1036 case ALC_INIT_GPIO3:
1037 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1039 case ALC_INIT_DEFAULT:
1040 switch (codec->vendor_id) {
1042 snd_hda_codec_write(codec, 0x0f, 0,
1043 AC_VERB_SET_EAPD_BTLENABLE, 2);
1044 snd_hda_codec_write(codec, 0x10, 0,
1045 AC_VERB_SET_EAPD_BTLENABLE, 2);
1057 snd_hda_codec_write(codec, 0x14, 0,
1058 AC_VERB_SET_EAPD_BTLENABLE, 2);
1059 snd_hda_codec_write(codec, 0x15, 0,
1060 AC_VERB_SET_EAPD_BTLENABLE, 2);
1063 switch (codec->vendor_id) {
1065 snd_hda_codec_write(codec, 0x1a, 0,
1066 AC_VERB_SET_COEF_INDEX, 7);
1067 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1068 AC_VERB_GET_PROC_COEF, 0);
1069 snd_hda_codec_write(codec, 0x1a, 0,
1070 AC_VERB_SET_COEF_INDEX, 7);
1071 snd_hda_codec_write(codec, 0x1a, 0,
1072 AC_VERB_SET_PROC_COEF,
1082 snd_hda_codec_write(codec, 0x20, 0,
1083 AC_VERB_SET_COEF_INDEX, 7);
1084 tmp = snd_hda_codec_read(codec, 0x20, 0,
1085 AC_VERB_GET_PROC_COEF, 0);
1086 snd_hda_codec_write(codec, 0x20, 0,
1087 AC_VERB_SET_COEF_INDEX, 7);
1088 snd_hda_codec_write(codec, 0x20, 0,
1089 AC_VERB_SET_PROC_COEF,
1093 alc888_coef_init(codec);
1097 snd_hda_codec_write(codec, 0x20, 0,
1098 AC_VERB_SET_COEF_INDEX, 7);
1099 tmp = snd_hda_codec_read(codec, 0x20, 0,
1100 AC_VERB_GET_PROC_COEF, 0);
1101 snd_hda_codec_write(codec, 0x20, 0,
1102 AC_VERB_SET_COEF_INDEX, 7);
1103 snd_hda_codec_write(codec, 0x20, 0,
1104 AC_VERB_SET_PROC_COEF,
1112 static void alc_init_auto_hp(struct hda_codec *codec)
1114 struct alc_spec *spec = codec->spec;
1116 if (!spec->autocfg.hp_pins[0])
1119 if (!spec->autocfg.speaker_pins[0]) {
1120 if (spec->autocfg.line_out_pins[0] &&
1121 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1122 spec->autocfg.speaker_pins[0] =
1123 spec->autocfg.line_out_pins[0];
1128 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1129 spec->autocfg.hp_pins[0]);
1130 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1131 AC_VERB_SET_UNSOLICITED_ENABLE,
1132 AC_USRSP_EN | ALC880_HP_EVENT);
1133 spec->unsol_event = alc_sku_unsol_event;
1136 /* check subsystem ID and set up device-specific initialization;
1137 * return 1 if initialized, 0 if invalid SSID
1139 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1140 * 31 ~ 16 : Manufacture ID
1142 * 7 ~ 0 : Assembly ID
1143 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1145 static int alc_subsystem_id(struct hda_codec *codec,
1146 hda_nid_t porta, hda_nid_t porte,
1149 unsigned int ass, tmp, i;
1151 struct alc_spec *spec = codec->spec;
1153 ass = codec->subsystem_id & 0xffff;
1154 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1157 /* invalid SSID, check the special NID pin defcfg instead */
1159 * 31~30 : port conetcivity
1162 * 19~16 : Check sum (15:1)
1167 if (codec->vendor_id == 0x10ec0260)
1169 ass = snd_hda_codec_get_pincfg(codec, nid);
1170 snd_printd("realtek: No valid SSID, "
1171 "checking pincfg 0x%08x for NID 0x%x\n",
1173 if (!(ass & 1) && !(ass & 0x100000))
1175 if ((ass >> 30) != 1) /* no physical connection */
1180 for (i = 1; i < 16; i++) {
1184 if (((ass >> 16) & 0xf) != tmp)
1187 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1188 ass & 0xffff, codec->vendor_id);
1192 * 2 : 0 --> Desktop, 1 --> Laptop
1193 * 3~5 : External Amplifier control
1196 tmp = (ass & 0x38) >> 3; /* external Amp control */
1199 spec->init_amp = ALC_INIT_GPIO1;
1202 spec->init_amp = ALC_INIT_GPIO2;
1205 spec->init_amp = ALC_INIT_GPIO3;
1208 spec->init_amp = ALC_INIT_DEFAULT;
1212 /* is laptop or Desktop and enable the function "Mute internal speaker
1213 * when the external headphone out jack is plugged"
1215 if (!(ass & 0x8000))
1218 * 10~8 : Jack location
1219 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1221 * 15 : 1 --> enable the function "Mute internal speaker
1222 * when the external headphone out jack is plugged"
1224 if (!spec->autocfg.hp_pins[0]) {
1225 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1227 spec->autocfg.hp_pins[0] = porta;
1229 spec->autocfg.hp_pins[0] = porte;
1231 spec->autocfg.hp_pins[0] = portd;
1236 alc_init_auto_hp(codec);
1240 static void alc_ssid_check(struct hda_codec *codec,
1241 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1243 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1244 struct alc_spec *spec = codec->spec;
1245 snd_printd("realtek: "
1246 "Enable default setup for auto mode as fallback\n");
1247 spec->init_amp = ALC_INIT_DEFAULT;
1248 alc_init_auto_hp(codec);
1253 * Fix-up pin default configurations
1261 static void alc_fix_pincfg(struct hda_codec *codec,
1262 const struct snd_pci_quirk *quirk,
1263 const struct alc_pincfg **pinfix)
1265 const struct alc_pincfg *cfg;
1267 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1271 cfg = pinfix[quirk->value];
1272 for (; cfg->nid; cfg++)
1273 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1283 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1284 /* Mic-in jack as mic in */
1285 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1286 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1287 /* Line-in jack as Line in */
1288 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1289 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1290 /* Line-Out as Front */
1291 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1298 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1299 /* Mic-in jack as mic in */
1300 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1301 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1302 /* Line-in jack as Surround */
1303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1305 /* Line-Out as Front */
1306 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1313 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1314 /* Mic-in jack as CLFE */
1315 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1316 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1317 /* Line-in jack as Surround */
1318 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1319 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1320 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1321 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1328 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1329 /* Mic-in jack as CLFE */
1330 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1331 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1332 /* Line-in jack as Surround */
1333 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1334 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1335 /* Line-Out as Side */
1336 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1340 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1341 { 2, alc888_4ST_ch2_intel_init },
1342 { 4, alc888_4ST_ch4_intel_init },
1343 { 6, alc888_4ST_ch6_intel_init },
1344 { 8, alc888_4ST_ch8_intel_init },
1348 * ALC888 Fujitsu Siemens Amillo xa3530
1351 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1352 /* Front Mic: set to PIN_IN (empty by default) */
1353 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1354 /* Connect Internal HP to Front */
1355 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1356 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1357 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1358 /* Connect Bass HP to Front */
1359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1362 /* Connect Line-Out side jack (SPDIF) to Side */
1363 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1364 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1365 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1366 /* Connect Mic jack to CLFE */
1367 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1370 /* Connect Line-in jack to Surround */
1371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1373 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1374 /* Connect HP out jack to Front */
1375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1377 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1378 /* Enable unsolicited event for HP jack and Line-out jack */
1379 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1380 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1384 static void alc_automute_amp(struct hda_codec *codec)
1386 struct alc_spec *spec = codec->spec;
1387 unsigned int val, mute;
1391 spec->jack_present = 0;
1392 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1393 nid = spec->autocfg.hp_pins[i];
1396 val = snd_hda_codec_read(codec, nid, 0,
1397 AC_VERB_GET_PIN_SENSE, 0);
1398 if (val & AC_PINSENSE_PRESENCE) {
1399 spec->jack_present = 1;
1404 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1405 /* Toggle internal speakers muting */
1406 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1407 nid = spec->autocfg.speaker_pins[i];
1410 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1411 HDA_AMP_MUTE, mute);
1415 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1418 if (codec->vendor_id == 0x10ec0880)
1422 if (res == ALC880_HP_EVENT)
1423 alc_automute_amp(codec);
1426 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1428 struct alc_spec *spec = codec->spec;
1430 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1431 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1432 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1433 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1434 alc_automute_amp(codec);
1438 * ALC888 Acer Aspire 4930G model
1441 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1442 /* Front Mic: set to PIN_IN (empty by default) */
1443 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1444 /* Unselect Front Mic by default in input mixer 3 */
1445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1446 /* Enable unsolicited event for HP jack */
1447 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1448 /* Connect Internal HP to front */
1449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1450 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1451 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1452 /* Connect HP out to front */
1453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1459 static struct hda_input_mux alc888_2_capture_sources[2] = {
1460 /* Front mic only available on one ADC */
1467 { "Front Mic", 0xb },
1480 static struct snd_kcontrol_new alc888_base_mixer[] = {
1481 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1482 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1483 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1484 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1485 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1487 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1488 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1489 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1490 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1491 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1492 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1493 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1494 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1495 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1497 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1502 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1504 struct alc_spec *spec = codec->spec;
1506 spec->autocfg.hp_pins[0] = 0x15;
1507 spec->autocfg.speaker_pins[0] = 0x14;
1508 alc_automute_amp(codec);
1512 * ALC880 3-stack model
1514 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1515 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1516 * F-Mic = 0x1b, HP = 0x19
1519 static hda_nid_t alc880_dac_nids[4] = {
1520 /* front, rear, clfe, rear_surr */
1521 0x02, 0x05, 0x04, 0x03
1524 static hda_nid_t alc880_adc_nids[3] = {
1529 /* The datasheet says the node 0x07 is connected from inputs,
1530 * but it shows zero connection in the real implementation on some devices.
1531 * Note: this is a 915GAV bug, fixed on 915GLV
1533 static hda_nid_t alc880_adc_nids_alt[2] = {
1538 #define ALC880_DIGOUT_NID 0x06
1539 #define ALC880_DIGIN_NID 0x0a
1541 static struct hda_input_mux alc880_capture_source = {
1545 { "Front Mic", 0x3 },
1551 /* channel source setting (2/6 channel selection for 3-stack) */
1553 static struct hda_verb alc880_threestack_ch2_init[] = {
1554 /* set line-in to input, mute it */
1555 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1556 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1557 /* set mic-in to input vref 80%, mute it */
1558 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1559 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1564 static struct hda_verb alc880_threestack_ch6_init[] = {
1565 /* set line-in to output, unmute it */
1566 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1567 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1568 /* set mic-in to output, unmute it */
1569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1574 static struct hda_channel_mode alc880_threestack_modes[2] = {
1575 { 2, alc880_threestack_ch2_init },
1576 { 6, alc880_threestack_ch6_init },
1579 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1583 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1588 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1589 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1595 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1599 .name = "Channel Mode",
1600 .info = alc_ch_mode_info,
1601 .get = alc_ch_mode_get,
1602 .put = alc_ch_mode_put,
1607 /* capture mixer elements */
1608 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1609 struct snd_ctl_elem_info *uinfo)
1611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1612 struct alc_spec *spec = codec->spec;
1615 mutex_lock(&codec->control_mutex);
1616 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1618 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1619 mutex_unlock(&codec->control_mutex);
1623 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1624 unsigned int size, unsigned int __user *tlv)
1626 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1627 struct alc_spec *spec = codec->spec;
1630 mutex_lock(&codec->control_mutex);
1631 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1633 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1634 mutex_unlock(&codec->control_mutex);
1638 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1639 struct snd_ctl_elem_value *ucontrol);
1641 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_value *ucontrol,
1645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1646 struct alc_spec *spec = codec->spec;
1647 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1650 mutex_lock(&codec->control_mutex);
1651 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1653 err = func(kcontrol, ucontrol);
1654 mutex_unlock(&codec->control_mutex);
1658 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol)
1661 return alc_cap_getput_caller(kcontrol, ucontrol,
1662 snd_hda_mixer_amp_volume_get);
1665 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1666 struct snd_ctl_elem_value *ucontrol)
1668 return alc_cap_getput_caller(kcontrol, ucontrol,
1669 snd_hda_mixer_amp_volume_put);
1672 /* capture mixer elements */
1673 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1675 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1676 struct snd_ctl_elem_value *ucontrol)
1678 return alc_cap_getput_caller(kcontrol, ucontrol,
1679 snd_hda_mixer_amp_switch_get);
1682 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1683 struct snd_ctl_elem_value *ucontrol)
1685 return alc_cap_getput_caller(kcontrol, ucontrol,
1686 snd_hda_mixer_amp_switch_put);
1689 #define _DEFINE_CAPMIX(num) \
1691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1692 .name = "Capture Switch", \
1693 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1695 .info = alc_cap_sw_info, \
1696 .get = alc_cap_sw_get, \
1697 .put = alc_cap_sw_put, \
1700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1701 .name = "Capture Volume", \
1702 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1703 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1704 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1706 .info = alc_cap_vol_info, \
1707 .get = alc_cap_vol_get, \
1708 .put = alc_cap_vol_put, \
1709 .tlv = { .c = alc_cap_vol_tlv }, \
1712 #define _DEFINE_CAPSRC(num) \
1714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1715 /* .name = "Capture Source", */ \
1716 .name = "Input Source", \
1718 .info = alc_mux_enum_info, \
1719 .get = alc_mux_enum_get, \
1720 .put = alc_mux_enum_put, \
1723 #define DEFINE_CAPMIX(num) \
1724 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1725 _DEFINE_CAPMIX(num), \
1726 _DEFINE_CAPSRC(num), \
1730 #define DEFINE_CAPMIX_NOSRC(num) \
1731 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1732 _DEFINE_CAPMIX(num), \
1736 /* up to three ADCs */
1740 DEFINE_CAPMIX_NOSRC(1);
1741 DEFINE_CAPMIX_NOSRC(2);
1742 DEFINE_CAPMIX_NOSRC(3);
1745 * ALC880 5-stack model
1747 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1749 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1750 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1753 /* additional mixers to alc880_three_stack_mixer */
1754 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1755 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1756 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1760 /* channel source setting (6/8 channel selection for 5-stack) */
1762 static struct hda_verb alc880_fivestack_ch6_init[] = {
1763 /* set line-in to input, mute it */
1764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1765 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1770 static struct hda_verb alc880_fivestack_ch8_init[] = {
1771 /* set line-in to output, unmute it */
1772 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1773 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1777 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1778 { 6, alc880_fivestack_ch6_init },
1779 { 8, alc880_fivestack_ch8_init },
1784 * ALC880 6-stack model
1786 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1787 * Side = 0x05 (0x0f)
1788 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1789 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1792 static hda_nid_t alc880_6st_dac_nids[4] = {
1793 /* front, rear, clfe, rear_surr */
1794 0x02, 0x03, 0x04, 0x05
1797 static struct hda_input_mux alc880_6stack_capture_source = {
1801 { "Front Mic", 0x1 },
1807 /* fixed 8-channels */
1808 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1812 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1813 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1814 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1815 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1816 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1817 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1818 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1819 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1820 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1821 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1822 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1823 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1824 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1825 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1826 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1827 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1828 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1829 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1830 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1833 .name = "Channel Mode",
1834 .info = alc_ch_mode_info,
1835 .get = alc_ch_mode_get,
1836 .put = alc_ch_mode_put,
1845 * W810 has rear IO for:
1848 * Center/LFE (DAC 04)
1851 * The system also has a pair of internal speakers, and a headphone jack.
1852 * These are both connected to Line2 on the codec, hence to DAC 02.
1854 * There is a variable resistor to control the speaker or headphone
1855 * volume. This is a hardware-only device without a software API.
1857 * Plugging headphones in will disable the internal speakers. This is
1858 * implemented in hardware, not via the driver using jack sense. In
1859 * a similar fashion, plugging into the rear socket marked "front" will
1860 * disable both the speakers and headphones.
1862 * For input, there's a microphone jack, and an "audio in" jack.
1863 * These may not do anything useful with this driver yet, because I
1864 * haven't setup any initialization verbs for these yet...
1867 static hda_nid_t alc880_w810_dac_nids[3] = {
1868 /* front, rear/surround, clfe */
1872 /* fixed 6 channels */
1873 static struct hda_channel_mode alc880_w810_modes[1] = {
1877 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1878 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1881 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1882 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1883 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1884 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1885 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1886 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1895 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1896 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1900 static hda_nid_t alc880_z71v_dac_nids[1] = {
1903 #define ALC880_Z71V_HP_DAC 0x03
1905 /* fixed 2 channels */
1906 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1910 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1913 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1914 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1924 * ALC880 F1734 model
1926 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1927 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1930 static hda_nid_t alc880_f1734_dac_nids[1] = {
1933 #define ALC880_F1734_HP_DAC 0x02
1935 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1936 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1937 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1939 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1942 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1947 static struct hda_input_mux alc880_f1734_capture_source = {
1959 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1960 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1961 * Mic = 0x18, Line = 0x1a
1964 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1965 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1967 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1968 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1970 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1971 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1972 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1973 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1974 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1975 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1976 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1977 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1984 .name = "Channel Mode",
1985 .info = alc_ch_mode_info,
1986 .get = alc_ch_mode_get,
1987 .put = alc_ch_mode_put,
1993 * ALC880 ASUS W1V model
1995 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1996 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1997 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2000 /* additional mixers to alc880_asus_mixer */
2001 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2002 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2003 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2008 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2010 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2013 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2014 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2016 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2017 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2022 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2023 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2024 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2025 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2026 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2027 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2028 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2031 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2032 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2035 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2036 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2037 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2038 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2041 .name = "Channel Mode",
2042 .info = alc_ch_mode_info,
2043 .get = alc_ch_mode_get,
2044 .put = alc_ch_mode_put,
2049 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2050 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2051 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2052 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2053 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2054 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2055 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2056 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2057 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2058 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2059 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2063 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2064 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2065 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2066 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2067 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2074 * virtual master controls
2078 * slave controls for virtual master
2080 static const char *alc_slave_vols[] = {
2081 "Front Playback Volume",
2082 "Surround Playback Volume",
2083 "Center Playback Volume",
2084 "LFE Playback Volume",
2085 "Side Playback Volume",
2086 "Headphone Playback Volume",
2087 "Speaker Playback Volume",
2088 "Mono Playback Volume",
2089 "Line-Out Playback Volume",
2090 "PCM Playback Volume",
2094 static const char *alc_slave_sws[] = {
2095 "Front Playback Switch",
2096 "Surround Playback Switch",
2097 "Center Playback Switch",
2098 "LFE Playback Switch",
2099 "Side Playback Switch",
2100 "Headphone Playback Switch",
2101 "Speaker Playback Switch",
2102 "Mono Playback Switch",
2103 "IEC958 Playback Switch",
2108 * build control elements
2111 static void alc_free_kctls(struct hda_codec *codec);
2113 /* additional beep mixers; the actual parameters are overwritten at build */
2114 static struct snd_kcontrol_new alc_beep_mixer[] = {
2115 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2116 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2120 static int alc_build_controls(struct hda_codec *codec)
2122 struct alc_spec *spec = codec->spec;
2126 for (i = 0; i < spec->num_mixers; i++) {
2127 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2131 if (spec->cap_mixer) {
2132 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2136 if (spec->multiout.dig_out_nid) {
2137 err = snd_hda_create_spdif_out_ctls(codec,
2138 spec->multiout.dig_out_nid);
2141 if (!spec->no_analog) {
2142 err = snd_hda_create_spdif_share_sw(codec,
2146 spec->multiout.share_spdif = 1;
2149 if (spec->dig_in_nid) {
2150 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2155 /* create beep controls if needed */
2156 if (spec->beep_amp) {
2157 struct snd_kcontrol_new *knew;
2158 for (knew = alc_beep_mixer; knew->name; knew++) {
2159 struct snd_kcontrol *kctl;
2160 kctl = snd_ctl_new1(knew, codec);
2163 kctl->private_value = spec->beep_amp;
2164 err = snd_hda_ctl_add(codec, kctl);
2170 /* if we have no master control, let's create it */
2171 if (!spec->no_analog &&
2172 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2173 unsigned int vmaster_tlv[4];
2174 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2175 HDA_OUTPUT, vmaster_tlv);
2176 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2177 vmaster_tlv, alc_slave_vols);
2181 if (!spec->no_analog &&
2182 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2183 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2184 NULL, alc_slave_sws);
2189 alc_free_kctls(codec); /* no longer needed */
2195 * initialize the codec volumes, etc
2199 * generic initialization of ADC, input mixers and output mixers
2201 static struct hda_verb alc880_volume_init_verbs[] = {
2203 * Unmute ADC0-2 and set the default input to mic-in
2205 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2207 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2209 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2210 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2212 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2214 * Note: PASD motherboards uses the Line In 2 as the input for front
2217 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2220 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2221 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2223 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2224 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2227 * Set up output mixers (0x0c - 0x0f)
2229 /* set vol=0 to output mixers */
2230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2231 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2234 /* set up input amps for analog loopback */
2235 /* Amp Indices: DAC = 0, mixer = 1 */
2236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2238 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2239 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2240 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2241 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2243 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2249 * 3-stack pin configuration:
2250 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2252 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2254 * preset connection lists of input pins
2255 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2257 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2258 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2259 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2262 * Set pin mode and muting
2264 /* set front pin widgets 0x14 for output */
2265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2266 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2267 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2270 /* Mic2 (as headphone out) for HP output */
2271 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2272 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 /* Line In pin widget for input */
2274 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2275 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2276 /* Line2 (as front mic) pin widget for input and vref at 80% */
2277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2278 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2279 /* CD pin widget for input */
2280 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2286 * 5-stack pin configuration:
2287 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2288 * line-in/side = 0x1a, f-mic = 0x1b
2290 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2292 * preset connection lists of input pins
2293 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2295 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2296 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2299 * Set pin mode and muting
2301 /* set pin widgets 0x14-0x17 for output */
2302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2303 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2304 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2305 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2306 /* unmute pins for output (no gain on this amp) */
2307 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2309 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2312 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2313 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2314 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2315 /* Mic2 (as headphone out) for HP output */
2316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2318 /* Line In pin widget for input */
2319 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2321 /* Line2 (as front mic) pin widget for input and vref at 80% */
2322 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2323 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2324 /* CD pin widget for input */
2325 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2331 * W810 pin configuration:
2332 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2334 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2335 /* hphone/speaker input selector: front DAC */
2336 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2341 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2342 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2345 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2346 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2352 * Z71V pin configuration:
2353 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2355 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2359 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2361 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2362 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2363 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2364 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2370 * 6-stack pin configuration:
2371 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2372 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2374 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2375 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2377 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2378 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2379 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2380 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2381 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2382 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2383 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2384 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2391 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2400 * Uniwill pin configuration:
2401 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2404 static struct hda_verb alc880_uniwill_init_verbs[] = {
2405 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2408 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2409 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2410 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2411 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2412 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2413 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2422 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2423 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2427 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2428 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2429 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2430 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2432 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2440 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2442 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2443 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2446 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2449 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2452 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2455 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2458 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2459 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2460 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2461 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2462 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2463 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2465 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2466 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2471 static struct hda_verb alc880_beep_init_verbs[] = {
2472 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2476 /* auto-toggle front mic */
2477 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2479 unsigned int present;
2482 present = snd_hda_codec_read(codec, 0x18, 0,
2483 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2484 bits = present ? HDA_AMP_MUTE : 0;
2485 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2488 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2490 struct alc_spec *spec = codec->spec;
2492 spec->autocfg.hp_pins[0] = 0x14;
2493 spec->autocfg.speaker_pins[0] = 0x15;
2494 spec->autocfg.speaker_pins[0] = 0x16;
2495 alc_automute_amp(codec);
2496 alc880_uniwill_mic_automute(codec);
2499 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2502 /* Looks like the unsol event is incompatible with the standard
2503 * definition. 4bit tag is placed at 28 bit!
2505 switch (res >> 28) {
2506 case ALC880_MIC_EVENT:
2507 alc880_uniwill_mic_automute(codec);
2510 alc_automute_amp_unsol_event(codec, res);
2515 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2517 struct alc_spec *spec = codec->spec;
2519 spec->autocfg.hp_pins[0] = 0x14;
2520 spec->autocfg.speaker_pins[0] = 0x15;
2521 alc_automute_amp(codec);
2524 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2526 unsigned int present;
2528 present = snd_hda_codec_read(codec, 0x21, 0,
2529 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2530 present &= HDA_AMP_VOLMASK;
2531 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2532 HDA_AMP_VOLMASK, present);
2533 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2534 HDA_AMP_VOLMASK, present);
2537 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2540 /* Looks like the unsol event is incompatible with the standard
2541 * definition. 4bit tag is placed at 28 bit!
2543 if ((res >> 28) == ALC880_DCVOL_EVENT)
2544 alc880_uniwill_p53_dcvol_automute(codec);
2546 alc_automute_amp_unsol_event(codec, res);
2550 * F1734 pin configuration:
2551 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2553 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2554 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2555 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2556 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2557 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2558 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2562 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2567 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2569 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2570 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2571 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2572 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2575 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2576 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2582 * ASUS pin configuration:
2583 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2585 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2586 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2587 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2588 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2589 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2591 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2592 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2594 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2595 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2597 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2600 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2602 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2604 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2605 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2606 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2607 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2608 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2613 /* Enable GPIO mask and set output */
2614 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2615 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2617 /* Clevo m520g init */
2618 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2619 /* headphone output */
2620 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2622 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2623 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2625 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2626 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2628 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2629 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2630 /* Mic1 (rear panel) */
2631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2633 /* Mic2 (front panel) */
2634 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2635 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2639 /* change to EAPD mode */
2640 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2641 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2646 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2647 /* change to EAPD mode */
2648 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2649 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2651 /* Headphone output */
2652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2654 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2655 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2657 /* Line In pin widget for input */
2658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2659 /* CD pin widget for input */
2660 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2661 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2662 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2664 /* change to EAPD mode */
2665 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2666 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2672 * LG m1 express dual
2675 * Rear Line-In/Out (blue): 0x14
2676 * Build-in Mic-In: 0x15
2678 * HP-Out (green): 0x1b
2679 * Mic-In/Out (red): 0x19
2683 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2684 static hda_nid_t alc880_lg_dac_nids[3] = {
2688 /* seems analog CD is not working */
2689 static struct hda_input_mux alc880_lg_capture_source = {
2694 { "Internal Mic", 0x6 },
2698 /* 2,4,6 channel modes */
2699 static struct hda_verb alc880_lg_ch2_init[] = {
2700 /* set line-in and mic-in to input */
2701 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2702 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2706 static struct hda_verb alc880_lg_ch4_init[] = {
2707 /* set line-in to out and mic-in to input */
2708 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2709 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2713 static struct hda_verb alc880_lg_ch6_init[] = {
2714 /* set line-in and mic-in to output */
2715 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2716 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2720 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2721 { 2, alc880_lg_ch2_init },
2722 { 4, alc880_lg_ch4_init },
2723 { 6, alc880_lg_ch6_init },
2726 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2728 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2730 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2731 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2732 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2733 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2734 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2735 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2736 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2737 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2738 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2739 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2740 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2743 .name = "Channel Mode",
2744 .info = alc_ch_mode_info,
2745 .get = alc_ch_mode_get,
2746 .put = alc_ch_mode_put,
2751 static struct hda_verb alc880_lg_init_verbs[] = {
2752 /* set capture source to mic-in */
2753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2756 /* mute all amp mixer inputs */
2757 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2758 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2760 /* line-in to input */
2761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2762 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2764 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2767 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2769 /* mic-in to input */
2770 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2771 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2774 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2775 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2776 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2778 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2782 /* toggle speaker-output according to the hp-jack state */
2783 static void alc880_lg_init_hook(struct hda_codec *codec)
2785 struct alc_spec *spec = codec->spec;
2787 spec->autocfg.hp_pins[0] = 0x1b;
2788 spec->autocfg.speaker_pins[0] = 0x17;
2789 alc_automute_amp(codec);
2798 * Built-in Mic-In: 0x19
2804 static struct hda_input_mux alc880_lg_lw_capture_source = {
2808 { "Internal Mic", 0x1 },
2813 #define alc880_lg_lw_modes alc880_threestack_modes
2815 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2816 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2817 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2818 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2819 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2820 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2821 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2822 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2823 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2824 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2825 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2828 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2829 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2832 .name = "Channel Mode",
2833 .info = alc_ch_mode_info,
2834 .get = alc_ch_mode_get,
2835 .put = alc_ch_mode_put,
2840 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2841 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2842 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2843 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2845 /* set capture source to mic-in */
2846 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2847 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2848 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2854 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2855 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2856 /* mic-in to input */
2857 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2858 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2860 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2863 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2867 /* toggle speaker-output according to the hp-jack state */
2868 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2870 struct alc_spec *spec = codec->spec;
2872 spec->autocfg.hp_pins[0] = 0x1b;
2873 spec->autocfg.speaker_pins[0] = 0x14;
2874 alc_automute_amp(codec);
2877 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2878 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2879 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2882 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2883 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2887 static struct hda_input_mux alc880_medion_rim_capture_source = {
2891 { "Internal Mic", 0x1 },
2895 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2896 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2898 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2903 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2904 /* Mic2 (as headphone out) for HP output */
2905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2907 /* Internal Speaker */
2908 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2909 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2911 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2912 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2914 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2918 /* toggle speaker-output according to the hp-jack state */
2919 static void alc880_medion_rim_automute(struct hda_codec *codec)
2921 struct alc_spec *spec = codec->spec;
2922 alc_automute_amp(codec);
2924 if (spec->jack_present)
2925 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2927 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2930 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2933 /* Looks like the unsol event is incompatible with the standard
2934 * definition. 4bit tag is placed at 28 bit!
2936 if ((res >> 28) == ALC880_HP_EVENT)
2937 alc880_medion_rim_automute(codec);
2940 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
2942 struct alc_spec *spec = codec->spec;
2944 spec->autocfg.hp_pins[0] = 0x14;
2945 spec->autocfg.speaker_pins[0] = 0x1b;
2946 alc880_medion_rim_automute(codec);
2949 #ifdef CONFIG_SND_HDA_POWER_SAVE
2950 static struct hda_amp_list alc880_loopbacks[] = {
2951 { 0x0b, HDA_INPUT, 0 },
2952 { 0x0b, HDA_INPUT, 1 },
2953 { 0x0b, HDA_INPUT, 2 },
2954 { 0x0b, HDA_INPUT, 3 },
2955 { 0x0b, HDA_INPUT, 4 },
2959 static struct hda_amp_list alc880_lg_loopbacks[] = {
2960 { 0x0b, HDA_INPUT, 1 },
2961 { 0x0b, HDA_INPUT, 6 },
2962 { 0x0b, HDA_INPUT, 7 },
2971 static int alc_init(struct hda_codec *codec)
2973 struct alc_spec *spec = codec->spec;
2977 alc_auto_init_amp(codec, spec->init_amp);
2979 for (i = 0; i < spec->num_init_verbs; i++)
2980 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2982 if (spec->init_hook)
2983 spec->init_hook(codec);
2988 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2990 struct alc_spec *spec = codec->spec;
2992 if (spec->unsol_event)
2993 spec->unsol_event(codec, res);
2996 #ifdef CONFIG_SND_HDA_POWER_SAVE
2997 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2999 struct alc_spec *spec = codec->spec;
3000 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3005 * Analog playback callbacks
3007 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3008 struct hda_codec *codec,
3009 struct snd_pcm_substream *substream)
3011 struct alc_spec *spec = codec->spec;
3012 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3016 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3017 struct hda_codec *codec,
3018 unsigned int stream_tag,
3019 unsigned int format,
3020 struct snd_pcm_substream *substream)
3022 struct alc_spec *spec = codec->spec;
3023 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3024 stream_tag, format, substream);
3027 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3028 struct hda_codec *codec,
3029 struct snd_pcm_substream *substream)
3031 struct alc_spec *spec = codec->spec;
3032 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3038 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3039 struct hda_codec *codec,
3040 struct snd_pcm_substream *substream)
3042 struct alc_spec *spec = codec->spec;
3043 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3046 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3047 struct hda_codec *codec,
3048 unsigned int stream_tag,
3049 unsigned int format,
3050 struct snd_pcm_substream *substream)
3052 struct alc_spec *spec = codec->spec;
3053 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3054 stream_tag, format, substream);
3057 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3058 struct hda_codec *codec,
3059 struct snd_pcm_substream *substream)
3061 struct alc_spec *spec = codec->spec;
3062 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3065 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3066 struct hda_codec *codec,
3067 struct snd_pcm_substream *substream)
3069 struct alc_spec *spec = codec->spec;
3070 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3076 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3077 struct hda_codec *codec,
3078 unsigned int stream_tag,
3079 unsigned int format,
3080 struct snd_pcm_substream *substream)
3082 struct alc_spec *spec = codec->spec;
3084 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3085 stream_tag, 0, format);
3089 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3090 struct hda_codec *codec,
3091 struct snd_pcm_substream *substream)
3093 struct alc_spec *spec = codec->spec;
3095 snd_hda_codec_cleanup_stream(codec,
3096 spec->adc_nids[substream->number + 1]);
3103 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3107 /* NID is set in alc_build_pcms */
3109 .open = alc880_playback_pcm_open,
3110 .prepare = alc880_playback_pcm_prepare,
3111 .cleanup = alc880_playback_pcm_cleanup
3115 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3119 /* NID is set in alc_build_pcms */
3122 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3126 /* NID is set in alc_build_pcms */
3129 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3130 .substreams = 2, /* can be overridden */
3133 /* NID is set in alc_build_pcms */
3135 .prepare = alc880_alt_capture_pcm_prepare,
3136 .cleanup = alc880_alt_capture_pcm_cleanup
3140 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3144 /* NID is set in alc_build_pcms */
3146 .open = alc880_dig_playback_pcm_open,
3147 .close = alc880_dig_playback_pcm_close,
3148 .prepare = alc880_dig_playback_pcm_prepare,
3149 .cleanup = alc880_dig_playback_pcm_cleanup
3153 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3157 /* NID is set in alc_build_pcms */
3160 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3161 static struct hda_pcm_stream alc_pcm_null_stream = {
3167 static int alc_build_pcms(struct hda_codec *codec)
3169 struct alc_spec *spec = codec->spec;
3170 struct hda_pcm *info = spec->pcm_rec;
3173 codec->num_pcms = 1;
3174 codec->pcm_info = info;
3176 if (spec->no_analog)
3179 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3180 "%s Analog", codec->chip_name);
3181 info->name = spec->stream_name_analog;
3183 if (spec->stream_analog_playback) {
3184 if (snd_BUG_ON(!spec->multiout.dac_nids))
3186 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3187 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3189 if (spec->stream_analog_capture) {
3190 if (snd_BUG_ON(!spec->adc_nids))
3192 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3193 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3196 if (spec->channel_mode) {
3197 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3198 for (i = 0; i < spec->num_channel_mode; i++) {
3199 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3200 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3206 /* SPDIF for stream index #1 */
3207 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3208 snprintf(spec->stream_name_digital,
3209 sizeof(spec->stream_name_digital),
3210 "%s Digital", codec->chip_name);
3211 codec->num_pcms = 2;
3212 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3213 info = spec->pcm_rec + 1;
3214 info->name = spec->stream_name_digital;
3215 if (spec->dig_out_type)
3216 info->pcm_type = spec->dig_out_type;
3218 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3219 if (spec->multiout.dig_out_nid &&
3220 spec->stream_digital_playback) {
3221 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3222 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3224 if (spec->dig_in_nid &&
3225 spec->stream_digital_capture) {
3226 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3227 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3229 /* FIXME: do we need this for all Realtek codec models? */
3230 codec->spdif_status_reset = 1;
3233 if (spec->no_analog)
3236 /* If the use of more than one ADC is requested for the current
3237 * model, configure a second analog capture-only PCM.
3239 /* Additional Analaog capture for index #2 */
3240 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3241 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3242 codec->num_pcms = 3;
3243 info = spec->pcm_rec + 2;
3244 info->name = spec->stream_name_analog;
3245 if (spec->alt_dac_nid) {
3246 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3247 *spec->stream_analog_alt_playback;
3248 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3251 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3252 alc_pcm_null_stream;
3253 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3255 if (spec->num_adc_nids > 1) {
3256 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3257 *spec->stream_analog_alt_capture;
3258 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3260 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3261 spec->num_adc_nids - 1;
3263 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3264 alc_pcm_null_stream;
3265 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3272 static void alc_free_kctls(struct hda_codec *codec)
3274 struct alc_spec *spec = codec->spec;
3276 if (spec->kctls.list) {
3277 struct snd_kcontrol_new *kctl = spec->kctls.list;
3279 for (i = 0; i < spec->kctls.used; i++)
3280 kfree(kctl[i].name);
3282 snd_array_free(&spec->kctls);
3285 static void alc_free(struct hda_codec *codec)
3287 struct alc_spec *spec = codec->spec;
3292 alc_free_kctls(codec);
3294 snd_hda_detach_beep_device(codec);
3297 #ifdef SND_HDA_NEEDS_RESUME
3298 static int alc_resume(struct hda_codec *codec)
3300 codec->patch_ops.init(codec);
3301 snd_hda_codec_resume_amp(codec);
3302 snd_hda_codec_resume_cache(codec);
3309 static struct hda_codec_ops alc_patch_ops = {
3310 .build_controls = alc_build_controls,
3311 .build_pcms = alc_build_pcms,
3314 .unsol_event = alc_unsol_event,
3315 #ifdef SND_HDA_NEEDS_RESUME
3316 .resume = alc_resume,
3318 #ifdef CONFIG_SND_HDA_POWER_SAVE
3319 .check_power_status = alc_check_power_status,
3325 * Test configuration for debugging
3327 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3330 #ifdef CONFIG_SND_DEBUG
3331 static hda_nid_t alc880_test_dac_nids[4] = {
3332 0x02, 0x03, 0x04, 0x05
3335 static struct hda_input_mux alc880_test_capture_source = {
3344 { "Surround", 0x6 },
3348 static struct hda_channel_mode alc880_test_modes[4] = {
3355 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3356 struct snd_ctl_elem_info *uinfo)
3358 static char *texts[] = {
3359 "N/A", "Line Out", "HP Out",
3360 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3362 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3364 uinfo->value.enumerated.items = 8;
3365 if (uinfo->value.enumerated.item >= 8)
3366 uinfo->value.enumerated.item = 7;
3367 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3371 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3372 struct snd_ctl_elem_value *ucontrol)
3374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3375 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3376 unsigned int pin_ctl, item = 0;
3378 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3379 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3380 if (pin_ctl & AC_PINCTL_OUT_EN) {
3381 if (pin_ctl & AC_PINCTL_HP_EN)
3385 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3386 switch (pin_ctl & AC_PINCTL_VREFEN) {
3387 case AC_PINCTL_VREF_HIZ: item = 3; break;
3388 case AC_PINCTL_VREF_50: item = 4; break;
3389 case AC_PINCTL_VREF_GRD: item = 5; break;
3390 case AC_PINCTL_VREF_80: item = 6; break;
3391 case AC_PINCTL_VREF_100: item = 7; break;
3394 ucontrol->value.enumerated.item[0] = item;
3398 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3399 struct snd_ctl_elem_value *ucontrol)
3401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3402 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3403 static unsigned int ctls[] = {
3404 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3405 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3406 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3407 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3408 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3409 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3411 unsigned int old_ctl, new_ctl;
3413 old_ctl = snd_hda_codec_read(codec, nid, 0,
3414 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3415 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3416 if (old_ctl != new_ctl) {
3418 snd_hda_codec_write_cache(codec, nid, 0,
3419 AC_VERB_SET_PIN_WIDGET_CONTROL,
3421 val = ucontrol->value.enumerated.item[0] >= 3 ?
3423 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3430 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3431 struct snd_ctl_elem_info *uinfo)
3433 static char *texts[] = {
3434 "Front", "Surround", "CLFE", "Side"
3436 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3438 uinfo->value.enumerated.items = 4;
3439 if (uinfo->value.enumerated.item >= 4)
3440 uinfo->value.enumerated.item = 3;
3441 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3445 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3446 struct snd_ctl_elem_value *ucontrol)
3448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3449 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3452 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3453 ucontrol->value.enumerated.item[0] = sel & 3;
3457 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3458 struct snd_ctl_elem_value *ucontrol)
3460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3461 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3464 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3465 if (ucontrol->value.enumerated.item[0] != sel) {
3466 sel = ucontrol->value.enumerated.item[0] & 3;
3467 snd_hda_codec_write_cache(codec, nid, 0,
3468 AC_VERB_SET_CONNECT_SEL, sel);
3474 #define PIN_CTL_TEST(xname,nid) { \
3475 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3477 .info = alc_test_pin_ctl_info, \
3478 .get = alc_test_pin_ctl_get, \
3479 .put = alc_test_pin_ctl_put, \
3480 .private_value = nid \
3483 #define PIN_SRC_TEST(xname,nid) { \
3484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3486 .info = alc_test_pin_src_info, \
3487 .get = alc_test_pin_src_get, \
3488 .put = alc_test_pin_src_put, \
3489 .private_value = nid \
3492 static struct snd_kcontrol_new alc880_test_mixer[] = {
3493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3494 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3495 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3496 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3498 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3499 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3500 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3501 PIN_CTL_TEST("Front Pin Mode", 0x14),
3502 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3503 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3504 PIN_CTL_TEST("Side Pin Mode", 0x17),
3505 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3506 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3507 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3508 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3509 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3510 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3511 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3512 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3513 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3514 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3515 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3516 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3517 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3518 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3519 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3520 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3521 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3522 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3525 .name = "Channel Mode",
3526 .info = alc_ch_mode_info,
3527 .get = alc_ch_mode_get,
3528 .put = alc_ch_mode_put,
3533 static struct hda_verb alc880_test_init_verbs[] = {
3534 /* Unmute inputs of 0x0c - 0x0f */
3535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3538 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3539 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3541 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3542 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3543 /* Vol output for 0x0c-0x0f */
3544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3548 /* Set output pins 0x14-0x17 */
3549 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3550 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3551 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3552 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3553 /* Unmute output pins 0x14-0x17 */
3554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3556 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3557 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3558 /* Set input pins 0x18-0x1c */
3559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3563 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3564 /* Mute input pins 0x18-0x1b */
3565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3567 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3568 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3571 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3573 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3574 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3575 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3576 /* Analog input/passthru */
3577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3589 static const char *alc880_models[ALC880_MODEL_LAST] = {
3590 [ALC880_3ST] = "3stack",
3591 [ALC880_TCL_S700] = "tcl",
3592 [ALC880_3ST_DIG] = "3stack-digout",
3593 [ALC880_CLEVO] = "clevo",
3594 [ALC880_5ST] = "5stack",
3595 [ALC880_5ST_DIG] = "5stack-digout",
3596 [ALC880_W810] = "w810",
3597 [ALC880_Z71V] = "z71v",
3598 [ALC880_6ST] = "6stack",
3599 [ALC880_6ST_DIG] = "6stack-digout",
3600 [ALC880_ASUS] = "asus",
3601 [ALC880_ASUS_W1V] = "asus-w1v",
3602 [ALC880_ASUS_DIG] = "asus-dig",
3603 [ALC880_ASUS_DIG2] = "asus-dig2",
3604 [ALC880_UNIWILL_DIG] = "uniwill",
3605 [ALC880_UNIWILL_P53] = "uniwill-p53",
3606 [ALC880_FUJITSU] = "fujitsu",
3607 [ALC880_F1734] = "F1734",
3609 [ALC880_LG_LW] = "lg-lw",
3610 [ALC880_MEDION_RIM] = "medion",
3611 #ifdef CONFIG_SND_DEBUG
3612 [ALC880_TEST] = "test",
3614 [ALC880_AUTO] = "auto",
3617 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3618 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3619 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3620 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3621 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3622 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3623 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3624 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3625 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3626 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3627 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3628 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3629 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3630 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3631 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3632 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3633 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3634 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3635 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3636 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3637 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3638 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3639 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3640 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3641 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3642 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3643 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3644 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3645 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3646 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3647 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3648 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3649 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3650 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3651 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3652 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3653 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3654 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3655 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3656 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3657 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3658 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3659 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3660 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3661 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3662 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3663 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3664 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3665 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3666 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3667 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3668 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3669 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3670 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3671 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3672 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3673 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3674 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3675 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3676 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3677 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3678 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3679 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3680 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3681 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3682 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3683 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3684 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3685 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3687 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3688 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3689 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3694 * ALC880 codec presets
3696 static struct alc_config_preset alc880_presets[] = {
3698 .mixers = { alc880_three_stack_mixer },
3699 .init_verbs = { alc880_volume_init_verbs,
3700 alc880_pin_3stack_init_verbs },
3701 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3702 .dac_nids = alc880_dac_nids,
3703 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3704 .channel_mode = alc880_threestack_modes,
3706 .input_mux = &alc880_capture_source,
3708 [ALC880_3ST_DIG] = {
3709 .mixers = { alc880_three_stack_mixer },
3710 .init_verbs = { alc880_volume_init_verbs,
3711 alc880_pin_3stack_init_verbs },
3712 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3713 .dac_nids = alc880_dac_nids,
3714 .dig_out_nid = ALC880_DIGOUT_NID,
3715 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3716 .channel_mode = alc880_threestack_modes,
3718 .input_mux = &alc880_capture_source,
3720 [ALC880_TCL_S700] = {
3721 .mixers = { alc880_tcl_s700_mixer },
3722 .init_verbs = { alc880_volume_init_verbs,
3723 alc880_pin_tcl_S700_init_verbs,
3724 alc880_gpio2_init_verbs },
3725 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3726 .dac_nids = alc880_dac_nids,
3727 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3728 .num_adc_nids = 1, /* single ADC */
3730 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3731 .channel_mode = alc880_2_jack_modes,
3732 .input_mux = &alc880_capture_source,
3735 .mixers = { alc880_three_stack_mixer,
3736 alc880_five_stack_mixer},
3737 .init_verbs = { alc880_volume_init_verbs,
3738 alc880_pin_5stack_init_verbs },
3739 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3740 .dac_nids = alc880_dac_nids,
3741 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3742 .channel_mode = alc880_fivestack_modes,
3743 .input_mux = &alc880_capture_source,
3745 [ALC880_5ST_DIG] = {
3746 .mixers = { alc880_three_stack_mixer,
3747 alc880_five_stack_mixer },
3748 .init_verbs = { alc880_volume_init_verbs,
3749 alc880_pin_5stack_init_verbs },
3750 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3751 .dac_nids = alc880_dac_nids,
3752 .dig_out_nid = ALC880_DIGOUT_NID,
3753 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3754 .channel_mode = alc880_fivestack_modes,
3755 .input_mux = &alc880_capture_source,
3758 .mixers = { alc880_six_stack_mixer },
3759 .init_verbs = { alc880_volume_init_verbs,
3760 alc880_pin_6stack_init_verbs },
3761 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3762 .dac_nids = alc880_6st_dac_nids,
3763 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3764 .channel_mode = alc880_sixstack_modes,
3765 .input_mux = &alc880_6stack_capture_source,
3767 [ALC880_6ST_DIG] = {
3768 .mixers = { alc880_six_stack_mixer },
3769 .init_verbs = { alc880_volume_init_verbs,
3770 alc880_pin_6stack_init_verbs },
3771 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3772 .dac_nids = alc880_6st_dac_nids,
3773 .dig_out_nid = ALC880_DIGOUT_NID,
3774 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3775 .channel_mode = alc880_sixstack_modes,
3776 .input_mux = &alc880_6stack_capture_source,
3779 .mixers = { alc880_w810_base_mixer },
3780 .init_verbs = { alc880_volume_init_verbs,
3781 alc880_pin_w810_init_verbs,
3782 alc880_gpio2_init_verbs },
3783 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3784 .dac_nids = alc880_w810_dac_nids,
3785 .dig_out_nid = ALC880_DIGOUT_NID,
3786 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3787 .channel_mode = alc880_w810_modes,
3788 .input_mux = &alc880_capture_source,
3791 .mixers = { alc880_z71v_mixer },
3792 .init_verbs = { alc880_volume_init_verbs,
3793 alc880_pin_z71v_init_verbs },
3794 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3795 .dac_nids = alc880_z71v_dac_nids,
3796 .dig_out_nid = ALC880_DIGOUT_NID,
3798 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3799 .channel_mode = alc880_2_jack_modes,
3800 .input_mux = &alc880_capture_source,
3803 .mixers = { alc880_f1734_mixer },
3804 .init_verbs = { alc880_volume_init_verbs,
3805 alc880_pin_f1734_init_verbs },
3806 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3807 .dac_nids = alc880_f1734_dac_nids,
3809 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3810 .channel_mode = alc880_2_jack_modes,
3811 .input_mux = &alc880_f1734_capture_source,
3812 .unsol_event = alc880_uniwill_p53_unsol_event,
3813 .init_hook = alc880_uniwill_p53_init_hook,
3816 .mixers = { alc880_asus_mixer },
3817 .init_verbs = { alc880_volume_init_verbs,
3818 alc880_pin_asus_init_verbs,
3819 alc880_gpio1_init_verbs },
3820 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3821 .dac_nids = alc880_asus_dac_nids,
3822 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3823 .channel_mode = alc880_asus_modes,
3825 .input_mux = &alc880_capture_source,
3827 [ALC880_ASUS_DIG] = {
3828 .mixers = { alc880_asus_mixer },
3829 .init_verbs = { alc880_volume_init_verbs,
3830 alc880_pin_asus_init_verbs,
3831 alc880_gpio1_init_verbs },
3832 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3833 .dac_nids = alc880_asus_dac_nids,
3834 .dig_out_nid = ALC880_DIGOUT_NID,
3835 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3836 .channel_mode = alc880_asus_modes,
3838 .input_mux = &alc880_capture_source,
3840 [ALC880_ASUS_DIG2] = {
3841 .mixers = { alc880_asus_mixer },
3842 .init_verbs = { alc880_volume_init_verbs,
3843 alc880_pin_asus_init_verbs,
3844 alc880_gpio2_init_verbs }, /* use GPIO2 */
3845 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3846 .dac_nids = alc880_asus_dac_nids,
3847 .dig_out_nid = ALC880_DIGOUT_NID,
3848 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3849 .channel_mode = alc880_asus_modes,
3851 .input_mux = &alc880_capture_source,
3853 [ALC880_ASUS_W1V] = {
3854 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3855 .init_verbs = { alc880_volume_init_verbs,
3856 alc880_pin_asus_init_verbs,
3857 alc880_gpio1_init_verbs },
3858 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3859 .dac_nids = alc880_asus_dac_nids,
3860 .dig_out_nid = ALC880_DIGOUT_NID,
3861 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3862 .channel_mode = alc880_asus_modes,
3864 .input_mux = &alc880_capture_source,
3866 [ALC880_UNIWILL_DIG] = {
3867 .mixers = { alc880_asus_mixer },
3868 .init_verbs = { alc880_volume_init_verbs,
3869 alc880_pin_asus_init_verbs },
3870 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3871 .dac_nids = alc880_asus_dac_nids,
3872 .dig_out_nid = ALC880_DIGOUT_NID,
3873 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3874 .channel_mode = alc880_asus_modes,
3876 .input_mux = &alc880_capture_source,
3878 [ALC880_UNIWILL] = {
3879 .mixers = { alc880_uniwill_mixer },
3880 .init_verbs = { alc880_volume_init_verbs,
3881 alc880_uniwill_init_verbs },
3882 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3883 .dac_nids = alc880_asus_dac_nids,
3884 .dig_out_nid = ALC880_DIGOUT_NID,
3885 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3886 .channel_mode = alc880_threestack_modes,
3888 .input_mux = &alc880_capture_source,
3889 .unsol_event = alc880_uniwill_unsol_event,
3890 .init_hook = alc880_uniwill_init_hook,
3892 [ALC880_UNIWILL_P53] = {
3893 .mixers = { alc880_uniwill_p53_mixer },
3894 .init_verbs = { alc880_volume_init_verbs,
3895 alc880_uniwill_p53_init_verbs },
3896 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3897 .dac_nids = alc880_asus_dac_nids,
3898 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3899 .channel_mode = alc880_threestack_modes,
3900 .input_mux = &alc880_capture_source,
3901 .unsol_event = alc880_uniwill_p53_unsol_event,
3902 .init_hook = alc880_uniwill_p53_init_hook,
3904 [ALC880_FUJITSU] = {
3905 .mixers = { alc880_fujitsu_mixer },
3906 .init_verbs = { alc880_volume_init_verbs,
3907 alc880_uniwill_p53_init_verbs,
3908 alc880_beep_init_verbs },
3909 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3910 .dac_nids = alc880_dac_nids,
3911 .dig_out_nid = ALC880_DIGOUT_NID,
3912 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3913 .channel_mode = alc880_2_jack_modes,
3914 .input_mux = &alc880_capture_source,
3915 .unsol_event = alc880_uniwill_p53_unsol_event,
3916 .init_hook = alc880_uniwill_p53_init_hook,
3919 .mixers = { alc880_three_stack_mixer },
3920 .init_verbs = { alc880_volume_init_verbs,
3921 alc880_pin_clevo_init_verbs },
3922 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3923 .dac_nids = alc880_dac_nids,
3925 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3926 .channel_mode = alc880_threestack_modes,
3928 .input_mux = &alc880_capture_source,
3931 .mixers = { alc880_lg_mixer },
3932 .init_verbs = { alc880_volume_init_verbs,
3933 alc880_lg_init_verbs },
3934 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3935 .dac_nids = alc880_lg_dac_nids,
3936 .dig_out_nid = ALC880_DIGOUT_NID,
3937 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3938 .channel_mode = alc880_lg_ch_modes,
3940 .input_mux = &alc880_lg_capture_source,
3941 .unsol_event = alc_automute_amp_unsol_event,
3942 .init_hook = alc880_lg_init_hook,
3943 #ifdef CONFIG_SND_HDA_POWER_SAVE
3944 .loopbacks = alc880_lg_loopbacks,
3948 .mixers = { alc880_lg_lw_mixer },
3949 .init_verbs = { alc880_volume_init_verbs,
3950 alc880_lg_lw_init_verbs },
3951 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3952 .dac_nids = alc880_dac_nids,
3953 .dig_out_nid = ALC880_DIGOUT_NID,
3954 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3955 .channel_mode = alc880_lg_lw_modes,
3956 .input_mux = &alc880_lg_lw_capture_source,
3957 .unsol_event = alc_automute_amp_unsol_event,
3958 .init_hook = alc880_lg_lw_init_hook,
3960 [ALC880_MEDION_RIM] = {
3961 .mixers = { alc880_medion_rim_mixer },
3962 .init_verbs = { alc880_volume_init_verbs,
3963 alc880_medion_rim_init_verbs,
3964 alc_gpio2_init_verbs },
3965 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3966 .dac_nids = alc880_dac_nids,
3967 .dig_out_nid = ALC880_DIGOUT_NID,
3968 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3969 .channel_mode = alc880_2_jack_modes,
3970 .input_mux = &alc880_medion_rim_capture_source,
3971 .unsol_event = alc880_medion_rim_unsol_event,
3972 .init_hook = alc880_medion_rim_init_hook,
3974 #ifdef CONFIG_SND_DEBUG
3976 .mixers = { alc880_test_mixer },
3977 .init_verbs = { alc880_test_init_verbs },
3978 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3979 .dac_nids = alc880_test_dac_nids,
3980 .dig_out_nid = ALC880_DIGOUT_NID,
3981 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3982 .channel_mode = alc880_test_modes,
3983 .input_mux = &alc880_test_capture_source,
3989 * Automatic parse of I/O pins from the BIOS configuration
3994 ALC_CTL_WIDGET_MUTE,
3997 static struct snd_kcontrol_new alc880_control_templates[] = {
3998 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3999 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4000 HDA_BIND_MUTE(NULL, 0, 0, 0),
4003 /* add dynamic controls */
4004 static int add_control(struct alc_spec *spec, int type, const char *name,
4007 struct snd_kcontrol_new *knew;
4009 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4010 knew = snd_array_new(&spec->kctls);
4013 *knew = alc880_control_templates[type];
4014 knew->name = kstrdup(name, GFP_KERNEL);
4017 knew->private_value = val;
4021 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4022 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4023 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4024 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4025 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4026 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4027 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4028 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4029 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4030 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4031 #define ALC880_PIN_CD_NID 0x1c
4033 /* fill in the dac_nids table from the parsed pin configuration */
4034 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4035 const struct auto_pin_cfg *cfg)
4041 memset(assigned, 0, sizeof(assigned));
4042 spec->multiout.dac_nids = spec->private_dac_nids;
4044 /* check the pins hardwired to audio widget */
4045 for (i = 0; i < cfg->line_outs; i++) {
4046 nid = cfg->line_out_pins[i];
4047 if (alc880_is_fixed_pin(nid)) {
4048 int idx = alc880_fixed_pin_idx(nid);
4049 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4053 /* left pins can be connect to any audio widget */
4054 for (i = 0; i < cfg->line_outs; i++) {
4055 nid = cfg->line_out_pins[i];
4056 if (alc880_is_fixed_pin(nid))
4058 /* search for an empty channel */
4059 for (j = 0; j < cfg->line_outs; j++) {
4061 spec->multiout.dac_nids[i] =
4062 alc880_idx_to_dac(j);
4068 spec->multiout.num_dacs = cfg->line_outs;
4072 /* add playback controls from the parsed DAC table */
4073 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4074 const struct auto_pin_cfg *cfg)
4077 static const char *chname[4] = {
4078 "Front", "Surround", NULL /*CLFE*/, "Side"
4083 for (i = 0; i < cfg->line_outs; i++) {
4084 if (!spec->multiout.dac_nids[i])
4086 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4089 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4090 "Center Playback Volume",
4091 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4095 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4096 "LFE Playback Volume",
4097 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4101 err = add_control(spec, ALC_CTL_BIND_MUTE,
4102 "Center Playback Switch",
4103 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4107 err = add_control(spec, ALC_CTL_BIND_MUTE,
4108 "LFE Playback Switch",
4109 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4114 sprintf(name, "%s Playback Volume", chname[i]);
4115 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4116 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4120 sprintf(name, "%s Playback Switch", chname[i]);
4121 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4122 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4131 /* add playback controls for speaker and HP outputs */
4132 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4142 if (alc880_is_fixed_pin(pin)) {
4143 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4144 /* specify the DAC as the extra output */
4145 if (!spec->multiout.hp_nid)
4146 spec->multiout.hp_nid = nid;
4148 spec->multiout.extra_out_nid[0] = nid;
4149 /* control HP volume/switch on the output mixer amp */
4150 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4151 sprintf(name, "%s Playback Volume", pfx);
4152 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4153 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4156 sprintf(name, "%s Playback Switch", pfx);
4157 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4158 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4161 } else if (alc880_is_multi_pin(pin)) {
4162 /* set manual connection */
4163 /* we have only a switch on HP-out PIN */
4164 sprintf(name, "%s Playback Switch", pfx);
4165 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4166 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4173 /* create input playback/capture controls for the given pin */
4174 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4175 const char *ctlname,
4176 int idx, hda_nid_t mix_nid)
4181 sprintf(name, "%s Playback Volume", ctlname);
4182 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4183 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4186 sprintf(name, "%s Playback Switch", ctlname);
4187 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4188 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4194 /* create playback/capture controls for input pins */
4195 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4196 const struct auto_pin_cfg *cfg)
4198 struct hda_input_mux *imux = &spec->private_imux[0];
4201 for (i = 0; i < AUTO_PIN_LAST; i++) {
4202 if (alc880_is_input_pin(cfg->input_pins[i])) {
4203 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4204 err = new_analog_input(spec, cfg->input_pins[i],
4205 auto_pin_cfg_labels[i],
4209 imux->items[imux->num_items].label =
4210 auto_pin_cfg_labels[i];
4211 imux->items[imux->num_items].index =
4212 alc880_input_pin_idx(cfg->input_pins[i]);
4219 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4220 unsigned int pin_type)
4222 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4225 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4229 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4230 hda_nid_t nid, int pin_type,
4233 alc_set_pin_output(codec, nid, pin_type);
4234 /* need the manual connection? */
4235 if (alc880_is_multi_pin(nid)) {
4236 struct alc_spec *spec = codec->spec;
4237 int idx = alc880_multi_pin_idx(nid);
4238 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4239 AC_VERB_SET_CONNECT_SEL,
4240 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4244 static int get_pin_type(int line_out_type)
4246 if (line_out_type == AUTO_PIN_HP_OUT)
4252 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4254 struct alc_spec *spec = codec->spec;
4257 for (i = 0; i < spec->autocfg.line_outs; i++) {
4258 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4259 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4260 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4264 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4266 struct alc_spec *spec = codec->spec;
4269 pin = spec->autocfg.speaker_pins[0];
4270 if (pin) /* connect to front */
4271 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4272 pin = spec->autocfg.hp_pins[0];
4273 if (pin) /* connect to front */
4274 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4277 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4279 struct alc_spec *spec = codec->spec;
4282 for (i = 0; i < AUTO_PIN_LAST; i++) {
4283 hda_nid_t nid = spec->autocfg.input_pins[i];
4284 if (alc880_is_input_pin(nid)) {
4285 alc_set_input_pin(codec, nid, i);
4286 if (nid != ALC880_PIN_CD_NID &&
4287 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4288 snd_hda_codec_write(codec, nid, 0,
4289 AC_VERB_SET_AMP_GAIN_MUTE,
4295 /* parse the BIOS configuration and set up the alc_spec */
4296 /* return 1 if successful, 0 if the proper config is not found,
4297 * or a negative error code
4299 static int alc880_parse_auto_config(struct hda_codec *codec)
4301 struct alc_spec *spec = codec->spec;
4303 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4305 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4309 if (!spec->autocfg.line_outs)
4310 return 0; /* can't find valid BIOS pin config */
4312 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4315 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4318 err = alc880_auto_create_extra_out(spec,
4319 spec->autocfg.speaker_pins[0],
4323 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4327 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4331 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4333 /* check multiple SPDIF-out (for recent codecs) */
4334 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4336 err = snd_hda_get_connections(codec,
4337 spec->autocfg.dig_out_pins[i],
4342 spec->multiout.dig_out_nid = dig_nid;
4344 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4345 spec->slave_dig_outs[i - 1] = dig_nid;
4346 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4350 if (spec->autocfg.dig_in_pin)
4351 spec->dig_in_nid = ALC880_DIGIN_NID;
4353 if (spec->kctls.list)
4354 add_mixer(spec, spec->kctls.list);
4356 add_verb(spec, alc880_volume_init_verbs);
4358 spec->num_mux_defs = 1;
4359 spec->input_mux = &spec->private_imux[0];
4361 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4366 /* additional initialization for auto-configuration model */
4367 static void alc880_auto_init(struct hda_codec *codec)
4369 struct alc_spec *spec = codec->spec;
4370 alc880_auto_init_multi_out(codec);
4371 alc880_auto_init_extra_out(codec);
4372 alc880_auto_init_analog_input(codec);
4373 if (spec->unsol_event)
4374 alc_inithook(codec);
4377 static void set_capture_mixer(struct alc_spec *spec)
4379 static struct snd_kcontrol_new *caps[2][3] = {
4380 { alc_capture_mixer_nosrc1,
4381 alc_capture_mixer_nosrc2,
4382 alc_capture_mixer_nosrc3 },
4383 { alc_capture_mixer1,
4385 alc_capture_mixer3 },
4387 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4389 if (spec->input_mux && spec->input_mux->num_items > 1)
4393 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4397 #define set_beep_amp(spec, nid, idx, dir) \
4398 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4401 * OK, here we have finally the patch for ALC880
4404 static int patch_alc880(struct hda_codec *codec)
4406 struct alc_spec *spec;
4410 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4416 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4419 if (board_config < 0) {
4420 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4421 "trying auto-probe from BIOS...\n", codec->chip_name);
4422 board_config = ALC880_AUTO;
4425 if (board_config == ALC880_AUTO) {
4426 /* automatic parse from the BIOS config */
4427 err = alc880_parse_auto_config(codec);
4433 "hda_codec: Cannot set up configuration "
4434 "from BIOS. Using 3-stack mode...\n");
4435 board_config = ALC880_3ST;
4439 err = snd_hda_attach_beep_device(codec, 0x1);
4445 if (board_config != ALC880_AUTO)
4446 setup_preset(spec, &alc880_presets[board_config]);
4448 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4449 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4450 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4452 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4453 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4455 if (!spec->adc_nids && spec->input_mux) {
4456 /* check whether NID 0x07 is valid */
4457 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4459 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4460 if (wcap != AC_WID_AUD_IN) {
4461 spec->adc_nids = alc880_adc_nids_alt;
4462 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4464 spec->adc_nids = alc880_adc_nids;
4465 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4468 set_capture_mixer(spec);
4469 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4471 spec->vmaster_nid = 0x0c;
4473 codec->patch_ops = alc_patch_ops;
4474 if (board_config == ALC880_AUTO)
4475 spec->init_hook = alc880_auto_init;
4476 #ifdef CONFIG_SND_HDA_POWER_SAVE
4477 if (!spec->loopback.amplist)
4478 spec->loopback.amplist = alc880_loopbacks;
4480 codec->proc_widget_hook = print_realtek_coef;
4490 static hda_nid_t alc260_dac_nids[1] = {
4495 static hda_nid_t alc260_adc_nids[1] = {
4500 static hda_nid_t alc260_adc_nids_alt[1] = {
4505 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4506 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4508 static hda_nid_t alc260_dual_adc_nids[2] = {
4513 #define ALC260_DIGOUT_NID 0x03
4514 #define ALC260_DIGIN_NID 0x06
4516 static struct hda_input_mux alc260_capture_source = {
4520 { "Front Mic", 0x1 },
4526 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4527 * headphone jack and the internal CD lines since these are the only pins at
4528 * which audio can appear. For flexibility, also allow the option of
4529 * recording the mixer output on the second ADC (ADC0 doesn't have a
4530 * connection to the mixer output).
4532 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4536 { "Mic/Line", 0x0 },
4538 { "Headphone", 0x2 },
4544 { "Mic/Line", 0x0 },
4546 { "Headphone", 0x2 },
4553 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4554 * the Fujitsu S702x, but jacks are marked differently.
4556 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4563 { "Headphone", 0x5 },
4572 { "Headphone", 0x6 },
4578 /* Maxdata Favorit 100XS */
4579 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4583 { "Line/Mic", 0x0 },
4590 { "Line/Mic", 0x0 },
4598 * This is just place-holder, so there's something for alc_build_pcms to look
4599 * at when it calculates the maximum number of channels. ALC260 has no mixer
4600 * element which allows changing the channel mode, so the verb list is
4603 static struct hda_channel_mode alc260_modes[1] = {
4608 /* Mixer combinations
4610 * basic: base_output + input + pc_beep + capture
4611 * HP: base_output + input + capture_alt
4612 * HP_3013: hp_3013 + input + capture
4613 * fujitsu: fujitsu + capture
4614 * acer: acer + capture
4617 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4618 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4619 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4620 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4621 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4622 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4623 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4627 static struct snd_kcontrol_new alc260_input_mixer[] = {
4628 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4629 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4630 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4631 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4633 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4635 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4639 /* update HP, line and mono out pins according to the master switch */
4640 static void alc260_hp_master_update(struct hda_codec *codec,
4641 hda_nid_t hp, hda_nid_t line,
4644 struct alc_spec *spec = codec->spec;
4645 unsigned int val = spec->master_sw ? PIN_HP : 0;
4646 /* change HP and line-out pins */
4647 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4649 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4651 /* mono (speaker) depending on the HP jack sense */
4652 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4653 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4657 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 struct alc_spec *spec = codec->spec;
4662 *ucontrol->value.integer.value = spec->master_sw;
4666 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4667 struct snd_ctl_elem_value *ucontrol)
4669 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4670 struct alc_spec *spec = codec->spec;
4671 int val = !!*ucontrol->value.integer.value;
4672 hda_nid_t hp, line, mono;
4674 if (val == spec->master_sw)
4676 spec->master_sw = val;
4677 hp = (kcontrol->private_value >> 16) & 0xff;
4678 line = (kcontrol->private_value >> 8) & 0xff;
4679 mono = kcontrol->private_value & 0xff;
4680 alc260_hp_master_update(codec, hp, line, mono);
4684 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4687 .name = "Master Playback Switch",
4688 .info = snd_ctl_boolean_mono_info,
4689 .get = alc260_hp_master_sw_get,
4690 .put = alc260_hp_master_sw_put,
4691 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4693 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4694 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4696 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4697 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4699 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4703 static struct hda_verb alc260_hp_unsol_verbs[] = {
4704 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4708 static void alc260_hp_automute(struct hda_codec *codec)
4710 struct alc_spec *spec = codec->spec;
4711 unsigned int present;
4713 present = snd_hda_codec_read(codec, 0x10, 0,
4714 AC_VERB_GET_PIN_SENSE, 0);
4715 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4716 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4719 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4721 if ((res >> 26) == ALC880_HP_EVENT)
4722 alc260_hp_automute(codec);
4725 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4727 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4728 .name = "Master Playback Switch",
4729 .info = snd_ctl_boolean_mono_info,
4730 .get = alc260_hp_master_sw_get,
4731 .put = alc260_hp_master_sw_put,
4732 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4734 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4735 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4736 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4737 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4738 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4740 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4741 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4745 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4746 .ops = &snd_hda_bind_vol,
4748 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4749 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4750 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4755 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4756 .ops = &snd_hda_bind_sw,
4758 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4759 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4764 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4765 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4766 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4767 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4772 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4773 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4777 static void alc260_hp_3013_automute(struct hda_codec *codec)
4779 struct alc_spec *spec = codec->spec;
4780 unsigned int present;
4782 present = snd_hda_codec_read(codec, 0x15, 0,
4783 AC_VERB_GET_PIN_SENSE, 0);
4784 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4785 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4788 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4791 if ((res >> 26) == ALC880_HP_EVENT)
4792 alc260_hp_3013_automute(codec);
4795 static void alc260_hp_3012_automute(struct hda_codec *codec)
4797 unsigned int present, bits;
4799 present = snd_hda_codec_read(codec, 0x10, 0,
4800 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4802 bits = present ? 0 : PIN_OUT;
4803 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4805 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4807 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4811 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4814 if ((res >> 26) == ALC880_HP_EVENT)
4815 alc260_hp_3012_automute(codec);
4818 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4819 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4821 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4822 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4823 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4824 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4825 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4826 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4827 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4828 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4829 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4830 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4831 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4835 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4836 * versions of the ALC260 don't act on requests to enable mic bias from NID
4837 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4838 * datasheet doesn't mention this restriction. At this stage it's not clear
4839 * whether this behaviour is intentional or is a hardware bug in chip
4840 * revisions available in early 2006. Therefore for now allow the
4841 * "Headphone Jack Mode" control to span all choices, but if it turns out
4842 * that the lack of mic bias for this NID is intentional we could change the
4843 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4845 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4846 * don't appear to make the mic bias available from the "line" jack, even
4847 * though the NID used for this jack (0x14) can supply it. The theory is
4848 * that perhaps Acer have included blocking capacitors between the ALC260
4849 * and the output jack. If this turns out to be the case for all such
4850 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4851 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4853 * The C20x Tablet series have a mono internal speaker which is controlled
4854 * via the chip's Mono sum widget and pin complex, so include the necessary
4855 * controls for such models. On models without a "mono speaker" the control
4856 * won't do anything.
4858 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4859 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4860 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4861 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4862 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4864 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4866 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4867 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4869 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4870 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4871 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4872 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4873 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4877 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4879 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4880 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4881 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4882 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4883 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4884 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4885 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4889 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4890 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4892 static struct snd_kcontrol_new alc260_will_mixer[] = {
4893 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4894 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4896 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4897 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4898 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4899 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4900 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4901 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4902 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4906 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4907 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4909 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4910 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4911 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4913 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4914 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4915 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4916 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4917 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4918 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4919 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4924 * initialization verbs
4926 static struct hda_verb alc260_init_verbs[] = {
4927 /* Line In pin widget for input */
4928 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4929 /* CD pin widget for input */
4930 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4931 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4932 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4933 /* Mic2 (front panel) pin widget for input and vref at 80% */
4934 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4935 /* LINE-2 is used for line-out in rear */
4936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4937 /* select line-out */
4938 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4940 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4942 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4944 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4945 /* mute capture amp left and right */
4946 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4947 /* set connection select to line in (default select for this ADC) */
4948 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4949 /* mute capture amp left and right */
4950 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4951 /* set connection select to line in (default select for this ADC) */
4952 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4953 /* set vol=0 Line-Out mixer amp left and right */
4954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4955 /* unmute pin widget amp left and right (no gain on this amp) */
4956 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4957 /* set vol=0 HP mixer amp left and right */
4958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4959 /* unmute pin widget amp left and right (no gain on this amp) */
4960 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4961 /* set vol=0 Mono mixer amp left and right */
4962 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4963 /* unmute pin widget amp left and right (no gain on this amp) */
4964 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4965 /* unmute LINE-2 out pin */
4966 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4967 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4970 /* mute analog inputs */
4971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4976 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4977 /* mute Front out path */
4978 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4979 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4980 /* mute Headphone out path */
4981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4982 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4983 /* mute Mono out path */
4984 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4985 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4989 #if 0 /* should be identical with alc260_init_verbs? */
4990 static struct hda_verb alc260_hp_init_verbs[] = {
4991 /* Headphone and output */
4992 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4994 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4995 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4996 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4997 /* Mic2 (front panel) pin widget for input and vref at 80% */
4998 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4999 /* Line In pin widget for input */
5000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5001 /* Line-2 pin widget for output */
5002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5003 /* CD pin widget for input */
5004 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5005 /* unmute amp left and right */
5006 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5007 /* set connection select to line in (default select for this ADC) */
5008 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5009 /* unmute Line-Out mixer amp left and right (volume = 0) */
5010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5011 /* mute pin widget amp left and right (no gain on this amp) */
5012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5013 /* unmute HP mixer amp left and right (volume = 0) */
5014 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5015 /* mute pin widget amp left and right (no gain on this amp) */
5016 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5017 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5020 /* mute analog inputs */
5021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5023 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5026 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5027 /* Unmute Front out path */
5028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5029 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5030 /* Unmute Headphone out path */
5031 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5033 /* Unmute Mono out path */
5034 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5035 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5040 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5041 /* Line out and output */
5042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5044 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5045 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5047 /* Mic2 (front panel) pin widget for input and vref at 80% */
5048 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5049 /* Line In pin widget for input */
5050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5051 /* Headphone pin widget for output */
5052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5053 /* CD pin widget for input */
5054 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5055 /* unmute amp left and right */
5056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5057 /* set connection select to line in (default select for this ADC) */
5058 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5059 /* unmute Line-Out mixer amp left and right (volume = 0) */
5060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5061 /* mute pin widget amp left and right (no gain on this amp) */
5062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5063 /* unmute HP mixer amp left and right (volume = 0) */
5064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5065 /* mute pin widget amp left and right (no gain on this amp) */
5066 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5067 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5070 /* mute analog inputs */
5071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5072 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5074 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5076 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5077 /* Unmute Front out path */
5078 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5080 /* Unmute Headphone out path */
5081 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5082 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5083 /* Unmute Mono out path */
5084 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5085 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5089 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5090 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5091 * audio = 0x16, internal speaker = 0x10.
5093 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5094 /* Disable all GPIOs */
5095 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5096 /* Internal speaker is connected to headphone pin */
5097 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5098 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5100 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5101 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5102 /* Ensure all other unused pins are disabled and muted. */
5103 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5105 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5106 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5107 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5108 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5112 /* Disable digital (SPDIF) pins */
5113 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5114 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5116 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5117 * when acting as an output.
5119 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5121 /* Start with output sum widgets muted and their output gains at min */
5122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5128 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5130 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5132 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5133 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5134 /* Unmute Line1 pin widget output buffer since it starts as an output.
5135 * If the pin mode is changed by the user the pin mode control will
5136 * take care of enabling the pin's input/output buffers as needed.
5137 * Therefore there's no need to enable the input buffer at this
5140 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5141 /* Unmute input buffer of pin widget used for Line-in (no equiv
5144 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5146 /* Mute capture amp left and right */
5147 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5148 /* Set ADC connection select to match default mixer setting - line
5151 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5153 /* Do the same for the second ADC: mute capture input amp and
5154 * set ADC connection to line in (on mic1 pin)
5156 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5157 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5159 /* Mute all inputs to mixer widget (even unconnected ones) */
5160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5163 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5172 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5173 * similar laptops (adapted from Fujitsu init verbs).
5175 static struct hda_verb alc260_acer_init_verbs[] = {
5176 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5177 * the headphone jack. Turn this on and rely on the standard mute
5178 * methods whenever the user wants to turn these outputs off.
5180 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5181 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5182 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5183 /* Internal speaker/Headphone jack is connected to Line-out pin */
5184 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5185 /* Internal microphone/Mic jack is connected to Mic1 pin */
5186 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5187 /* Line In jack is connected to Line1 pin */
5188 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5189 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5190 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5191 /* Ensure all other unused pins are disabled and muted. */
5192 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5193 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5194 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5195 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5196 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5197 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5198 /* Disable digital (SPDIF) pins */
5199 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5200 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5202 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5203 * bus when acting as outputs.
5205 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5206 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5208 /* Start with output sum widgets muted and their output gains at min */
5209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5210 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5211 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5212 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5213 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5214 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5215 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5216 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5217 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5219 /* Unmute Line-out pin widget amp left and right
5220 * (no equiv mixer ctrl)
5222 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5223 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5224 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5225 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5226 * inputs. If the pin mode is changed by the user the pin mode control
5227 * will take care of enabling the pin's input/output buffers as needed.
5228 * Therefore there's no need to enable the input buffer at this
5231 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5234 /* Mute capture amp left and right */
5235 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5236 /* Set ADC connection select to match default mixer setting - mic
5239 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5241 /* Do similar with the second ADC: mute capture input amp and
5242 * set ADC connection to mic to match ALSA's default state.
5244 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5245 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5247 /* Mute all inputs to mixer widget (even unconnected ones) */
5248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5260 /* Initialisation sequence for Maxdata Favorit 100XS
5261 * (adapted from Acer init verbs).
5263 static struct hda_verb alc260_favorit100_init_verbs[] = {
5264 /* GPIO 0 enables the output jack.
5265 * Turn this on and rely on the standard mute
5266 * methods whenever the user wants to turn these outputs off.
5268 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5269 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5270 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5271 /* Line/Mic input jack is connected to Mic1 pin */
5272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5273 /* Ensure all other unused pins are disabled and muted. */
5274 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5276 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5277 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5278 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5279 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5284 /* Disable digital (SPDIF) pins */
5285 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5286 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5288 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5289 * bus when acting as outputs.
5291 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5292 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5294 /* Start with output sum widgets muted and their output gains at min */
5295 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5296 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5297 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5299 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5300 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5301 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5302 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5303 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5305 /* Unmute Line-out pin widget amp left and right
5306 * (no equiv mixer ctrl)
5308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5309 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5310 * inputs. If the pin mode is changed by the user the pin mode control
5311 * will take care of enabling the pin's input/output buffers as needed.
5312 * Therefore there's no need to enable the input buffer at this
5315 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317 /* Mute capture amp left and right */
5318 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5319 /* Set ADC connection select to match default mixer setting - mic
5322 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5324 /* Do similar with the second ADC: mute capture input amp and
5325 * set ADC connection to mic to match ALSA's default state.
5327 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5328 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5330 /* Mute all inputs to mixer widget (even unconnected ones) */
5331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5343 static struct hda_verb alc260_will_verbs[] = {
5344 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5345 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5346 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5347 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5348 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5349 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5353 static struct hda_verb alc260_replacer_672v_verbs[] = {
5354 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5355 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5356 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5358 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5359 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5360 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5362 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5366 /* toggle speaker-output according to the hp-jack state */
5367 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5369 unsigned int present;
5371 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5372 present = snd_hda_codec_read(codec, 0x0f, 0,
5373 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5375 snd_hda_codec_write_cache(codec, 0x01, 0,
5376 AC_VERB_SET_GPIO_DATA, 1);
5377 snd_hda_codec_write_cache(codec, 0x0f, 0,
5378 AC_VERB_SET_PIN_WIDGET_CONTROL,
5381 snd_hda_codec_write_cache(codec, 0x01, 0,
5382 AC_VERB_SET_GPIO_DATA, 0);
5383 snd_hda_codec_write_cache(codec, 0x0f, 0,
5384 AC_VERB_SET_PIN_WIDGET_CONTROL,
5389 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5392 if ((res >> 26) == ALC880_HP_EVENT)
5393 alc260_replacer_672v_automute(codec);
5396 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5397 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5398 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5399 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5400 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5401 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5402 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5403 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5404 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5405 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5406 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5410 /* Test configuration for debugging, modelled after the ALC880 test
5413 #ifdef CONFIG_SND_DEBUG
5414 static hda_nid_t alc260_test_dac_nids[1] = {
5417 static hda_nid_t alc260_test_adc_nids[2] = {
5420 /* For testing the ALC260, each input MUX needs its own definition since
5421 * the signal assignments are different. This assumes that the first ADC
5424 static struct hda_input_mux alc260_test_capture_sources[2] = {
5428 { "MIC1 pin", 0x0 },
5429 { "MIC2 pin", 0x1 },
5430 { "LINE1 pin", 0x2 },
5431 { "LINE2 pin", 0x3 },
5433 { "LINE-OUT pin", 0x5 },
5434 { "HP-OUT pin", 0x6 },
5440 { "MIC1 pin", 0x0 },
5441 { "MIC2 pin", 0x1 },
5442 { "LINE1 pin", 0x2 },
5443 { "LINE2 pin", 0x3 },
5446 { "LINE-OUT pin", 0x6 },
5447 { "HP-OUT pin", 0x7 },
5451 static struct snd_kcontrol_new alc260_test_mixer[] = {
5452 /* Output driver widgets */
5453 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5454 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5455 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5456 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5457 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5458 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5460 /* Modes for retasking pin widgets
5461 * Note: the ALC260 doesn't seem to act on requests to enable mic
5462 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5463 * mention this restriction. At this stage it's not clear whether
5464 * this behaviour is intentional or is a hardware bug in chip
5465 * revisions available at least up until early 2006. Therefore for
5466 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5467 * choices, but if it turns out that the lack of mic bias for these
5468 * NIDs is intentional we could change their modes from
5469 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5471 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5472 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5473 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5474 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5475 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5476 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5478 /* Loopback mixer controls */
5479 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5480 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5481 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5482 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5483 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5484 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5485 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5486 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5487 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5488 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5489 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5490 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5491 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5492 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5494 /* Controls for GPIO pins, assuming they are configured as outputs */
5495 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5496 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5497 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5498 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5500 /* Switches to allow the digital IO pins to be enabled. The datasheet
5501 * is ambigious as to which NID is which; testing on laptops which
5502 * make this output available should provide clarification.
5504 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5505 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5507 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5508 * this output to turn on an external amplifier.
5510 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5511 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5515 static struct hda_verb alc260_test_init_verbs[] = {
5516 /* Enable all GPIOs as outputs with an initial value of 0 */
5517 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5518 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5519 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5521 /* Enable retasking pins as output, initially without power amp */
5522 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5523 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5526 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5527 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5529 /* Disable digital (SPDIF) pins initially, but users can enable
5530 * them via a mixer switch. In the case of SPDIF-out, this initverb
5531 * payload also sets the generation to 0, output to be in "consumer"
5532 * PCM format, copyright asserted, no pre-emphasis and no validity
5535 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5536 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5538 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5539 * OUT1 sum bus when acting as an output.
5541 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5542 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5543 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5544 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5546 /* Start with output sum widgets muted and their output gains at min */
5547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5549 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5551 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5552 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5553 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5554 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5555 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5557 /* Unmute retasking pin widget output buffers since the default
5558 * state appears to be output. As the pin mode is changed by the
5559 * user the pin mode control will take care of enabling the pin's
5560 * input/output buffers as needed.
5562 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5565 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5566 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5567 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5568 /* Also unmute the mono-out pin widget */
5569 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5571 /* Mute capture amp left and right */
5572 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5573 /* Set ADC connection select to match default mixer setting (mic1
5576 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5578 /* Do the same for the second ADC: mute capture input amp and
5579 * set ADC connection to mic1 pin
5581 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5582 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5584 /* Mute all inputs to mixer widget (even unconnected ones) */
5585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5598 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5599 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5601 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5602 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5605 * for BIOS auto-configuration
5608 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5609 const char *pfx, int *vol_bits)
5612 unsigned long vol_val, sw_val;
5616 if (nid >= 0x0f && nid < 0x11) {
5617 nid_vol = nid - 0x7;
5618 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5619 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5620 } else if (nid == 0x11) {
5621 nid_vol = nid - 0x7;
5622 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5623 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5624 } else if (nid >= 0x12 && nid <= 0x15) {
5626 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5627 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5631 if (!(*vol_bits & (1 << nid_vol))) {
5632 /* first control for the volume widget */
5633 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5634 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5637 *vol_bits |= (1 << nid_vol);
5639 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5640 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5646 /* add playback controls from the parsed DAC table */
5647 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5648 const struct auto_pin_cfg *cfg)
5654 spec->multiout.num_dacs = 1;
5655 spec->multiout.dac_nids = spec->private_dac_nids;
5656 spec->multiout.dac_nids[0] = 0x02;
5658 nid = cfg->line_out_pins[0];
5660 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5665 nid = cfg->speaker_pins[0];
5667 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5672 nid = cfg->hp_pins[0];
5674 err = alc260_add_playback_controls(spec, nid, "Headphone",
5682 /* create playback/capture controls for input pins */
5683 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5684 const struct auto_pin_cfg *cfg)
5686 struct hda_input_mux *imux = &spec->private_imux[0];
5689 for (i = 0; i < AUTO_PIN_LAST; i++) {
5690 if (cfg->input_pins[i] >= 0x12) {
5691 idx = cfg->input_pins[i] - 0x12;
5692 err = new_analog_input(spec, cfg->input_pins[i],
5693 auto_pin_cfg_labels[i], idx,
5697 imux->items[imux->num_items].label =
5698 auto_pin_cfg_labels[i];
5699 imux->items[imux->num_items].index = idx;
5702 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5703 idx = cfg->input_pins[i] - 0x09;
5704 err = new_analog_input(spec, cfg->input_pins[i],
5705 auto_pin_cfg_labels[i], idx,
5709 imux->items[imux->num_items].label =
5710 auto_pin_cfg_labels[i];
5711 imux->items[imux->num_items].index = idx;
5718 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5719 hda_nid_t nid, int pin_type,
5722 alc_set_pin_output(codec, nid, pin_type);
5723 /* need the manual connection? */
5725 int idx = nid - 0x12;
5726 snd_hda_codec_write(codec, idx + 0x0b, 0,
5727 AC_VERB_SET_CONNECT_SEL, sel_idx);
5731 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5733 struct alc_spec *spec = codec->spec;
5736 nid = spec->autocfg.line_out_pins[0];
5738 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5739 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5742 nid = spec->autocfg.speaker_pins[0];
5744 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5746 nid = spec->autocfg.hp_pins[0];
5748 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5751 #define ALC260_PIN_CD_NID 0x16
5752 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5754 struct alc_spec *spec = codec->spec;
5757 for (i = 0; i < AUTO_PIN_LAST; i++) {
5758 hda_nid_t nid = spec->autocfg.input_pins[i];
5760 alc_set_input_pin(codec, nid, i);
5761 if (nid != ALC260_PIN_CD_NID &&
5762 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5763 snd_hda_codec_write(codec, nid, 0,
5764 AC_VERB_SET_AMP_GAIN_MUTE,
5771 * generic initialization of ADC, input mixers and output mixers
5773 static struct hda_verb alc260_volume_init_verbs[] = {
5775 * Unmute ADC0-1 and set the default input to mic-in
5777 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5778 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5779 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5780 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5782 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5784 * Note: PASD motherboards uses the Line In 2 as the input for
5785 * front panel mic (mic 2)
5787 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5788 /* mute analog inputs */
5789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5796 * Set up output mixers (0x08 - 0x0a)
5798 /* set vol=0 to output mixers */
5799 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5801 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5802 /* set up input amps for analog loopback */
5803 /* Amp Indices: DAC = 0, mixer = 1 */
5804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5807 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5808 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5809 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5814 static int alc260_parse_auto_config(struct hda_codec *codec)
5816 struct alc_spec *spec = codec->spec;
5818 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5820 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5824 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5827 if (!spec->kctls.list)
5828 return 0; /* can't find valid BIOS pin config */
5829 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5833 spec->multiout.max_channels = 2;
5835 if (spec->autocfg.dig_outs)
5836 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5837 if (spec->kctls.list)
5838 add_mixer(spec, spec->kctls.list);
5840 add_verb(spec, alc260_volume_init_verbs);
5842 spec->num_mux_defs = 1;
5843 spec->input_mux = &spec->private_imux[0];
5845 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5850 /* additional initialization for auto-configuration model */
5851 static void alc260_auto_init(struct hda_codec *codec)
5853 struct alc_spec *spec = codec->spec;
5854 alc260_auto_init_multi_out(codec);
5855 alc260_auto_init_analog_input(codec);
5856 if (spec->unsol_event)
5857 alc_inithook(codec);
5860 #ifdef CONFIG_SND_HDA_POWER_SAVE
5861 static struct hda_amp_list alc260_loopbacks[] = {
5862 { 0x07, HDA_INPUT, 0 },
5863 { 0x07, HDA_INPUT, 1 },
5864 { 0x07, HDA_INPUT, 2 },
5865 { 0x07, HDA_INPUT, 3 },
5866 { 0x07, HDA_INPUT, 4 },
5872 * ALC260 configurations
5874 static const char *alc260_models[ALC260_MODEL_LAST] = {
5875 [ALC260_BASIC] = "basic",
5877 [ALC260_HP_3013] = "hp-3013",
5878 [ALC260_HP_DC7600] = "hp-dc7600",
5879 [ALC260_FUJITSU_S702X] = "fujitsu",
5880 [ALC260_ACER] = "acer",
5881 [ALC260_WILL] = "will",
5882 [ALC260_REPLACER_672V] = "replacer",
5883 [ALC260_FAVORIT100] = "favorit100",
5884 #ifdef CONFIG_SND_DEBUG
5885 [ALC260_TEST] = "test",
5887 [ALC260_AUTO] = "auto",
5890 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5891 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5892 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5893 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5894 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5895 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5896 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5897 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5898 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5899 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5900 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5901 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5902 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5903 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5904 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5905 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5906 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5907 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5908 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5909 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5913 static struct alc_config_preset alc260_presets[] = {
5915 .mixers = { alc260_base_output_mixer,
5916 alc260_input_mixer },
5917 .init_verbs = { alc260_init_verbs },
5918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5919 .dac_nids = alc260_dac_nids,
5920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5921 .adc_nids = alc260_adc_nids,
5922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5923 .channel_mode = alc260_modes,
5924 .input_mux = &alc260_capture_source,
5927 .mixers = { alc260_hp_output_mixer,
5928 alc260_input_mixer },
5929 .init_verbs = { alc260_init_verbs,
5930 alc260_hp_unsol_verbs },
5931 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5932 .dac_nids = alc260_dac_nids,
5933 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5934 .adc_nids = alc260_adc_nids_alt,
5935 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5936 .channel_mode = alc260_modes,
5937 .input_mux = &alc260_capture_source,
5938 .unsol_event = alc260_hp_unsol_event,
5939 .init_hook = alc260_hp_automute,
5941 [ALC260_HP_DC7600] = {
5942 .mixers = { alc260_hp_dc7600_mixer,
5943 alc260_input_mixer },
5944 .init_verbs = { alc260_init_verbs,
5945 alc260_hp_dc7600_verbs },
5946 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5947 .dac_nids = alc260_dac_nids,
5948 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5949 .adc_nids = alc260_adc_nids_alt,
5950 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5951 .channel_mode = alc260_modes,
5952 .input_mux = &alc260_capture_source,
5953 .unsol_event = alc260_hp_3012_unsol_event,
5954 .init_hook = alc260_hp_3012_automute,
5956 [ALC260_HP_3013] = {
5957 .mixers = { alc260_hp_3013_mixer,
5958 alc260_input_mixer },
5959 .init_verbs = { alc260_hp_3013_init_verbs,
5960 alc260_hp_3013_unsol_verbs },
5961 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5962 .dac_nids = alc260_dac_nids,
5963 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5964 .adc_nids = alc260_adc_nids_alt,
5965 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5966 .channel_mode = alc260_modes,
5967 .input_mux = &alc260_capture_source,
5968 .unsol_event = alc260_hp_3013_unsol_event,
5969 .init_hook = alc260_hp_3013_automute,
5971 [ALC260_FUJITSU_S702X] = {
5972 .mixers = { alc260_fujitsu_mixer },
5973 .init_verbs = { alc260_fujitsu_init_verbs },
5974 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5975 .dac_nids = alc260_dac_nids,
5976 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5977 .adc_nids = alc260_dual_adc_nids,
5978 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5979 .channel_mode = alc260_modes,
5980 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5981 .input_mux = alc260_fujitsu_capture_sources,
5984 .mixers = { alc260_acer_mixer },
5985 .init_verbs = { alc260_acer_init_verbs },
5986 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5987 .dac_nids = alc260_dac_nids,
5988 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5989 .adc_nids = alc260_dual_adc_nids,
5990 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5991 .channel_mode = alc260_modes,
5992 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5993 .input_mux = alc260_acer_capture_sources,
5995 [ALC260_FAVORIT100] = {
5996 .mixers = { alc260_favorit100_mixer },
5997 .init_verbs = { alc260_favorit100_init_verbs },
5998 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5999 .dac_nids = alc260_dac_nids,
6000 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6001 .adc_nids = alc260_dual_adc_nids,
6002 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6003 .channel_mode = alc260_modes,
6004 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6005 .input_mux = alc260_favorit100_capture_sources,
6008 .mixers = { alc260_will_mixer },
6009 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6010 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6011 .dac_nids = alc260_dac_nids,
6012 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6013 .adc_nids = alc260_adc_nids,
6014 .dig_out_nid = ALC260_DIGOUT_NID,
6015 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6016 .channel_mode = alc260_modes,
6017 .input_mux = &alc260_capture_source,
6019 [ALC260_REPLACER_672V] = {
6020 .mixers = { alc260_replacer_672v_mixer },
6021 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6022 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6023 .dac_nids = alc260_dac_nids,
6024 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6025 .adc_nids = alc260_adc_nids,
6026 .dig_out_nid = ALC260_DIGOUT_NID,
6027 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6028 .channel_mode = alc260_modes,
6029 .input_mux = &alc260_capture_source,
6030 .unsol_event = alc260_replacer_672v_unsol_event,
6031 .init_hook = alc260_replacer_672v_automute,
6033 #ifdef CONFIG_SND_DEBUG
6035 .mixers = { alc260_test_mixer },
6036 .init_verbs = { alc260_test_init_verbs },
6037 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6038 .dac_nids = alc260_test_dac_nids,
6039 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6040 .adc_nids = alc260_test_adc_nids,
6041 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6042 .channel_mode = alc260_modes,
6043 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6044 .input_mux = alc260_test_capture_sources,
6049 static int patch_alc260(struct hda_codec *codec)
6051 struct alc_spec *spec;
6052 int err, board_config;
6054 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6060 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6063 if (board_config < 0) {
6064 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6065 "trying auto-probe from BIOS...\n",
6067 board_config = ALC260_AUTO;
6070 if (board_config == ALC260_AUTO) {
6071 /* automatic parse from the BIOS config */
6072 err = alc260_parse_auto_config(codec);
6078 "hda_codec: Cannot set up configuration "
6079 "from BIOS. Using base mode...\n");
6080 board_config = ALC260_BASIC;
6084 err = snd_hda_attach_beep_device(codec, 0x1);
6090 if (board_config != ALC260_AUTO)
6091 setup_preset(spec, &alc260_presets[board_config]);
6093 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6094 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6096 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6097 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6099 if (!spec->adc_nids && spec->input_mux) {
6100 /* check whether NID 0x04 is valid */
6101 unsigned int wcap = get_wcaps(codec, 0x04);
6102 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6104 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6105 spec->adc_nids = alc260_adc_nids_alt;
6106 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6108 spec->adc_nids = alc260_adc_nids;
6109 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6112 set_capture_mixer(spec);
6113 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6115 spec->vmaster_nid = 0x08;
6117 codec->patch_ops = alc_patch_ops;
6118 if (board_config == ALC260_AUTO)
6119 spec->init_hook = alc260_auto_init;
6120 #ifdef CONFIG_SND_HDA_POWER_SAVE
6121 if (!spec->loopback.amplist)
6122 spec->loopback.amplist = alc260_loopbacks;
6124 codec->proc_widget_hook = print_realtek_coef;
6133 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6134 * configuration. Each pin widget can choose any input DACs and a mixer.
6135 * Each ADC is connected from a mixer of all inputs. This makes possible
6136 * 6-channel independent captures.
6138 * In addition, an independent DAC for the multi-playback (not used in this
6141 #define ALC882_DIGOUT_NID 0x06
6142 #define ALC882_DIGIN_NID 0x0a
6144 static struct hda_channel_mode alc882_ch_modes[1] = {
6148 static hda_nid_t alc882_dac_nids[4] = {
6149 /* front, rear, clfe, rear_surr */
6150 0x02, 0x03, 0x04, 0x05
6153 /* identical with ALC880 */
6154 #define alc882_adc_nids alc880_adc_nids
6155 #define alc882_adc_nids_alt alc880_adc_nids_alt
6157 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6158 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6161 /* FIXME: should be a matrix-type input source selection */
6163 static struct hda_input_mux alc882_capture_source = {
6167 { "Front Mic", 0x1 },
6173 static struct hda_input_mux mb5_capture_source = {
6185 static struct hda_verb alc882_3ST_ch2_init[] = {
6186 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6187 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6188 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6189 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6196 static struct hda_verb alc882_3ST_ch6_init[] = {
6197 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6198 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6199 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6200 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6201 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6202 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6206 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6207 { 2, alc882_3ST_ch2_init },
6208 { 6, alc882_3ST_ch6_init },
6214 static struct hda_verb alc882_sixstack_ch6_init[] = {
6215 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6216 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6217 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6218 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6225 static struct hda_verb alc882_sixstack_ch8_init[] = {
6226 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6227 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6228 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6229 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6233 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6234 { 6, alc882_sixstack_ch6_init },
6235 { 8, alc882_sixstack_ch8_init },
6239 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6245 static struct hda_verb alc885_mbp_ch2_init[] = {
6246 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6247 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6248 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6255 static struct hda_verb alc885_mbp_ch6_init[] = {
6256 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6257 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6258 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6259 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6260 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6264 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6265 { 2, alc885_mbp_ch2_init },
6266 { 6, alc885_mbp_ch6_init },
6271 * Speakers/Woofer/HP = Front
6274 static struct hda_verb alc885_mb5_ch2_init[] = {
6275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6282 * Speakers/HP = Front
6286 static struct hda_verb alc885_mb5_ch6_init[] = {
6287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6288 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6289 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6293 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6294 { 2, alc885_mb5_ch2_init },
6295 { 6, alc885_mb5_ch6_init },
6298 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6299 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6301 static struct snd_kcontrol_new alc882_base_mixer[] = {
6302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6303 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6304 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6305 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6306 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6307 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6308 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6309 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6310 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6311 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6313 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6314 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6315 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6316 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6318 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6319 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6320 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6321 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6322 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6326 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6328 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6329 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6330 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6331 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6332 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6334 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6335 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6336 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6340 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6341 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6342 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6343 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6344 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6345 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6346 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6347 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6348 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
6349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6350 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6352 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6353 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6354 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6358 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6359 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6360 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6361 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6362 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6363 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6364 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6365 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6366 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6367 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6371 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6372 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6373 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6375 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6376 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6377 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6378 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6381 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6382 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6384 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6388 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6389 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6391 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6392 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6393 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6394 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6395 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6396 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6397 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6398 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6399 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6400 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6401 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6404 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6408 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6412 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6413 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6417 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6422 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6425 .name = "Channel Mode",
6426 .info = alc_ch_mode_info,
6427 .get = alc_ch_mode_get,
6428 .put = alc_ch_mode_put,
6433 static struct hda_verb alc882_init_verbs[] = {
6434 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6437 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6447 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6448 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6449 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6451 /* Front Pin: output 0 (0x0c) */
6452 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6453 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6454 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6455 /* Rear Pin: output 1 (0x0d) */
6456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6458 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6459 /* CLFE Pin: output 2 (0x0e) */
6460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6461 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6462 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6463 /* Side Pin: output 3 (0x0f) */
6464 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6465 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6466 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6467 /* Mic (rear) pin: input vref at 80% */
6468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6470 /* Front Mic pin: input vref at 80% */
6471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6473 /* Line In pin: input */
6474 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6475 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6476 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6477 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6478 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6479 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6480 /* CD pin widget for input */
6481 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6483 /* FIXME: use matrix-type input source selection */
6484 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6485 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6486 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6487 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6488 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6489 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6491 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6493 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6500 /* ADC1: mute amp left and right */
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6502 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6503 /* ADC2: mute amp left and right */
6504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6505 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6506 /* ADC3: mute amp left and right */
6507 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6508 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6513 static struct hda_verb alc882_eapd_verbs[] = {
6514 /* change to EAPD mode */
6515 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6516 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6521 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6522 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6523 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6524 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6525 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6526 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6527 /* FIXME: this looks suspicious...
6528 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6529 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6534 static struct hda_verb alc882_macpro_init_verbs[] = {
6535 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6539 /* Front Pin: output 0 (0x0c) */
6540 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6542 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6543 /* Front Mic pin: input vref at 80% */
6544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6545 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6546 /* Speaker: output */
6547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6549 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6550 /* Headphone output (output 0 - 0x0c) */
6551 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6553 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6555 /* FIXME: use matrix-type input source selection */
6556 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6557 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6558 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6559 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6560 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6561 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6563 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6572 /* ADC1: mute amp left and right */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6574 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6575 /* ADC2: mute amp left and right */
6576 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6577 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6578 /* ADC3: mute amp left and right */
6579 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6580 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6586 static struct hda_verb alc885_mb5_init_verbs[] = {
6588 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6589 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6590 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6591 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6593 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6596 /* Surround mixer */
6597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6601 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6605 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6606 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6607 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6608 /* Front Pin (0x0c) */
6609 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6610 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6611 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6612 /* LFE Pin (0x0e) */
6613 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6614 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6615 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
6617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6618 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6619 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
6620 /* Front Mic pin: input vref at 80% */
6621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6622 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6627 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6628 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6629 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6630 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6634 /* Macbook Pro rev3 */
6635 static struct hda_verb alc885_mbp3_init_verbs[] = {
6636 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6641 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6644 /* Front Pin: output 0 (0x0c) */
6645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6646 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6647 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6648 /* HP Pin: output 0 (0x0d) */
6649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6651 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6652 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6653 /* Mic (rear) pin: input vref at 80% */
6654 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6656 /* Front Mic pin: input vref at 80% */
6657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6659 /* Line In pin: use output 1 when in LineOut mode */
6660 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6661 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6662 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6664 /* FIXME: use matrix-type input source selection */
6665 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6666 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6672 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6674 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6675 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6680 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6681 /* ADC1: mute amp left and right */
6682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6683 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6684 /* ADC2: mute amp left and right */
6685 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6686 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6687 /* ADC3: mute amp left and right */
6688 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6689 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6694 /* iMac 24 mixer. */
6695 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6696 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6697 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6701 /* iMac 24 init verbs. */
6702 static struct hda_verb alc885_imac24_init_verbs[] = {
6703 /* Internal speakers: output 0 (0x0c) */
6704 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6705 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6706 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6707 /* Internal speakers: output 0 (0x0c) */
6708 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6709 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6710 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6711 /* Headphone: output 0 (0x0c) */
6712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6714 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6715 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6716 /* Front Mic: input vref at 80% */
6717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6722 /* Toggle speaker-output according to the hp-jack state */
6723 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6725 struct alc_spec *spec = codec->spec;
6727 spec->autocfg.hp_pins[0] = 0x14;
6728 spec->autocfg.speaker_pins[0] = 0x18;
6729 spec->autocfg.speaker_pins[1] = 0x1a;
6730 alc_automute_amp(codec);
6733 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6735 struct alc_spec *spec = codec->spec;
6737 spec->autocfg.hp_pins[0] = 0x15;
6738 spec->autocfg.speaker_pins[0] = 0x14;
6739 alc_automute_amp(codec);
6743 static struct hda_verb alc882_targa_verbs[] = {
6744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6748 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6750 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6751 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6752 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6754 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6755 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6756 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6757 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6761 /* toggle speaker-output according to the hp-jack state */
6762 static void alc882_targa_automute(struct hda_codec *codec)
6764 struct alc_spec *spec = codec->spec;
6765 alc_automute_amp(codec);
6766 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6767 spec->jack_present ? 1 : 3);
6770 static void alc882_targa_init_hook(struct hda_codec *codec)
6772 struct alc_spec *spec = codec->spec;
6774 spec->autocfg.hp_pins[0] = 0x14;
6775 spec->autocfg.speaker_pins[0] = 0x1b;
6776 alc882_targa_automute(codec);
6779 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6781 if ((res >> 26) == ALC880_HP_EVENT)
6782 alc882_targa_automute(codec);
6785 static struct hda_verb alc882_asus_a7j_verbs[] = {
6786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6790 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6791 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6793 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6794 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6795 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6797 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6798 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6799 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6803 static struct hda_verb alc882_asus_a7m_verbs[] = {
6804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6809 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6811 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6812 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6813 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6815 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6816 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6817 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6821 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6823 unsigned int gpiostate, gpiomask, gpiodir;
6825 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6826 AC_VERB_GET_GPIO_DATA, 0);
6829 gpiostate |= (1 << pin);
6831 gpiostate &= ~(1 << pin);
6833 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6834 AC_VERB_GET_GPIO_MASK, 0);
6835 gpiomask |= (1 << pin);
6837 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6838 AC_VERB_GET_GPIO_DIRECTION, 0);
6839 gpiodir |= (1 << pin);
6842 snd_hda_codec_write(codec, codec->afg, 0,
6843 AC_VERB_SET_GPIO_MASK, gpiomask);
6844 snd_hda_codec_write(codec, codec->afg, 0,
6845 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6849 snd_hda_codec_write(codec, codec->afg, 0,
6850 AC_VERB_SET_GPIO_DATA, gpiostate);
6853 /* set up GPIO at initialization */
6854 static void alc885_macpro_init_hook(struct hda_codec *codec)
6856 alc882_gpio_mute(codec, 0, 0);
6857 alc882_gpio_mute(codec, 1, 0);
6860 /* set up GPIO and update auto-muting at initialization */
6861 static void alc885_imac24_init_hook(struct hda_codec *codec)
6863 alc885_macpro_init_hook(codec);
6864 alc885_imac24_automute_init_hook(codec);
6868 * generic initialization of ADC, input mixers and output mixers
6870 static struct hda_verb alc882_auto_init_verbs[] = {
6872 * Unmute ADC0-2 and set the default input to mic-in
6874 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6876 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6877 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6878 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6879 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6881 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6883 * Note: PASD motherboards uses the Line In 2 as the input for
6884 * front panel mic (mic 2)
6886 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6887 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6888 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6889 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6890 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6894 * Set up output mixers (0x0c - 0x0f)
6896 /* set vol=0 to output mixers */
6897 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6898 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6899 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6900 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6901 /* set up input amps for analog loopback */
6902 /* Amp Indices: DAC = 0, mixer = 1 */
6903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6905 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6907 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6908 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6909 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6910 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6911 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6912 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6914 /* FIXME: use matrix-type input source selection */
6915 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6916 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6917 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6935 #ifdef CONFIG_SND_HDA_POWER_SAVE
6936 #define alc882_loopbacks alc880_loopbacks
6939 /* pcm configuration: identiacal with ALC880 */
6940 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6941 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6942 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6943 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6946 * configuration and preset
6948 static const char *alc882_models[ALC882_MODEL_LAST] = {
6949 [ALC882_3ST_DIG] = "3stack-dig",
6950 [ALC882_6ST_DIG] = "6stack-dig",
6951 [ALC882_ARIMA] = "arima",
6952 [ALC882_W2JC] = "w2jc",
6953 [ALC882_TARGA] = "targa",
6954 [ALC882_ASUS_A7J] = "asus-a7j",
6955 [ALC882_ASUS_A7M] = "asus-a7m",
6956 [ALC885_MACPRO] = "macpro",
6957 [ALC885_MB5] = "mb5",
6958 [ALC885_MBP3] = "mbp3",
6959 [ALC885_IMAC24] = "imac24",
6960 [ALC882_AUTO] = "auto",
6963 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6964 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6965 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6966 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6967 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6968 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6969 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6970 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6971 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6972 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6973 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6974 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6975 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6979 static struct alc_config_preset alc882_presets[] = {
6980 [ALC882_3ST_DIG] = {
6981 .mixers = { alc882_base_mixer },
6982 .init_verbs = { alc882_init_verbs },
6983 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6984 .dac_nids = alc882_dac_nids,
6985 .dig_out_nid = ALC882_DIGOUT_NID,
6986 .dig_in_nid = ALC882_DIGIN_NID,
6987 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6988 .channel_mode = alc882_ch_modes,
6990 .input_mux = &alc882_capture_source,
6992 [ALC882_6ST_DIG] = {
6993 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6994 .init_verbs = { alc882_init_verbs },
6995 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6996 .dac_nids = alc882_dac_nids,
6997 .dig_out_nid = ALC882_DIGOUT_NID,
6998 .dig_in_nid = ALC882_DIGIN_NID,
6999 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7000 .channel_mode = alc882_sixstack_modes,
7001 .input_mux = &alc882_capture_source,
7004 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7005 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7006 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7007 .dac_nids = alc882_dac_nids,
7008 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7009 .channel_mode = alc882_sixstack_modes,
7010 .input_mux = &alc882_capture_source,
7013 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7014 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7015 alc880_gpio1_init_verbs },
7016 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7017 .dac_nids = alc882_dac_nids,
7018 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7019 .channel_mode = alc880_threestack_modes,
7021 .input_mux = &alc882_capture_source,
7022 .dig_out_nid = ALC882_DIGOUT_NID,
7025 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7026 .init_verbs = { alc885_mbp3_init_verbs,
7027 alc880_gpio1_init_verbs },
7028 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7029 .dac_nids = alc882_dac_nids,
7030 .channel_mode = alc885_mbp_6ch_modes,
7031 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7032 .input_mux = &alc882_capture_source,
7033 .dig_out_nid = ALC882_DIGOUT_NID,
7034 .dig_in_nid = ALC882_DIGIN_NID,
7035 .unsol_event = alc_automute_amp_unsol_event,
7036 .init_hook = alc885_mbp3_init_hook,
7039 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7040 .init_verbs = { alc885_mb5_init_verbs,
7041 alc880_gpio1_init_verbs },
7042 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7043 .dac_nids = alc882_dac_nids,
7044 .channel_mode = alc885_mb5_6ch_modes,
7045 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7046 .input_mux = &mb5_capture_source,
7047 .dig_out_nid = ALC882_DIGOUT_NID,
7048 .dig_in_nid = ALC882_DIGIN_NID,
7051 .mixers = { alc882_macpro_mixer },
7052 .init_verbs = { alc882_macpro_init_verbs },
7053 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7054 .dac_nids = alc882_dac_nids,
7055 .dig_out_nid = ALC882_DIGOUT_NID,
7056 .dig_in_nid = ALC882_DIGIN_NID,
7057 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7058 .channel_mode = alc882_ch_modes,
7059 .input_mux = &alc882_capture_source,
7060 .init_hook = alc885_macpro_init_hook,
7063 .mixers = { alc885_imac24_mixer },
7064 .init_verbs = { alc885_imac24_init_verbs },
7065 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7066 .dac_nids = alc882_dac_nids,
7067 .dig_out_nid = ALC882_DIGOUT_NID,
7068 .dig_in_nid = ALC882_DIGIN_NID,
7069 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7070 .channel_mode = alc882_ch_modes,
7071 .input_mux = &alc882_capture_source,
7072 .unsol_event = alc_automute_amp_unsol_event,
7073 .init_hook = alc885_imac24_init_hook,
7076 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7077 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7078 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7079 .dac_nids = alc882_dac_nids,
7080 .dig_out_nid = ALC882_DIGOUT_NID,
7081 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7082 .adc_nids = alc882_adc_nids,
7083 .capsrc_nids = alc882_capsrc_nids,
7084 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7085 .channel_mode = alc882_3ST_6ch_modes,
7087 .input_mux = &alc882_capture_source,
7088 .unsol_event = alc882_targa_unsol_event,
7089 .init_hook = alc882_targa_init_hook,
7091 [ALC882_ASUS_A7J] = {
7092 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7093 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7094 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7095 .dac_nids = alc882_dac_nids,
7096 .dig_out_nid = ALC882_DIGOUT_NID,
7097 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7098 .adc_nids = alc882_adc_nids,
7099 .capsrc_nids = alc882_capsrc_nids,
7100 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7101 .channel_mode = alc882_3ST_6ch_modes,
7103 .input_mux = &alc882_capture_source,
7105 [ALC882_ASUS_A7M] = {
7106 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7107 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7108 alc880_gpio1_init_verbs,
7109 alc882_asus_a7m_verbs },
7110 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7111 .dac_nids = alc882_dac_nids,
7112 .dig_out_nid = ALC882_DIGOUT_NID,
7113 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7114 .channel_mode = alc880_threestack_modes,
7116 .input_mux = &alc882_capture_source,
7125 PINFIX_ABIT_AW9D_MAX
7128 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7129 { 0x15, 0x01080104 }, /* side */
7130 { 0x16, 0x01011012 }, /* rear */
7131 { 0x17, 0x01016011 }, /* clfe */
7135 static const struct alc_pincfg *alc882_pin_fixes[] = {
7136 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7139 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7140 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7145 * BIOS auto configuration
7147 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7148 hda_nid_t nid, int pin_type,
7152 struct alc_spec *spec = codec->spec;
7155 alc_set_pin_output(codec, nid, pin_type);
7156 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7159 idx = spec->multiout.dac_nids[dac_idx] - 2;
7160 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7164 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7166 struct alc_spec *spec = codec->spec;
7169 for (i = 0; i <= HDA_SIDE; i++) {
7170 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7171 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7173 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7178 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7180 struct alc_spec *spec = codec->spec;
7183 pin = spec->autocfg.hp_pins[0];
7184 if (pin) /* connect to front */
7186 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7187 pin = spec->autocfg.speaker_pins[0];
7189 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7192 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7193 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7195 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7197 struct alc_spec *spec = codec->spec;
7200 for (i = 0; i < AUTO_PIN_LAST; i++) {
7201 hda_nid_t nid = spec->autocfg.input_pins[i];
7204 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7205 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7206 snd_hda_codec_write(codec, nid, 0,
7207 AC_VERB_SET_AMP_GAIN_MUTE,
7212 static void alc882_auto_init_input_src(struct hda_codec *codec)
7214 struct alc_spec *spec = codec->spec;
7217 for (c = 0; c < spec->num_adc_nids; c++) {
7218 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7219 hda_nid_t nid = spec->capsrc_nids[c];
7220 unsigned int mux_idx;
7221 const struct hda_input_mux *imux;
7222 int conns, mute, idx, item;
7224 conns = snd_hda_get_connections(codec, nid, conn_list,
7225 ARRAY_SIZE(conn_list));
7228 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7229 imux = &spec->input_mux[mux_idx];
7230 for (idx = 0; idx < conns; idx++) {
7231 /* if the current connection is the selected one,
7232 * unmute it as default - otherwise mute it
7234 mute = AMP_IN_MUTE(idx);
7235 for (item = 0; item < imux->num_items; item++) {
7236 if (imux->items[item].index == idx) {
7237 if (spec->cur_mux[c] == item)
7238 mute = AMP_IN_UNMUTE(idx);
7242 /* check if we have a selector or mixer
7243 * we could check for the widget type instead, but
7244 * just check for Amp-In presence (in case of mixer
7245 * without amp-in there is something wrong, this
7246 * function shouldn't be used or capsrc nid is wrong)
7248 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7249 snd_hda_codec_write(codec, nid, 0,
7250 AC_VERB_SET_AMP_GAIN_MUTE,
7252 else if (mute != AMP_IN_MUTE(idx))
7253 snd_hda_codec_write(codec, nid, 0,
7254 AC_VERB_SET_CONNECT_SEL,
7260 /* add mic boosts if needed */
7261 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7263 struct alc_spec *spec = codec->spec;
7267 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7268 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7269 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7271 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7275 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7276 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7277 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7279 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7286 /* almost identical with ALC880 parser... */
7287 static int alc882_parse_auto_config(struct hda_codec *codec)
7289 struct alc_spec *spec = codec->spec;
7290 int err = alc880_parse_auto_config(codec);
7295 return 0; /* no config found */
7297 err = alc_auto_add_mic_boost(codec);
7301 /* hack - override the init verbs */
7302 spec->init_verbs[0] = alc882_auto_init_verbs;
7304 return 1; /* config found */
7307 /* additional initialization for auto-configuration model */
7308 static void alc882_auto_init(struct hda_codec *codec)
7310 struct alc_spec *spec = codec->spec;
7311 alc882_auto_init_multi_out(codec);
7312 alc882_auto_init_hp_out(codec);
7313 alc882_auto_init_analog_input(codec);
7314 alc882_auto_init_input_src(codec);
7315 if (spec->unsol_event)
7316 alc_inithook(codec);
7319 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7321 static int patch_alc882(struct hda_codec *codec)
7323 struct alc_spec *spec;
7324 int err, board_config;
7326 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7332 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7336 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7337 /* Pick up systems that don't supply PCI SSID */
7338 switch (codec->subsystem_id) {
7339 case 0x106b0c00: /* Mac Pro */
7340 board_config = ALC885_MACPRO;
7342 case 0x106b1000: /* iMac 24 */
7343 case 0x106b2800: /* AppleTV */
7344 case 0x106b3e00: /* iMac 24 Aluminium */
7345 board_config = ALC885_IMAC24;
7347 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7348 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7349 case 0x106b00a4: /* MacbookPro4,1 */
7350 case 0x106b2c00: /* Macbook Pro rev3 */
7351 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7352 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7353 board_config = ALC885_MBP3;
7355 case 0x106b3f00: /* Macbook 5,1 */
7356 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7357 * seems not working, so apparently
7358 * no perfect solution yet
7360 board_config = ALC885_MB5;
7363 /* ALC889A is handled better as ALC888-compatible */
7364 if (codec->revision_id == 0x100101 ||
7365 codec->revision_id == 0x100103) {
7367 return patch_alc883(codec);
7369 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7370 "trying auto-probe from BIOS...\n",
7372 board_config = ALC882_AUTO;
7376 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7378 if (board_config == ALC882_AUTO) {
7379 /* automatic parse from the BIOS config */
7380 err = alc882_parse_auto_config(codec);
7386 "hda_codec: Cannot set up configuration "
7387 "from BIOS. Using base mode...\n");
7388 board_config = ALC882_3ST_DIG;
7392 err = snd_hda_attach_beep_device(codec, 0x1);
7398 if (board_config != ALC882_AUTO)
7399 setup_preset(spec, &alc882_presets[board_config]);
7401 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7402 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7403 /* FIXME: setup DAC5 */
7404 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7405 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7407 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7408 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7410 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7411 if (!spec->adc_nids && spec->input_mux) {
7412 /* check whether NID 0x07 is valid */
7413 unsigned int wcap = get_wcaps(codec, 0x07);
7415 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7416 if (wcap != AC_WID_AUD_IN) {
7417 spec->adc_nids = alc882_adc_nids_alt;
7418 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7419 spec->capsrc_nids = alc882_capsrc_nids_alt;
7421 spec->adc_nids = alc882_adc_nids;
7422 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7423 spec->capsrc_nids = alc882_capsrc_nids;
7426 set_capture_mixer(spec);
7427 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7429 spec->vmaster_nid = 0x0c;
7431 codec->patch_ops = alc_patch_ops;
7432 if (board_config == ALC882_AUTO)
7433 spec->init_hook = alc882_auto_init;
7434 #ifdef CONFIG_SND_HDA_POWER_SAVE
7435 if (!spec->loopback.amplist)
7436 spec->loopback.amplist = alc882_loopbacks;
7438 codec->proc_widget_hook = print_realtek_coef;
7446 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7447 * configuration. Each pin widget can choose any input DACs and a mixer.
7448 * Each ADC is connected from a mixer of all inputs. This makes possible
7449 * 6-channel independent captures.
7451 * In addition, an independent DAC for the multi-playback (not used in this
7454 #define ALC883_DIGOUT_NID 0x06
7455 #define ALC883_DIGIN_NID 0x0a
7457 #define ALC1200_DIGOUT_NID 0x10
7459 static hda_nid_t alc883_dac_nids[4] = {
7460 /* front, rear, clfe, rear_surr */
7461 0x02, 0x03, 0x04, 0x05
7464 static hda_nid_t alc883_adc_nids[2] = {
7469 static hda_nid_t alc883_adc_nids_alt[1] = {
7474 static hda_nid_t alc883_adc_nids_rev[2] = {
7479 #define alc889_adc_nids alc880_adc_nids
7481 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7483 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7485 #define alc889_capsrc_nids alc882_capsrc_nids
7488 /* FIXME: should be a matrix-type input source selection */
7490 static struct hda_input_mux alc883_capture_source = {
7494 { "Front Mic", 0x1 },
7500 static struct hda_input_mux alc883_3stack_6ch_intel = {
7504 { "Front Mic", 0x0 },
7510 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7518 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7528 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7536 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7540 { "Front Mic", 0x1 },
7545 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7553 static struct hda_input_mux alc889A_mb31_capture_source = {
7557 /* Front Mic (0x01) unused */
7559 /* Line 2 (0x03) unused */
7560 /* CD (0x04) unsused? */
7567 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7574 static struct hda_verb alc883_3ST_ch2_init[] = {
7575 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7576 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7577 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7578 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7585 static struct hda_verb alc883_3ST_ch4_init[] = {
7586 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7587 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7588 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7589 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7590 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7597 static struct hda_verb alc883_3ST_ch6_init[] = {
7598 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7599 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7600 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7601 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7602 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7603 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7607 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7608 { 2, alc883_3ST_ch2_init },
7609 { 4, alc883_3ST_ch4_init },
7610 { 6, alc883_3ST_ch6_init },
7616 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7617 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7618 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7619 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7620 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7627 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7628 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7629 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7630 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7631 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7632 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7639 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7640 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7641 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7642 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7645 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7649 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7650 { 2, alc883_3ST_ch2_intel_init },
7651 { 4, alc883_3ST_ch4_intel_init },
7652 { 6, alc883_3ST_ch6_intel_init },
7658 static struct hda_verb alc883_sixstack_ch6_init[] = {
7659 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7660 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7661 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7662 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7669 static struct hda_verb alc883_sixstack_ch8_init[] = {
7670 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7671 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7672 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7673 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7677 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7678 { 6, alc883_sixstack_ch6_init },
7679 { 8, alc883_sixstack_ch8_init },
7682 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7683 static struct hda_verb alc889A_mb31_ch2_init[] = {
7684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7685 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7686 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7687 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7691 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7692 static struct hda_verb alc889A_mb31_ch4_init[] = {
7693 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7694 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7700 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7701 static struct hda_verb alc889A_mb31_ch5_init[] = {
7702 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7703 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7704 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7705 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7709 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7710 static struct hda_verb alc889A_mb31_ch6_init[] = {
7711 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7713 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7718 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7719 { 2, alc889A_mb31_ch2_init },
7720 { 4, alc889A_mb31_ch4_init },
7721 { 5, alc889A_mb31_ch5_init },
7722 { 6, alc889A_mb31_ch6_init },
7725 static struct hda_verb alc883_medion_eapd_verbs[] = {
7726 /* eanable EAPD on medion laptop */
7727 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7728 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7732 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7733 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7736 static struct snd_kcontrol_new alc883_base_mixer[] = {
7737 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7738 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7739 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7740 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7741 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7742 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7743 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7744 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7745 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7746 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7748 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7749 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7750 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7751 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7753 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7755 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7756 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7757 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7761 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7762 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7763 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7764 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7765 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7766 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7767 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7772 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7773 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7778 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7779 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7780 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7781 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7782 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7783 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7784 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7786 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7787 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7788 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7792 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7793 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7794 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7796 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7798 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7799 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7800 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7801 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7802 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7806 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7807 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7808 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7809 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7810 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7811 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7812 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7813 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7817 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7818 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7819 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7823 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7824 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7825 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7827 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7828 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7829 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7830 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7831 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7832 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7833 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7834 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7835 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7836 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7838 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7839 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7841 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7846 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7847 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7848 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7850 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7851 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7853 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7854 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7855 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7862 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7863 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7864 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7865 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7866 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7870 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7871 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7872 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7873 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7874 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7875 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7876 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7877 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7878 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7880 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7881 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7882 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7883 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7886 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7887 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7888 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7889 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7893 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7894 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7896 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7897 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7898 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7899 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7900 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7901 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7902 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7903 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7904 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7905 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7906 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7908 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7913 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7914 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7915 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7916 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7917 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7918 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7921 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7922 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7924 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7928 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7929 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7930 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7931 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7932 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7933 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7935 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7940 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7941 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7942 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7947 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7948 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7949 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7953 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7954 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7956 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7957 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7958 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7959 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7961 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7962 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7966 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7968 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7969 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7970 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7971 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7973 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7974 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7978 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7982 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7983 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7984 0x0d, 1, 0x0, HDA_OUTPUT),
7985 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7986 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7987 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7989 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7993 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7995 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7998 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8003 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8006 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8007 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8008 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8009 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8011 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8012 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8013 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8014 /* Output switches */
8015 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8016 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8017 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8020 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8023 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8025 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8029 static struct hda_bind_ctls alc883_bind_cap_vol = {
8030 .ops = &snd_hda_bind_vol,
8032 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8033 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8038 static struct hda_bind_ctls alc883_bind_cap_switch = {
8039 .ops = &snd_hda_bind_sw,
8041 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8042 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8047 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8048 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8049 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8051 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8052 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8059 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8060 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8061 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8063 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8064 /* .name = "Capture Source", */
8065 .name = "Input Source",
8067 .info = alc_mux_enum_info,
8068 .get = alc_mux_enum_get,
8069 .put = alc_mux_enum_put,
8074 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8077 .name = "Channel Mode",
8078 .info = alc_ch_mode_info,
8079 .get = alc_ch_mode_get,
8080 .put = alc_ch_mode_put,
8085 static struct hda_verb alc883_init_verbs[] = {
8086 /* ADC1: mute amp left and right */
8087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8088 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8089 /* ADC2: mute amp left and right */
8090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8091 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8092 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8095 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8097 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8098 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8102 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8105 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8106 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8107 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8109 /* mute analog input loopbacks */
8110 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8111 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8114 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8116 /* Front Pin: output 0 (0x0c) */
8117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8119 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8120 /* Rear Pin: output 1 (0x0d) */
8121 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8123 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8124 /* CLFE Pin: output 2 (0x0e) */
8125 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8127 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8128 /* Side Pin: output 3 (0x0f) */
8129 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8130 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8131 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8132 /* Mic (rear) pin: input vref at 80% */
8133 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8135 /* Front Mic pin: input vref at 80% */
8136 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8138 /* Line In pin: input */
8139 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8140 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8141 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8142 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8143 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8144 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8145 /* CD pin widget for input */
8146 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8148 /* FIXME: use matrix-type input source selection */
8149 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8163 /* toggle speaker-output according to the hp-jack state */
8164 static void alc883_mitac_init_hook(struct hda_codec *codec)
8166 struct alc_spec *spec = codec->spec;
8168 spec->autocfg.hp_pins[0] = 0x15;
8169 spec->autocfg.speaker_pins[0] = 0x14;
8170 spec->autocfg.speaker_pins[1] = 0x17;
8171 alc_automute_amp(codec);
8174 /* auto-toggle front mic */
8176 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8178 unsigned int present;
8181 present = snd_hda_codec_read(codec, 0x18, 0,
8182 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8183 bits = present ? HDA_AMP_MUTE : 0;
8184 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8188 static struct hda_verb alc883_mitac_verbs[] = {
8190 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8191 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8193 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8194 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8196 /* enable unsolicited event */
8197 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8198 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8203 static struct hda_verb alc883_clevo_m720_verbs[] = {
8205 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8206 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8208 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8209 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8211 /* enable unsolicited event */
8212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8218 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8220 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8223 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8226 /* enable unsolicited event */
8227 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8232 static struct hda_verb alc883_tagra_verbs[] = {
8233 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8234 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8237 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8239 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8240 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8241 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8243 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8244 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8245 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8246 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8251 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8252 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8253 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8254 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8258 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8261 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8266 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8267 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8268 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8270 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8271 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8275 static struct hda_verb alc883_haier_w66_verbs[] = {
8276 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8277 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8279 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8281 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8282 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8283 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8284 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8288 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8290 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8292 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8293 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8294 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8295 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8296 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8300 static struct hda_verb alc888_6st_dell_verbs[] = {
8301 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8305 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8307 struct alc_spec *spec = codec->spec;
8309 spec->autocfg.hp_pins[0] = 0x1b;
8310 spec->autocfg.speaker_pins[0] = 0x14;
8311 spec->autocfg.speaker_pins[1] = 0x16;
8312 spec->autocfg.speaker_pins[2] = 0x18;
8313 alc_automute_amp(codec);
8316 static struct hda_verb alc888_3st_hp_verbs[] = {
8317 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8318 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8319 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8320 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8327 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8328 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8329 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8330 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8331 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8338 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8339 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8340 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8341 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8342 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8343 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8350 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8351 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8352 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8353 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8354 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8355 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8356 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8360 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8361 { 2, alc888_3st_hp_2ch_init },
8362 { 4, alc888_3st_hp_4ch_init },
8363 { 6, alc888_3st_hp_6ch_init },
8366 /* toggle front-jack and RCA according to the hp-jack state */
8367 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8369 unsigned int present;
8371 present = snd_hda_codec_read(codec, 0x1b, 0,
8372 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8373 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8374 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8375 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8376 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8379 /* toggle RCA according to the front-jack state */
8380 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8382 unsigned int present;
8384 present = snd_hda_codec_read(codec, 0x14, 0,
8385 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8386 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8387 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8390 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8393 if ((res >> 26) == ALC880_HP_EVENT)
8394 alc888_lenovo_ms7195_front_automute(codec);
8395 if ((res >> 26) == ALC880_FRONT_EVENT)
8396 alc888_lenovo_ms7195_rca_automute(codec);
8399 static struct hda_verb alc883_medion_md2_verbs[] = {
8400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8401 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8403 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8405 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8409 /* toggle speaker-output according to the hp-jack state */
8410 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8412 struct alc_spec *spec = codec->spec;
8414 spec->autocfg.hp_pins[0] = 0x14;
8415 spec->autocfg.speaker_pins[0] = 0x15;
8416 alc_automute_amp(codec);
8419 /* toggle speaker-output according to the hp-jack state */
8420 #define alc883_tagra_init_hook alc882_targa_init_hook
8421 #define alc883_tagra_unsol_event alc882_targa_unsol_event
8423 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8425 unsigned int present;
8427 present = snd_hda_codec_read(codec, 0x18, 0,
8428 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8429 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8430 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8433 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8435 struct alc_spec *spec = codec->spec;
8437 spec->autocfg.hp_pins[0] = 0x15;
8438 spec->autocfg.speaker_pins[0] = 0x14;
8439 alc_automute_amp(codec);
8440 alc883_clevo_m720_mic_automute(codec);
8443 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8446 switch (res >> 26) {
8447 case ALC880_MIC_EVENT:
8448 alc883_clevo_m720_mic_automute(codec);
8451 alc_automute_amp_unsol_event(codec, res);
8456 /* toggle speaker-output according to the hp-jack state */
8457 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8459 struct alc_spec *spec = codec->spec;
8461 spec->autocfg.hp_pins[0] = 0x14;
8462 spec->autocfg.speaker_pins[0] = 0x15;
8463 alc_automute_amp(codec);
8466 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8468 struct alc_spec *spec = codec->spec;
8470 spec->autocfg.hp_pins[0] = 0x1b;
8471 spec->autocfg.speaker_pins[0] = 0x14;
8472 alc_automute_amp(codec);
8475 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8477 unsigned int present;
8480 present = snd_hda_codec_read(codec, 0x14, 0,
8481 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8482 bits = present ? HDA_AMP_MUTE : 0;
8483 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8484 HDA_AMP_MUTE, bits);
8487 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8489 unsigned int present;
8492 present = snd_hda_codec_read(codec, 0x1b, 0,
8493 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8494 bits = present ? HDA_AMP_MUTE : 0;
8495 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8496 HDA_AMP_MUTE, bits);
8497 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8498 HDA_AMP_MUTE, bits);
8501 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8504 if ((res >> 26) == ALC880_HP_EVENT)
8505 alc883_lenovo_101e_all_automute(codec);
8506 if ((res >> 26) == ALC880_FRONT_EVENT)
8507 alc883_lenovo_101e_ispeaker_automute(codec);
8510 /* toggle speaker-output according to the hp-jack state */
8511 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8513 struct alc_spec *spec = codec->spec;
8515 spec->autocfg.hp_pins[0] = 0x14;
8516 spec->autocfg.speaker_pins[0] = 0x15;
8517 spec->autocfg.speaker_pins[1] = 0x16;
8518 alc_automute_amp(codec);
8521 static struct hda_verb alc883_acer_eapd_verbs[] = {
8522 /* HP Pin: output 0 (0x0c) */
8523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8525 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8526 /* Front Pin: output 0 (0x0c) */
8527 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8529 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8530 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8531 /* eanable EAPD on medion laptop */
8532 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8533 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8534 /* enable unsolicited event */
8535 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8539 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8541 struct alc_spec *spec = codec->spec;
8543 spec->autocfg.hp_pins[0] = 0x1b;
8544 spec->autocfg.speaker_pins[0] = 0x14;
8545 spec->autocfg.speaker_pins[1] = 0x15;
8546 spec->autocfg.speaker_pins[2] = 0x16;
8547 spec->autocfg.speaker_pins[3] = 0x17;
8548 alc_automute_amp(codec);
8551 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8553 struct alc_spec *spec = codec->spec;
8555 spec->autocfg.hp_pins[0] = 0x1b;
8556 spec->autocfg.speaker_pins[0] = 0x14;
8557 spec->autocfg.speaker_pins[1] = 0x15;
8558 spec->autocfg.speaker_pins[2] = 0x16;
8559 spec->autocfg.speaker_pins[3] = 0x17;
8560 spec->autocfg.speaker_pins[4] = 0x1a;
8561 alc_automute_amp(codec);
8565 * generic initialization of ADC, input mixers and output mixers
8567 static struct hda_verb alc883_auto_init_verbs[] = {
8569 * Unmute ADC0-2 and set the default input to mic-in
8571 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8574 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8576 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8578 * Note: PASD motherboards uses the Line In 2 as the input for
8579 * front panel mic (mic 2)
8581 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8584 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8589 * Set up output mixers (0x0c - 0x0f)
8591 /* set vol=0 to output mixers */
8592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8593 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8595 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8596 /* set up input amps for analog loopback */
8597 /* Amp Indices: DAC = 0, mixer = 1 */
8598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8600 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8601 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8605 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8606 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8607 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8609 /* FIXME: use matrix-type input source selection */
8610 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8615 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8621 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8627 static struct hda_verb alc888_asus_m90v_verbs[] = {
8628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8629 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8630 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8631 /* enable unsolicited event */
8632 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8633 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8637 static void alc883_nb_mic_automute(struct hda_codec *codec)
8639 unsigned int present;
8641 present = snd_hda_codec_read(codec, 0x18, 0,
8642 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8643 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8644 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8645 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8646 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8649 static void alc883_M90V_init_hook(struct hda_codec *codec)
8651 struct alc_spec *spec = codec->spec;
8653 spec->autocfg.hp_pins[0] = 0x1b;
8654 spec->autocfg.speaker_pins[0] = 0x14;
8655 spec->autocfg.speaker_pins[1] = 0x15;
8656 spec->autocfg.speaker_pins[2] = 0x16;
8657 alc_automute_pin(codec);
8660 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8663 switch (res >> 26) {
8664 case ALC880_MIC_EVENT:
8665 alc883_nb_mic_automute(codec);
8668 alc_sku_unsol_event(codec, res);
8673 static void alc883_mode2_inithook(struct hda_codec *codec)
8675 alc883_M90V_init_hook(codec);
8676 alc883_nb_mic_automute(codec);
8679 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8685 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8686 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8687 /* enable unsolicited event */
8688 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8692 static void alc883_eee1601_inithook(struct hda_codec *codec)
8694 struct alc_spec *spec = codec->spec;
8696 spec->autocfg.hp_pins[0] = 0x14;
8697 spec->autocfg.speaker_pins[0] = 0x1b;
8698 alc_automute_pin(codec);
8701 static struct hda_verb alc889A_mb31_verbs[] = {
8702 /* Init rear pin (used as headphone output) */
8703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8704 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8706 /* Init line pin (used as output in 4ch and 6ch mode) */
8707 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8708 /* Init line 2 pin (used as headphone out by default) */
8709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8714 /* Mute speakers according to the headphone jack state */
8715 static void alc889A_mb31_automute(struct hda_codec *codec)
8717 unsigned int present;
8719 /* Mute only in 2ch or 4ch mode */
8720 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8722 present = snd_hda_codec_read(codec, 0x15, 0,
8723 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8724 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8725 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8726 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8727 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8731 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8733 if ((res >> 26) == ALC880_HP_EVENT)
8734 alc889A_mb31_automute(codec);
8737 #ifdef CONFIG_SND_HDA_POWER_SAVE
8738 #define alc883_loopbacks alc880_loopbacks
8741 /* pcm configuration: identiacal with ALC880 */
8742 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8743 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8744 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8745 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8746 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8749 * configuration and preset
8751 static const char *alc883_models[ALC883_MODEL_LAST] = {
8752 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8753 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8754 [ALC883_3ST_6ch] = "3stack-6ch",
8755 [ALC883_6ST_DIG] = "6stack-dig",
8756 [ALC883_TARGA_DIG] = "targa-dig",
8757 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8758 [ALC883_ACER] = "acer",
8759 [ALC883_ACER_ASPIRE] = "acer-aspire",
8760 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8761 [ALC883_MEDION] = "medion",
8762 [ALC883_MEDION_MD2] = "medion-md2",
8763 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8764 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8765 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8766 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8767 [ALC888_LENOVO_SKY] = "lenovo-sky",
8768 [ALC883_HAIER_W66] = "haier-w66",
8769 [ALC888_3ST_HP] = "3stack-hp",
8770 [ALC888_6ST_DELL] = "6stack-dell",
8771 [ALC883_MITAC] = "mitac",
8772 [ALC883_CLEVO_M720] = "clevo-m720",
8773 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8774 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8775 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8776 [ALC1200_ASUS_P5Q] = "asus-p5q",
8777 [ALC889A_MB31] = "mb31",
8778 [ALC883_AUTO] = "auto",
8781 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8782 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8783 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8784 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8785 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8786 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8787 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8788 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8789 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8790 ALC888_ACER_ASPIRE_4930G),
8791 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8792 ALC888_ACER_ASPIRE_4930G),
8793 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8794 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8795 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8796 ALC888_ACER_ASPIRE_4930G),
8797 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8798 ALC888_ACER_ASPIRE_4930G),
8799 /* default Acer -- disabled as it causes more problems.
8800 * model=auto should work fine now
8802 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8803 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8804 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8805 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8806 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8807 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8808 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8809 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8810 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8811 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8812 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8813 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8814 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8815 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8816 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8817 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8818 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8819 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8820 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8821 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8822 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8823 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8824 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8825 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8826 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8827 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8828 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8829 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8830 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8831 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8832 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8833 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8834 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8835 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8836 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8837 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8838 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8839 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8840 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8841 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8842 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8843 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8844 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8845 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8846 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8847 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8848 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8849 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8850 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8851 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8852 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8853 ALC883_FUJITSU_PI2515),
8854 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8855 ALC888_FUJITSU_XA3530),
8856 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8857 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8858 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8859 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8860 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8861 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8862 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8863 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8864 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8865 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8866 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8867 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8868 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8869 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8873 static hda_nid_t alc883_slave_dig_outs[] = {
8874 ALC1200_DIGOUT_NID, 0,
8877 static hda_nid_t alc1200_slave_dig_outs[] = {
8878 ALC883_DIGOUT_NID, 0,
8881 static struct alc_config_preset alc883_presets[] = {
8882 [ALC883_3ST_2ch_DIG] = {
8883 .mixers = { alc883_3ST_2ch_mixer },
8884 .init_verbs = { alc883_init_verbs },
8885 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8886 .dac_nids = alc883_dac_nids,
8887 .dig_out_nid = ALC883_DIGOUT_NID,
8888 .dig_in_nid = ALC883_DIGIN_NID,
8889 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8890 .channel_mode = alc883_3ST_2ch_modes,
8891 .input_mux = &alc883_capture_source,
8893 [ALC883_3ST_6ch_DIG] = {
8894 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8895 .init_verbs = { alc883_init_verbs },
8896 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8897 .dac_nids = alc883_dac_nids,
8898 .dig_out_nid = ALC883_DIGOUT_NID,
8899 .dig_in_nid = ALC883_DIGIN_NID,
8900 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8901 .channel_mode = alc883_3ST_6ch_modes,
8903 .input_mux = &alc883_capture_source,
8905 [ALC883_3ST_6ch] = {
8906 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8907 .init_verbs = { alc883_init_verbs },
8908 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8909 .dac_nids = alc883_dac_nids,
8910 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8911 .channel_mode = alc883_3ST_6ch_modes,
8913 .input_mux = &alc883_capture_source,
8915 [ALC883_3ST_6ch_INTEL] = {
8916 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8917 .init_verbs = { alc883_init_verbs },
8918 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8919 .dac_nids = alc883_dac_nids,
8920 .dig_out_nid = ALC883_DIGOUT_NID,
8921 .dig_in_nid = ALC883_DIGIN_NID,
8922 .slave_dig_outs = alc883_slave_dig_outs,
8923 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8924 .channel_mode = alc883_3ST_6ch_intel_modes,
8926 .input_mux = &alc883_3stack_6ch_intel,
8928 [ALC883_6ST_DIG] = {
8929 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8930 .init_verbs = { alc883_init_verbs },
8931 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8932 .dac_nids = alc883_dac_nids,
8933 .dig_out_nid = ALC883_DIGOUT_NID,
8934 .dig_in_nid = ALC883_DIGIN_NID,
8935 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8936 .channel_mode = alc883_sixstack_modes,
8937 .input_mux = &alc883_capture_source,
8939 [ALC883_TARGA_DIG] = {
8940 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8941 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8942 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8943 .dac_nids = alc883_dac_nids,
8944 .dig_out_nid = ALC883_DIGOUT_NID,
8945 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8946 .channel_mode = alc883_3ST_6ch_modes,
8948 .input_mux = &alc883_capture_source,
8949 .unsol_event = alc883_tagra_unsol_event,
8950 .init_hook = alc883_tagra_init_hook,
8952 [ALC883_TARGA_2ch_DIG] = {
8953 .mixers = { alc883_tagra_2ch_mixer},
8954 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8955 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8956 .dac_nids = alc883_dac_nids,
8957 .adc_nids = alc883_adc_nids_alt,
8958 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8959 .dig_out_nid = ALC883_DIGOUT_NID,
8960 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8961 .channel_mode = alc883_3ST_2ch_modes,
8962 .input_mux = &alc883_capture_source,
8963 .unsol_event = alc883_tagra_unsol_event,
8964 .init_hook = alc883_tagra_init_hook,
8967 .mixers = { alc883_base_mixer },
8968 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8969 * and the headphone jack. Turn this on and rely on the
8970 * standard mute methods whenever the user wants to turn
8971 * these outputs off.
8973 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8974 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8975 .dac_nids = alc883_dac_nids,
8976 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8977 .channel_mode = alc883_3ST_2ch_modes,
8978 .input_mux = &alc883_capture_source,
8980 [ALC883_ACER_ASPIRE] = {
8981 .mixers = { alc883_acer_aspire_mixer },
8982 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8983 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8984 .dac_nids = alc883_dac_nids,
8985 .dig_out_nid = ALC883_DIGOUT_NID,
8986 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8987 .channel_mode = alc883_3ST_2ch_modes,
8988 .input_mux = &alc883_capture_source,
8989 .unsol_event = alc_automute_amp_unsol_event,
8990 .init_hook = alc883_acer_aspire_init_hook,
8992 [ALC888_ACER_ASPIRE_4930G] = {
8993 .mixers = { alc888_base_mixer,
8994 alc883_chmode_mixer },
8995 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8996 alc888_acer_aspire_4930g_verbs },
8997 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8998 .dac_nids = alc883_dac_nids,
8999 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9000 .adc_nids = alc883_adc_nids_rev,
9001 .capsrc_nids = alc883_capsrc_nids_rev,
9002 .dig_out_nid = ALC883_DIGOUT_NID,
9003 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9004 .channel_mode = alc883_3ST_6ch_modes,
9007 ARRAY_SIZE(alc888_2_capture_sources),
9008 .input_mux = alc888_2_capture_sources,
9009 .unsol_event = alc_automute_amp_unsol_event,
9010 .init_hook = alc888_acer_aspire_4930g_init_hook,
9013 .mixers = { alc883_fivestack_mixer,
9014 alc883_chmode_mixer },
9015 .init_verbs = { alc883_init_verbs,
9016 alc883_medion_eapd_verbs },
9017 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9018 .dac_nids = alc883_dac_nids,
9019 .adc_nids = alc883_adc_nids_alt,
9020 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9021 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9022 .channel_mode = alc883_sixstack_modes,
9023 .input_mux = &alc883_capture_source,
9025 [ALC883_MEDION_MD2] = {
9026 .mixers = { alc883_medion_md2_mixer},
9027 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9028 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9029 .dac_nids = alc883_dac_nids,
9030 .dig_out_nid = ALC883_DIGOUT_NID,
9031 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9032 .channel_mode = alc883_3ST_2ch_modes,
9033 .input_mux = &alc883_capture_source,
9034 .unsol_event = alc_automute_amp_unsol_event,
9035 .init_hook = alc883_medion_md2_init_hook,
9037 [ALC883_LAPTOP_EAPD] = {
9038 .mixers = { alc883_base_mixer },
9039 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9040 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9041 .dac_nids = alc883_dac_nids,
9042 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9043 .channel_mode = alc883_3ST_2ch_modes,
9044 .input_mux = &alc883_capture_source,
9046 [ALC883_CLEVO_M720] = {
9047 .mixers = { alc883_clevo_m720_mixer },
9048 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9049 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9050 .dac_nids = alc883_dac_nids,
9051 .dig_out_nid = ALC883_DIGOUT_NID,
9052 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9053 .channel_mode = alc883_3ST_2ch_modes,
9054 .input_mux = &alc883_capture_source,
9055 .unsol_event = alc883_clevo_m720_unsol_event,
9056 .init_hook = alc883_clevo_m720_init_hook,
9058 [ALC883_LENOVO_101E_2ch] = {
9059 .mixers = { alc883_lenovo_101e_2ch_mixer},
9060 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9061 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9062 .dac_nids = alc883_dac_nids,
9063 .adc_nids = alc883_adc_nids_alt,
9064 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9065 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9066 .channel_mode = alc883_3ST_2ch_modes,
9067 .input_mux = &alc883_lenovo_101e_capture_source,
9068 .unsol_event = alc883_lenovo_101e_unsol_event,
9069 .init_hook = alc883_lenovo_101e_all_automute,
9071 [ALC883_LENOVO_NB0763] = {
9072 .mixers = { alc883_lenovo_nb0763_mixer },
9073 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9074 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9075 .dac_nids = alc883_dac_nids,
9076 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9077 .channel_mode = alc883_3ST_2ch_modes,
9079 .input_mux = &alc883_lenovo_nb0763_capture_source,
9080 .unsol_event = alc_automute_amp_unsol_event,
9081 .init_hook = alc883_medion_md2_init_hook,
9083 [ALC888_LENOVO_MS7195_DIG] = {
9084 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9085 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9086 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9087 .dac_nids = alc883_dac_nids,
9088 .dig_out_nid = ALC883_DIGOUT_NID,
9089 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9090 .channel_mode = alc883_3ST_6ch_modes,
9092 .input_mux = &alc883_capture_source,
9093 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9094 .init_hook = alc888_lenovo_ms7195_front_automute,
9096 [ALC883_HAIER_W66] = {
9097 .mixers = { alc883_tagra_2ch_mixer},
9098 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9099 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9100 .dac_nids = alc883_dac_nids,
9101 .dig_out_nid = ALC883_DIGOUT_NID,
9102 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9103 .channel_mode = alc883_3ST_2ch_modes,
9104 .input_mux = &alc883_capture_source,
9105 .unsol_event = alc_automute_amp_unsol_event,
9106 .init_hook = alc883_haier_w66_init_hook,
9109 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9110 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9111 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9112 .dac_nids = alc883_dac_nids,
9113 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9114 .channel_mode = alc888_3st_hp_modes,
9116 .input_mux = &alc883_capture_source,
9117 .unsol_event = alc_automute_amp_unsol_event,
9118 .init_hook = alc888_3st_hp_init_hook,
9120 [ALC888_6ST_DELL] = {
9121 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9122 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9123 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9124 .dac_nids = alc883_dac_nids,
9125 .dig_out_nid = ALC883_DIGOUT_NID,
9126 .dig_in_nid = ALC883_DIGIN_NID,
9127 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9128 .channel_mode = alc883_sixstack_modes,
9129 .input_mux = &alc883_capture_source,
9130 .unsol_event = alc_automute_amp_unsol_event,
9131 .init_hook = alc888_6st_dell_init_hook,
9134 .mixers = { alc883_mitac_mixer },
9135 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9136 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9137 .dac_nids = alc883_dac_nids,
9138 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9139 .channel_mode = alc883_3ST_2ch_modes,
9140 .input_mux = &alc883_capture_source,
9141 .unsol_event = alc_automute_amp_unsol_event,
9142 .init_hook = alc883_mitac_init_hook,
9144 [ALC883_FUJITSU_PI2515] = {
9145 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9146 .init_verbs = { alc883_init_verbs,
9147 alc883_2ch_fujitsu_pi2515_verbs},
9148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9149 .dac_nids = alc883_dac_nids,
9150 .dig_out_nid = ALC883_DIGOUT_NID,
9151 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9152 .channel_mode = alc883_3ST_2ch_modes,
9153 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9154 .unsol_event = alc_automute_amp_unsol_event,
9155 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
9157 [ALC888_FUJITSU_XA3530] = {
9158 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9159 .init_verbs = { alc883_init_verbs,
9160 alc888_fujitsu_xa3530_verbs },
9161 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9162 .dac_nids = alc883_dac_nids,
9163 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9164 .adc_nids = alc883_adc_nids_rev,
9165 .capsrc_nids = alc883_capsrc_nids_rev,
9166 .dig_out_nid = ALC883_DIGOUT_NID,
9167 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9168 .channel_mode = alc888_4ST_8ch_intel_modes,
9170 ARRAY_SIZE(alc888_2_capture_sources),
9171 .input_mux = alc888_2_capture_sources,
9172 .unsol_event = alc_automute_amp_unsol_event,
9173 .init_hook = alc888_fujitsu_xa3530_init_hook,
9175 [ALC888_LENOVO_SKY] = {
9176 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9177 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9178 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9179 .dac_nids = alc883_dac_nids,
9180 .dig_out_nid = ALC883_DIGOUT_NID,
9181 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9182 .channel_mode = alc883_sixstack_modes,
9184 .input_mux = &alc883_lenovo_sky_capture_source,
9185 .unsol_event = alc_automute_amp_unsol_event,
9186 .init_hook = alc888_lenovo_sky_init_hook,
9188 [ALC888_ASUS_M90V] = {
9189 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9190 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9191 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9192 .dac_nids = alc883_dac_nids,
9193 .dig_out_nid = ALC883_DIGOUT_NID,
9194 .dig_in_nid = ALC883_DIGIN_NID,
9195 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9196 .channel_mode = alc883_3ST_6ch_modes,
9198 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9199 .unsol_event = alc883_mode2_unsol_event,
9200 .init_hook = alc883_mode2_inithook,
9202 [ALC888_ASUS_EEE1601] = {
9203 .mixers = { alc883_asus_eee1601_mixer },
9204 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9205 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9207 .dac_nids = alc883_dac_nids,
9208 .dig_out_nid = ALC883_DIGOUT_NID,
9209 .dig_in_nid = ALC883_DIGIN_NID,
9210 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9211 .channel_mode = alc883_3ST_2ch_modes,
9213 .input_mux = &alc883_asus_eee1601_capture_source,
9214 .unsol_event = alc_sku_unsol_event,
9215 .init_hook = alc883_eee1601_inithook,
9217 [ALC1200_ASUS_P5Q] = {
9218 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9219 .init_verbs = { alc883_init_verbs },
9220 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9221 .dac_nids = alc883_dac_nids,
9222 .dig_out_nid = ALC1200_DIGOUT_NID,
9223 .dig_in_nid = ALC883_DIGIN_NID,
9224 .slave_dig_outs = alc1200_slave_dig_outs,
9225 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9226 .channel_mode = alc883_sixstack_modes,
9227 .input_mux = &alc883_capture_source,
9230 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9231 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9232 alc880_gpio1_init_verbs },
9233 .adc_nids = alc883_adc_nids,
9234 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9235 .dac_nids = alc883_dac_nids,
9236 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9237 .channel_mode = alc889A_mb31_6ch_modes,
9238 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9239 .input_mux = &alc889A_mb31_capture_source,
9240 .dig_out_nid = ALC883_DIGOUT_NID,
9241 .unsol_event = alc889A_mb31_unsol_event,
9242 .init_hook = alc889A_mb31_automute,
9248 * BIOS auto configuration
9250 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9251 hda_nid_t nid, int pin_type,
9255 struct alc_spec *spec = codec->spec;
9258 alc_set_pin_output(codec, nid, pin_type);
9259 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9262 idx = spec->multiout.dac_nids[dac_idx] - 2;
9263 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9267 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9269 struct alc_spec *spec = codec->spec;
9272 for (i = 0; i <= HDA_SIDE; i++) {
9273 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9274 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9276 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9281 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9283 struct alc_spec *spec = codec->spec;
9286 pin = spec->autocfg.hp_pins[0];
9287 if (pin) /* connect to front */
9289 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9290 pin = spec->autocfg.speaker_pins[0];
9292 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9295 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9296 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9298 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9300 struct alc_spec *spec = codec->spec;
9303 for (i = 0; i < AUTO_PIN_LAST; i++) {
9304 hda_nid_t nid = spec->autocfg.input_pins[i];
9305 if (alc883_is_input_pin(nid)) {
9306 alc_set_input_pin(codec, nid, i);
9307 if (nid != ALC883_PIN_CD_NID &&
9308 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9309 snd_hda_codec_write(codec, nid, 0,
9310 AC_VERB_SET_AMP_GAIN_MUTE,
9316 #define alc883_auto_init_input_src alc882_auto_init_input_src
9318 /* almost identical with ALC880 parser... */
9319 static int alc883_parse_auto_config(struct hda_codec *codec)
9321 struct alc_spec *spec = codec->spec;
9322 int err = alc880_parse_auto_config(codec);
9323 struct auto_pin_cfg *cfg = &spec->autocfg;
9329 return 0; /* no config found */
9331 err = alc_auto_add_mic_boost(codec);
9335 /* hack - override the init verbs */
9336 spec->init_verbs[0] = alc883_auto_init_verbs;
9338 /* setup input_mux for ALC889 */
9339 if (codec->vendor_id == 0x10ec0889) {
9340 /* digital-mic input pin is excluded in alc880_auto_create..()
9341 * because it's under 0x18
9343 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9344 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9345 struct hda_input_mux *imux = &spec->private_imux[0];
9346 for (i = 1; i < 3; i++)
9347 memcpy(&spec->private_imux[i],
9348 &spec->private_imux[0],
9349 sizeof(spec->private_imux[0]));
9350 imux->items[imux->num_items].label = "Int DMic";
9351 imux->items[imux->num_items].index = 0x0b;
9353 spec->num_mux_defs = 3;
9354 spec->input_mux = spec->private_imux;
9358 return 1; /* config found */
9361 /* additional initialization for auto-configuration model */
9362 static void alc883_auto_init(struct hda_codec *codec)
9364 struct alc_spec *spec = codec->spec;
9365 alc883_auto_init_multi_out(codec);
9366 alc883_auto_init_hp_out(codec);
9367 alc883_auto_init_analog_input(codec);
9368 alc883_auto_init_input_src(codec);
9369 if (spec->unsol_event)
9370 alc_inithook(codec);
9373 static int patch_alc883(struct hda_codec *codec)
9375 struct alc_spec *spec;
9376 int err, board_config;
9378 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9384 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9386 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9389 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9390 /* Pick up systems that don't supply PCI SSID */
9391 switch (codec->subsystem_id) {
9392 case 0x106b3600: /* Macbook 3.1 */
9393 board_config = ALC889A_MB31;
9397 "hda_codec: Unknown model for %s, trying "
9398 "auto-probe from BIOS...\n", codec->chip_name);
9399 board_config = ALC883_AUTO;
9403 if (board_config == ALC883_AUTO) {
9404 /* automatic parse from the BIOS config */
9405 err = alc883_parse_auto_config(codec);
9411 "hda_codec: Cannot set up configuration "
9412 "from BIOS. Using base mode...\n");
9413 board_config = ALC883_3ST_2ch_DIG;
9417 err = snd_hda_attach_beep_device(codec, 0x1);
9423 if (board_config != ALC883_AUTO)
9424 setup_preset(spec, &alc883_presets[board_config]);
9426 switch (codec->vendor_id) {
9428 if (!spec->num_adc_nids) {
9429 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9430 spec->adc_nids = alc883_adc_nids;
9432 if (!spec->capsrc_nids)
9433 spec->capsrc_nids = alc883_capsrc_nids;
9434 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9435 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9438 if (!spec->num_adc_nids) {
9439 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9440 spec->adc_nids = alc889_adc_nids;
9442 if (!spec->capsrc_nids)
9443 spec->capsrc_nids = alc889_capsrc_nids;
9444 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9448 if (!spec->num_adc_nids) {
9449 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9450 spec->adc_nids = alc883_adc_nids;
9452 if (!spec->capsrc_nids)
9453 spec->capsrc_nids = alc883_capsrc_nids;
9454 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9458 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9459 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9460 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9462 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9463 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9465 if (!spec->cap_mixer)
9466 set_capture_mixer(spec);
9467 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9469 spec->vmaster_nid = 0x0c;
9471 codec->patch_ops = alc_patch_ops;
9472 if (board_config == ALC883_AUTO)
9473 spec->init_hook = alc883_auto_init;
9475 #ifdef CONFIG_SND_HDA_POWER_SAVE
9476 if (!spec->loopback.amplist)
9477 spec->loopback.amplist = alc883_loopbacks;
9479 codec->proc_widget_hook = print_realtek_coef;
9488 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9489 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9491 #define alc262_dac_nids alc260_dac_nids
9492 #define alc262_adc_nids alc882_adc_nids
9493 #define alc262_adc_nids_alt alc882_adc_nids_alt
9494 #define alc262_capsrc_nids alc882_capsrc_nids
9495 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9497 #define alc262_modes alc260_modes
9498 #define alc262_capture_source alc882_capture_source
9500 static hda_nid_t alc262_dmic_adc_nids[1] = {
9505 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9507 static struct snd_kcontrol_new alc262_base_mixer[] = {
9508 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9509 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9510 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9511 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9512 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9513 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9516 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9517 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9518 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9519 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9520 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9522 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9523 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9527 /* update HP, line and mono-out pins according to the master switch */
9528 static void alc262_hp_master_update(struct hda_codec *codec)
9530 struct alc_spec *spec = codec->spec;
9531 int val = spec->master_sw;
9534 snd_hda_codec_write_cache(codec, 0x1b, 0,
9535 AC_VERB_SET_PIN_WIDGET_CONTROL,
9537 snd_hda_codec_write_cache(codec, 0x15, 0,
9538 AC_VERB_SET_PIN_WIDGET_CONTROL,
9540 /* mono (speaker) depending on the HP jack sense */
9541 val = val && !spec->jack_present;
9542 snd_hda_codec_write_cache(codec, 0x16, 0,
9543 AC_VERB_SET_PIN_WIDGET_CONTROL,
9547 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9549 struct alc_spec *spec = codec->spec;
9550 unsigned int presence;
9551 presence = snd_hda_codec_read(codec, 0x1b, 0,
9552 AC_VERB_GET_PIN_SENSE, 0);
9553 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9554 alc262_hp_master_update(codec);
9557 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9559 if ((res >> 26) != ALC880_HP_EVENT)
9561 alc262_hp_bpc_automute(codec);
9564 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9566 struct alc_spec *spec = codec->spec;
9567 unsigned int presence;
9568 presence = snd_hda_codec_read(codec, 0x15, 0,
9569 AC_VERB_GET_PIN_SENSE, 0);
9570 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9571 alc262_hp_master_update(codec);
9574 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9577 if ((res >> 26) != ALC880_HP_EVENT)
9579 alc262_hp_wildwest_automute(codec);
9582 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9584 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9585 struct snd_ctl_elem_value *ucontrol)
9587 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9588 struct alc_spec *spec = codec->spec;
9589 int val = !!*ucontrol->value.integer.value;
9591 if (val == spec->master_sw)
9593 spec->master_sw = val;
9594 alc262_hp_master_update(codec);
9598 #define ALC262_HP_MASTER_SWITCH \
9600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9601 .name = "Master Playback Switch", \
9602 .info = snd_ctl_boolean_mono_info, \
9603 .get = alc262_hp_master_sw_get, \
9604 .put = alc262_hp_master_sw_put, \
9607 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9608 ALC262_HP_MASTER_SWITCH,
9609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9610 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9612 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9614 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9618 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9619 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9620 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9621 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9622 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9623 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9626 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9627 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9631 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9632 ALC262_HP_MASTER_SWITCH,
9633 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9634 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9637 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9639 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9643 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9646 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9647 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9651 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9652 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9653 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9654 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9658 /* mute/unmute internal speaker according to the hp jack and mute state */
9659 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9661 struct alc_spec *spec = codec->spec;
9663 spec->autocfg.hp_pins[0] = 0x15;
9664 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9665 alc_automute_amp(codec);
9668 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9670 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9671 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9675 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9679 static struct hda_verb alc262_hp_t5735_verbs[] = {
9680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9681 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9683 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9687 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9688 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9690 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9691 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9692 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9693 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9697 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9698 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9700 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9701 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9702 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9703 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9704 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9706 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9711 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9718 /* bind hp and internal speaker mute (with plug check) as master switch */
9719 static void alc262_hippo_master_update(struct hda_codec *codec)
9721 struct alc_spec *spec = codec->spec;
9722 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9723 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9724 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9728 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9729 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9730 HDA_AMP_MUTE, mute);
9731 /* mute internal speaker per jack sense */
9732 if (spec->jack_present)
9733 mute = HDA_AMP_MUTE;
9735 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9736 HDA_AMP_MUTE, mute);
9737 if (speaker_nid && speaker_nid != line_nid)
9738 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9739 HDA_AMP_MUTE, mute);
9742 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9744 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9745 struct snd_ctl_elem_value *ucontrol)
9747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9748 struct alc_spec *spec = codec->spec;
9749 int val = !!*ucontrol->value.integer.value;
9751 if (val == spec->master_sw)
9753 spec->master_sw = val;
9754 alc262_hippo_master_update(codec);
9758 #define ALC262_HIPPO_MASTER_SWITCH \
9760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9761 .name = "Master Playback Switch", \
9762 .info = snd_ctl_boolean_mono_info, \
9763 .get = alc262_hippo_master_sw_get, \
9764 .put = alc262_hippo_master_sw_put, \
9767 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9768 ALC262_HIPPO_MASTER_SWITCH,
9769 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9770 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9771 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9772 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9773 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9774 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9775 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9776 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9777 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9778 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9779 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9780 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9784 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9785 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9786 ALC262_HIPPO_MASTER_SWITCH,
9787 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9788 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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 /* mute/unmute internal speaker according to the hp jack and mute state */
9801 static void alc262_hippo_automute(struct hda_codec *codec)
9803 struct alc_spec *spec = codec->spec;
9804 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9805 unsigned int present;
9807 /* need to execute and sync at first */
9808 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9809 present = snd_hda_codec_read(codec, hp_nid, 0,
9810 AC_VERB_GET_PIN_SENSE, 0);
9811 spec->jack_present = (present & 0x80000000) != 0;
9812 alc262_hippo_master_update(codec);
9815 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9817 if ((res >> 26) != ALC880_HP_EVENT)
9819 alc262_hippo_automute(codec);
9822 static void alc262_hippo_init_hook(struct hda_codec *codec)
9824 struct alc_spec *spec = codec->spec;
9826 spec->autocfg.hp_pins[0] = 0x15;
9827 spec->autocfg.speaker_pins[0] = 0x14;
9828 alc262_hippo_automute(codec);
9831 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9833 struct alc_spec *spec = codec->spec;
9835 spec->autocfg.hp_pins[0] = 0x1b;
9836 spec->autocfg.speaker_pins[0] = 0x14;
9837 alc262_hippo_automute(codec);
9841 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9842 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9843 ALC262_HIPPO_MASTER_SWITCH,
9844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9846 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9847 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9851 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9852 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9853 ALC262_HIPPO_MASTER_SWITCH,
9854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9857 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9858 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9862 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9863 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9864 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9865 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9866 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9867 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9868 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9871 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9872 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9873 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9874 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9878 static struct hda_verb alc262_tyan_verbs[] = {
9879 /* Headphone automute */
9880 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9881 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9882 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9884 /* P11 AUX_IN, white 4-pin connector */
9885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9886 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9887 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9888 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9893 /* unsolicited event for HP jack sensing */
9894 static void alc262_tyan_init_hook(struct hda_codec *codec)
9896 struct alc_spec *spec = codec->spec;
9898 spec->autocfg.hp_pins[0] = 0x1b;
9899 spec->autocfg.speaker_pins[0] = 0x15;
9900 alc_automute_amp(codec);
9904 #define alc262_capture_mixer alc882_capture_mixer
9905 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9908 * generic initialization of ADC, input mixers and output mixers
9910 static struct hda_verb alc262_init_verbs[] = {
9912 * Unmute ADC0-2 and set the default input to mic-in
9914 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9916 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9918 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9921 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9923 * Note: PASD motherboards uses the Line In 2 as the input for
9924 * front panel mic (mic 2)
9926 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9934 * Set up output mixers (0x0c - 0x0e)
9936 /* set vol=0 to output mixers */
9937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9938 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9939 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9940 /* set up input amps for analog loopback */
9941 /* Amp Indices: DAC = 0, mixer = 1 */
9942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9944 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9945 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9946 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9947 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9949 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9950 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9952 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9954 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9958 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9959 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9960 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9962 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9963 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9965 /* FIXME: use matrix-type input source selection */
9966 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9967 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9973 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9974 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9975 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9976 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9980 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9986 static struct hda_verb alc262_eapd_verbs[] = {
9987 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9988 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9992 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9993 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9998 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9999 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10000 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10001 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10003 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10004 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10008 static struct hda_verb alc262_sony_unsol_verbs[] = {
10009 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10010 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10013 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10014 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10018 static struct hda_input_mux alc262_dmic_capture_source = {
10021 { "Int DMic", 0x9 },
10026 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10027 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10028 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10030 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10035 static struct hda_verb alc262_toshiba_s06_verbs[] = {
10036 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10039 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10040 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10041 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10043 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10047 static void alc262_dmic_automute(struct hda_codec *codec)
10049 unsigned int present;
10051 present = snd_hda_codec_read(codec, 0x18, 0,
10052 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10053 snd_hda_codec_write(codec, 0x22, 0,
10054 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10058 /* unsolicited event for HP jack sensing */
10059 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10062 if ((res >> 26) == ALC880_MIC_EVENT)
10063 alc262_dmic_automute(codec);
10065 alc_sku_unsol_event(codec, res);
10068 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10070 struct alc_spec *spec = codec->spec;
10072 spec->autocfg.hp_pins[0] = 0x15;
10073 spec->autocfg.speaker_pins[0] = 0x14;
10074 alc_automute_pin(codec);
10075 alc262_dmic_automute(codec);
10081 * 0x16 = internal speaker
10082 * 0x18 = external mic
10085 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10086 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10087 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10091 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10093 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10094 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10098 static struct hda_verb alc262_nec_verbs[] = {
10099 /* Unmute Speaker */
10100 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10103 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10104 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10106 /* External mic to headphone */
10107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10108 /* External mic to speaker */
10109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10115 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10116 * 0x1b = port replicator headphone out
10119 #define ALC_HP_EVENT 0x37
10121 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10122 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10123 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10124 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10125 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10129 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10130 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10131 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10135 static struct hda_input_mux alc262_fujitsu_capture_source = {
10139 { "Int Mic", 0x1 },
10144 static struct hda_input_mux alc262_HP_capture_source = {
10148 { "Front Mic", 0x1 },
10155 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10159 { "Front Mic", 0x2 },
10165 /* mute/unmute internal speaker according to the hp jacks and mute state */
10166 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10168 struct alc_spec *spec = codec->spec;
10171 if (force || !spec->sense_updated) {
10172 unsigned int present;
10173 /* need to execute and sync at first */
10174 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10175 /* check laptop HP jack */
10176 present = snd_hda_codec_read(codec, 0x14, 0,
10177 AC_VERB_GET_PIN_SENSE, 0);
10178 /* need to execute and sync at first */
10179 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10180 /* check docking HP jack */
10181 present |= snd_hda_codec_read(codec, 0x1b, 0,
10182 AC_VERB_GET_PIN_SENSE, 0);
10183 if (present & AC_PINSENSE_PRESENCE)
10184 spec->jack_present = 1;
10186 spec->jack_present = 0;
10187 spec->sense_updated = 1;
10189 /* unmute internal speaker only if both HPs are unplugged and
10190 * master switch is on
10192 if (spec->jack_present)
10193 mute = HDA_AMP_MUTE;
10195 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10196 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10197 HDA_AMP_MUTE, mute);
10200 /* unsolicited event for HP jack sensing */
10201 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10204 if ((res >> 26) != ALC_HP_EVENT)
10206 alc262_fujitsu_automute(codec, 1);
10209 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10211 alc262_fujitsu_automute(codec, 1);
10214 /* bind volumes of both NID 0x0c and 0x0d */
10215 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10216 .ops = &snd_hda_bind_vol,
10218 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10219 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10224 /* mute/unmute internal speaker according to the hp jack and mute state */
10225 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10227 struct alc_spec *spec = codec->spec;
10230 if (force || !spec->sense_updated) {
10231 unsigned int present_int_hp;
10232 /* need to execute and sync at first */
10233 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10234 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10235 AC_VERB_GET_PIN_SENSE, 0);
10236 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10237 spec->sense_updated = 1;
10239 if (spec->jack_present) {
10240 /* mute internal speaker */
10241 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10242 HDA_AMP_MUTE, HDA_AMP_MUTE);
10243 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10244 HDA_AMP_MUTE, HDA_AMP_MUTE);
10246 /* unmute internal speaker if necessary */
10247 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10248 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10249 HDA_AMP_MUTE, mute);
10250 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10251 HDA_AMP_MUTE, mute);
10255 /* unsolicited event for HP jack sensing */
10256 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10259 if ((res >> 26) != ALC_HP_EVENT)
10261 alc262_lenovo_3000_automute(codec, 1);
10264 /* bind hp and internal speaker mute (with plug check) */
10265 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10266 struct snd_ctl_elem_value *ucontrol)
10268 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10269 long *valp = ucontrol->value.integer.value;
10272 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10274 valp ? 0 : HDA_AMP_MUTE);
10275 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10277 valp ? 0 : HDA_AMP_MUTE);
10280 alc262_fujitsu_automute(codec, 0);
10284 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10285 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10288 .name = "Master Playback Switch",
10289 .info = snd_hda_mixer_amp_switch_info,
10290 .get = snd_hda_mixer_amp_switch_get,
10291 .put = alc262_fujitsu_master_sw_put,
10292 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10294 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10295 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10296 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10298 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10299 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10300 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10301 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10305 /* bind hp and internal speaker mute (with plug check) */
10306 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10307 struct snd_ctl_elem_value *ucontrol)
10309 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10310 long *valp = ucontrol->value.integer.value;
10313 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10315 valp ? 0 : HDA_AMP_MUTE);
10318 alc262_lenovo_3000_automute(codec, 0);
10322 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10323 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10326 .name = "Master Playback Switch",
10327 .info = snd_hda_mixer_amp_switch_info,
10328 .get = snd_hda_mixer_amp_switch_get,
10329 .put = alc262_lenovo_3000_master_sw_put,
10330 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10332 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10333 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10334 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10337 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10338 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10339 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10343 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10344 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10345 ALC262_HIPPO_MASTER_SWITCH,
10346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10348 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10349 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10350 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10351 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10355 /* additional init verbs for Benq laptops */
10356 static struct hda_verb alc262_EAPD_verbs[] = {
10357 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10358 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10362 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10363 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10364 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10366 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10367 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10371 /* Samsung Q1 Ultra Vista model setup */
10372 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10373 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10374 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10377 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10378 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10382 static struct hda_verb alc262_ultra_verbs[] = {
10384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10388 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10391 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10396 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10397 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10399 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10401 /* ADC, choose mic */
10402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10407 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10411 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10415 /* mute/unmute internal speaker according to the hp jack and mute state */
10416 static void alc262_ultra_automute(struct hda_codec *codec)
10418 struct alc_spec *spec = codec->spec;
10422 /* auto-mute only when HP is used as HP */
10423 if (!spec->cur_mux[0]) {
10424 unsigned int present;
10425 /* need to execute and sync at first */
10426 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10427 present = snd_hda_codec_read(codec, 0x15, 0,
10428 AC_VERB_GET_PIN_SENSE, 0);
10429 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10430 if (spec->jack_present)
10431 mute = HDA_AMP_MUTE;
10433 /* mute/unmute internal speaker */
10434 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10435 HDA_AMP_MUTE, mute);
10436 /* mute/unmute HP */
10437 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10438 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10441 /* unsolicited event for HP jack sensing */
10442 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10445 if ((res >> 26) != ALC880_HP_EVENT)
10447 alc262_ultra_automute(codec);
10450 static struct hda_input_mux alc262_ultra_capture_source = {
10454 { "Headphone", 0x7 },
10458 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10459 struct snd_ctl_elem_value *ucontrol)
10461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10462 struct alc_spec *spec = codec->spec;
10465 ret = alc_mux_enum_put(kcontrol, ucontrol);
10468 /* reprogram the HP pin as mic or HP according to the input source */
10469 snd_hda_codec_write_cache(codec, 0x15, 0,
10470 AC_VERB_SET_PIN_WIDGET_CONTROL,
10471 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10472 alc262_ultra_automute(codec); /* mute/unmute HP */
10476 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10477 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10478 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10481 .name = "Capture Source",
10482 .info = alc_mux_enum_info,
10483 .get = alc_mux_enum_get,
10484 .put = alc262_ultra_mux_enum_put,
10489 /* add playback controls from the parsed DAC table */
10490 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10491 const struct auto_pin_cfg *cfg)
10496 spec->multiout.num_dacs = 1; /* only use one dac */
10497 spec->multiout.dac_nids = spec->private_dac_nids;
10498 spec->multiout.dac_nids[0] = 2;
10500 nid = cfg->line_out_pins[0];
10502 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10503 "Front Playback Volume",
10504 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10507 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10508 "Front Playback Switch",
10509 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10514 nid = cfg->speaker_pins[0];
10517 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10518 "Speaker Playback Volume",
10519 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10523 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10524 "Speaker Playback Switch",
10525 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10530 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10531 "Speaker Playback Switch",
10532 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10538 nid = cfg->hp_pins[0];
10540 /* spec->multiout.hp_nid = 2; */
10542 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10543 "Headphone Playback Volume",
10544 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10548 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10549 "Headphone Playback Switch",
10550 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10555 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10556 "Headphone Playback Switch",
10557 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10566 /* identical with ALC880 */
10567 #define alc262_auto_create_analog_input_ctls \
10568 alc880_auto_create_analog_input_ctls
10571 * generic initialization of ADC, input mixers and output mixers
10573 static struct hda_verb alc262_volume_init_verbs[] = {
10575 * Unmute ADC0-2 and set the default input to mic-in
10577 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10579 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10581 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10584 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10586 * Note: PASD motherboards uses the Line In 2 as the input for
10587 * front panel mic (mic 2)
10589 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10590 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10591 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10592 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10593 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10594 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10597 * Set up output mixers (0x0c - 0x0f)
10599 /* set vol=0 to output mixers */
10600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10601 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10604 /* set up input amps for analog loopback */
10605 /* Amp Indices: DAC = 0, mixer = 1 */
10606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10610 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10613 /* FIXME: use matrix-type input source selection */
10614 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10615 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10616 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10617 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10618 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10619 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10621 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10622 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10623 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10624 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10627 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10634 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10636 * Unmute ADC0-2 and set the default input to mic-in
10638 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10639 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10640 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10642 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10643 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10645 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10647 * Note: PASD motherboards uses the Line In 2 as the input for
10648 * front panel mic (mic 2)
10650 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10651 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10652 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10653 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10654 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10655 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10656 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10657 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10660 * Set up output mixers (0x0c - 0x0e)
10662 /* set vol=0 to output mixers */
10663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10665 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10667 /* set up input amps for analog loopback */
10668 /* Amp Indices: DAC = 0, mixer = 1 */
10669 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10670 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10671 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10672 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10673 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10674 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10676 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10677 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10678 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10680 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10683 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10686 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10687 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10688 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10689 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10690 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10695 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10696 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10697 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10700 /* FIXME: use matrix-type input source selection */
10701 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10702 /* Input mixer1: only unmute Mic */
10703 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10704 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10709 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10710 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10711 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10713 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10714 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10715 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10716 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10717 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10718 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10733 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10738 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10740 * Unmute ADC0-2 and set the default input to mic-in
10742 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10744 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10745 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10746 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10747 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10749 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10751 * Note: PASD motherboards uses the Line In 2 as the input for front
10752 * panel mic (mic 2)
10754 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10755 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10756 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10757 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10758 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10760 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10761 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10762 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10764 * Set up output mixers (0x0c - 0x0e)
10766 /* set vol=0 to output mixers */
10767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10768 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10769 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10771 /* set up input amps for analog loopback */
10772 /* Amp Indices: DAC = 0, mixer = 1 */
10773 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10775 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10782 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10783 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10784 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10790 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10792 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10795 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10796 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10799 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10800 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10802 /* FIXME: use matrix-type input source selection */
10803 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10804 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10810 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10815 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10816 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10817 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10818 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10819 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10821 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10826 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10829 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10834 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10836 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10837 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10838 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10840 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10842 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10843 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10846 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10847 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10852 #ifdef CONFIG_SND_HDA_POWER_SAVE
10853 #define alc262_loopbacks alc880_loopbacks
10856 /* pcm configuration: identiacal with ALC880 */
10857 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10858 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10859 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10860 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10863 * BIOS auto configuration
10865 static int alc262_parse_auto_config(struct hda_codec *codec)
10867 struct alc_spec *spec = codec->spec;
10869 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10871 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10875 if (!spec->autocfg.line_outs) {
10876 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10877 spec->multiout.max_channels = 2;
10878 spec->no_analog = 1;
10881 return 0; /* can't find valid BIOS pin config */
10883 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10886 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10890 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10893 if (spec->autocfg.dig_outs) {
10894 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10895 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10897 if (spec->autocfg.dig_in_pin)
10898 spec->dig_in_nid = ALC262_DIGIN_NID;
10900 if (spec->kctls.list)
10901 add_mixer(spec, spec->kctls.list);
10903 add_verb(spec, alc262_volume_init_verbs);
10904 spec->num_mux_defs = 1;
10905 spec->input_mux = &spec->private_imux[0];
10907 err = alc_auto_add_mic_boost(codec);
10911 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10916 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10917 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10918 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10919 #define alc262_auto_init_input_src alc882_auto_init_input_src
10922 /* init callback for auto-configuration model -- overriding the default init */
10923 static void alc262_auto_init(struct hda_codec *codec)
10925 struct alc_spec *spec = codec->spec;
10926 alc262_auto_init_multi_out(codec);
10927 alc262_auto_init_hp_out(codec);
10928 alc262_auto_init_analog_input(codec);
10929 alc262_auto_init_input_src(codec);
10930 if (spec->unsol_event)
10931 alc_inithook(codec);
10935 * configuration and preset
10937 static const char *alc262_models[ALC262_MODEL_LAST] = {
10938 [ALC262_BASIC] = "basic",
10939 [ALC262_HIPPO] = "hippo",
10940 [ALC262_HIPPO_1] = "hippo_1",
10941 [ALC262_FUJITSU] = "fujitsu",
10942 [ALC262_HP_BPC] = "hp-bpc",
10943 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10944 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10945 [ALC262_HP_RP5700] = "hp-rp5700",
10946 [ALC262_BENQ_ED8] = "benq",
10947 [ALC262_BENQ_T31] = "benq-t31",
10948 [ALC262_SONY_ASSAMD] = "sony-assamd",
10949 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10950 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10951 [ALC262_ULTRA] = "ultra",
10952 [ALC262_LENOVO_3000] = "lenovo-3000",
10953 [ALC262_NEC] = "nec",
10954 [ALC262_TYAN] = "tyan",
10955 [ALC262_AUTO] = "auto",
10958 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10959 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10960 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10961 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10963 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10965 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10967 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10968 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10969 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10970 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10971 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10972 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10973 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10974 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10975 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10976 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10977 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10978 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10979 ALC262_HP_TC_T5735),
10980 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10981 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10982 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10983 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10984 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10985 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10986 ALC262_SONY_ASSAMD),
10987 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10988 ALC262_TOSHIBA_RX1),
10989 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10990 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10991 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10992 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10993 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10995 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10996 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10997 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10998 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10999 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11003 static struct alc_config_preset alc262_presets[] = {
11005 .mixers = { alc262_base_mixer },
11006 .init_verbs = { alc262_init_verbs },
11007 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11008 .dac_nids = alc262_dac_nids,
11010 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11011 .channel_mode = alc262_modes,
11012 .input_mux = &alc262_capture_source,
11015 .mixers = { alc262_hippo_mixer },
11016 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
11017 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11018 .dac_nids = alc262_dac_nids,
11020 .dig_out_nid = ALC262_DIGOUT_NID,
11021 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11022 .channel_mode = alc262_modes,
11023 .input_mux = &alc262_capture_source,
11024 .unsol_event = alc262_hippo_unsol_event,
11025 .init_hook = alc262_hippo_init_hook,
11027 [ALC262_HIPPO_1] = {
11028 .mixers = { alc262_hippo1_mixer },
11029 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11030 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11031 .dac_nids = alc262_dac_nids,
11033 .dig_out_nid = ALC262_DIGOUT_NID,
11034 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11035 .channel_mode = alc262_modes,
11036 .input_mux = &alc262_capture_source,
11037 .unsol_event = alc262_hippo_unsol_event,
11038 .init_hook = alc262_hippo1_init_hook,
11040 [ALC262_FUJITSU] = {
11041 .mixers = { alc262_fujitsu_mixer },
11042 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11043 alc262_fujitsu_unsol_verbs },
11044 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11045 .dac_nids = alc262_dac_nids,
11047 .dig_out_nid = ALC262_DIGOUT_NID,
11048 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11049 .channel_mode = alc262_modes,
11050 .input_mux = &alc262_fujitsu_capture_source,
11051 .unsol_event = alc262_fujitsu_unsol_event,
11052 .init_hook = alc262_fujitsu_init_hook,
11054 [ALC262_HP_BPC] = {
11055 .mixers = { alc262_HP_BPC_mixer },
11056 .init_verbs = { alc262_HP_BPC_init_verbs },
11057 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11058 .dac_nids = alc262_dac_nids,
11060 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11061 .channel_mode = alc262_modes,
11062 .input_mux = &alc262_HP_capture_source,
11063 .unsol_event = alc262_hp_bpc_unsol_event,
11064 .init_hook = alc262_hp_bpc_automute,
11066 [ALC262_HP_BPC_D7000_WF] = {
11067 .mixers = { alc262_HP_BPC_WildWest_mixer },
11068 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11069 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11070 .dac_nids = alc262_dac_nids,
11072 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11073 .channel_mode = alc262_modes,
11074 .input_mux = &alc262_HP_D7000_capture_source,
11075 .unsol_event = alc262_hp_wildwest_unsol_event,
11076 .init_hook = alc262_hp_wildwest_automute,
11078 [ALC262_HP_BPC_D7000_WL] = {
11079 .mixers = { alc262_HP_BPC_WildWest_mixer,
11080 alc262_HP_BPC_WildWest_option_mixer },
11081 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11082 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11083 .dac_nids = alc262_dac_nids,
11085 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11086 .channel_mode = alc262_modes,
11087 .input_mux = &alc262_HP_D7000_capture_source,
11088 .unsol_event = alc262_hp_wildwest_unsol_event,
11089 .init_hook = alc262_hp_wildwest_automute,
11091 [ALC262_HP_TC_T5735] = {
11092 .mixers = { alc262_hp_t5735_mixer },
11093 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11094 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11095 .dac_nids = alc262_dac_nids,
11097 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11098 .channel_mode = alc262_modes,
11099 .input_mux = &alc262_capture_source,
11100 .unsol_event = alc_automute_amp_unsol_event,
11101 .init_hook = alc262_hp_t5735_init_hook,
11103 [ALC262_HP_RP5700] = {
11104 .mixers = { alc262_hp_rp5700_mixer },
11105 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11106 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11107 .dac_nids = alc262_dac_nids,
11108 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11109 .channel_mode = alc262_modes,
11110 .input_mux = &alc262_hp_rp5700_capture_source,
11112 [ALC262_BENQ_ED8] = {
11113 .mixers = { alc262_base_mixer },
11114 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11115 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11116 .dac_nids = alc262_dac_nids,
11118 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11119 .channel_mode = alc262_modes,
11120 .input_mux = &alc262_capture_source,
11122 [ALC262_SONY_ASSAMD] = {
11123 .mixers = { alc262_sony_mixer },
11124 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11125 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11126 .dac_nids = alc262_dac_nids,
11128 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11129 .channel_mode = alc262_modes,
11130 .input_mux = &alc262_capture_source,
11131 .unsol_event = alc262_hippo_unsol_event,
11132 .init_hook = alc262_hippo_init_hook,
11134 [ALC262_BENQ_T31] = {
11135 .mixers = { alc262_benq_t31_mixer },
11136 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11137 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11138 .dac_nids = alc262_dac_nids,
11140 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11141 .channel_mode = alc262_modes,
11142 .input_mux = &alc262_capture_source,
11143 .unsol_event = alc262_hippo_unsol_event,
11144 .init_hook = alc262_hippo_init_hook,
11147 .mixers = { alc262_ultra_mixer },
11148 .cap_mixer = alc262_ultra_capture_mixer,
11149 .init_verbs = { alc262_ultra_verbs },
11150 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11151 .dac_nids = alc262_dac_nids,
11152 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11153 .channel_mode = alc262_modes,
11154 .input_mux = &alc262_ultra_capture_source,
11155 .adc_nids = alc262_adc_nids, /* ADC0 */
11156 .capsrc_nids = alc262_capsrc_nids,
11157 .num_adc_nids = 1, /* single ADC */
11158 .unsol_event = alc262_ultra_unsol_event,
11159 .init_hook = alc262_ultra_automute,
11161 [ALC262_LENOVO_3000] = {
11162 .mixers = { alc262_lenovo_3000_mixer },
11163 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11164 alc262_lenovo_3000_unsol_verbs },
11165 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11166 .dac_nids = alc262_dac_nids,
11168 .dig_out_nid = ALC262_DIGOUT_NID,
11169 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11170 .channel_mode = alc262_modes,
11171 .input_mux = &alc262_fujitsu_capture_source,
11172 .unsol_event = alc262_lenovo_3000_unsol_event,
11175 .mixers = { alc262_nec_mixer },
11176 .init_verbs = { alc262_nec_verbs },
11177 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11178 .dac_nids = alc262_dac_nids,
11180 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11181 .channel_mode = alc262_modes,
11182 .input_mux = &alc262_capture_source,
11184 [ALC262_TOSHIBA_S06] = {
11185 .mixers = { alc262_toshiba_s06_mixer },
11186 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11187 alc262_eapd_verbs },
11188 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11189 .capsrc_nids = alc262_dmic_capsrc_nids,
11190 .dac_nids = alc262_dac_nids,
11191 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11192 .dig_out_nid = ALC262_DIGOUT_NID,
11193 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11194 .channel_mode = alc262_modes,
11195 .input_mux = &alc262_dmic_capture_source,
11196 .unsol_event = alc262_toshiba_s06_unsol_event,
11197 .init_hook = alc262_toshiba_s06_init_hook,
11199 [ALC262_TOSHIBA_RX1] = {
11200 .mixers = { alc262_toshiba_rx1_mixer },
11201 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11202 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11203 .dac_nids = alc262_dac_nids,
11205 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11206 .channel_mode = alc262_modes,
11207 .input_mux = &alc262_capture_source,
11208 .unsol_event = alc262_hippo_unsol_event,
11209 .init_hook = alc262_hippo_init_hook,
11212 .mixers = { alc262_tyan_mixer },
11213 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11214 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11215 .dac_nids = alc262_dac_nids,
11217 .dig_out_nid = ALC262_DIGOUT_NID,
11218 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11219 .channel_mode = alc262_modes,
11220 .input_mux = &alc262_capture_source,
11221 .unsol_event = alc_automute_amp_unsol_event,
11222 .init_hook = alc262_tyan_init_hook,
11226 static int patch_alc262(struct hda_codec *codec)
11228 struct alc_spec *spec;
11232 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11236 codec->spec = spec;
11238 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11243 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11244 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11245 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11246 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11250 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11252 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11256 if (board_config < 0) {
11257 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11258 "trying auto-probe from BIOS...\n", codec->chip_name);
11259 board_config = ALC262_AUTO;
11262 if (board_config == ALC262_AUTO) {
11263 /* automatic parse from the BIOS config */
11264 err = alc262_parse_auto_config(codec);
11270 "hda_codec: Cannot set up configuration "
11271 "from BIOS. Using base mode...\n");
11272 board_config = ALC262_BASIC;
11276 if (!spec->no_analog) {
11277 err = snd_hda_attach_beep_device(codec, 0x1);
11284 if (board_config != ALC262_AUTO)
11285 setup_preset(spec, &alc262_presets[board_config]);
11287 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11288 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11290 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11291 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11293 spec->capture_style = CAPT_MIX;
11294 if (!spec->adc_nids && spec->input_mux) {
11295 /* check whether NID 0x07 is valid */
11296 unsigned int wcap = get_wcaps(codec, 0x07);
11299 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11300 if (wcap != AC_WID_AUD_IN) {
11301 spec->adc_nids = alc262_adc_nids_alt;
11302 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11303 spec->capsrc_nids = alc262_capsrc_nids_alt;
11305 spec->adc_nids = alc262_adc_nids;
11306 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11307 spec->capsrc_nids = alc262_capsrc_nids;
11310 if (!spec->cap_mixer && !spec->no_analog)
11311 set_capture_mixer(spec);
11312 if (!spec->no_analog)
11313 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11315 spec->vmaster_nid = 0x0c;
11317 codec->patch_ops = alc_patch_ops;
11318 if (board_config == ALC262_AUTO)
11319 spec->init_hook = alc262_auto_init;
11320 #ifdef CONFIG_SND_HDA_POWER_SAVE
11321 if (!spec->loopback.amplist)
11322 spec->loopback.amplist = alc262_loopbacks;
11324 codec->proc_widget_hook = print_realtek_coef;
11330 * ALC268 channel source setting (2 channel)
11332 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11333 #define alc268_modes alc260_modes
11335 static hda_nid_t alc268_dac_nids[2] = {
11340 static hda_nid_t alc268_adc_nids[2] = {
11345 static hda_nid_t alc268_adc_nids_alt[1] = {
11350 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11352 static struct snd_kcontrol_new alc268_base_mixer[] = {
11353 /* output mixer control */
11354 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11355 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11356 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11357 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11358 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11359 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11360 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11364 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11365 /* output mixer control */
11366 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11367 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11368 ALC262_HIPPO_MASTER_SWITCH,
11369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11371 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11375 /* bind Beep switches of both NID 0x0f and 0x10 */
11376 static struct hda_bind_ctls alc268_bind_beep_sw = {
11377 .ops = &snd_hda_bind_sw,
11379 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11380 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11385 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11386 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11387 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11391 static struct hda_verb alc268_eapd_verbs[] = {
11392 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11393 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11397 /* Toshiba specific */
11398 static struct hda_verb alc268_toshiba_verbs[] = {
11399 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11403 static struct hda_input_mux alc268_acer_lc_capture_source = {
11411 /* Acer specific */
11412 /* bind volumes of both NID 0x02 and 0x03 */
11413 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11414 .ops = &snd_hda_bind_vol,
11416 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11417 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11422 /* mute/unmute internal speaker according to the hp jack and mute state */
11423 static void alc268_acer_automute(struct hda_codec *codec, int force)
11425 struct alc_spec *spec = codec->spec;
11428 if (force || !spec->sense_updated) {
11429 unsigned int present;
11430 present = snd_hda_codec_read(codec, 0x14, 0,
11431 AC_VERB_GET_PIN_SENSE, 0);
11432 spec->jack_present = (present & 0x80000000) != 0;
11433 spec->sense_updated = 1;
11435 if (spec->jack_present)
11436 mute = HDA_AMP_MUTE; /* mute internal speaker */
11437 else /* unmute internal speaker if necessary */
11438 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11439 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11440 HDA_AMP_MUTE, mute);
11444 /* bind hp and internal speaker mute (with plug check) */
11445 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11446 struct snd_ctl_elem_value *ucontrol)
11448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11449 long *valp = ucontrol->value.integer.value;
11452 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11454 valp[0] ? 0 : HDA_AMP_MUTE);
11455 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11457 valp[1] ? 0 : HDA_AMP_MUTE);
11459 alc268_acer_automute(codec, 0);
11463 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11464 /* output mixer control */
11465 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11467 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11468 .name = "Master Playback Switch",
11469 .info = snd_hda_mixer_amp_switch_info,
11470 .get = snd_hda_mixer_amp_switch_get,
11471 .put = alc268_acer_master_sw_put,
11472 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11474 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11478 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11479 /* output mixer control */
11480 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11483 .name = "Master Playback Switch",
11484 .info = snd_hda_mixer_amp_switch_info,
11485 .get = snd_hda_mixer_amp_switch_get,
11486 .put = alc268_acer_master_sw_put,
11487 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11489 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11490 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11491 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11495 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11496 /* output mixer control */
11497 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11499 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11500 .name = "Master Playback Switch",
11501 .info = snd_hda_mixer_amp_switch_info,
11502 .get = snd_hda_mixer_amp_switch_get,
11503 .put = alc268_acer_master_sw_put,
11504 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11506 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11507 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11511 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11512 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11514 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11515 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11516 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11521 static struct hda_verb alc268_acer_verbs[] = {
11522 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11523 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11525 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11527 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11528 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11532 /* unsolicited event for HP jack sensing */
11533 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11534 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11536 static void alc268_acer_unsol_event(struct hda_codec *codec,
11539 if ((res >> 26) != ALC880_HP_EVENT)
11541 alc268_acer_automute(codec, 1);
11544 static void alc268_acer_init_hook(struct hda_codec *codec)
11546 alc268_acer_automute(codec, 1);
11549 /* toggle speaker-output according to the hp-jack state */
11550 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11552 unsigned int present;
11553 unsigned char bits;
11555 present = snd_hda_codec_read(codec, 0x15, 0,
11556 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11557 bits = present ? AMP_IN_MUTE(0) : 0;
11558 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11559 AMP_IN_MUTE(0), bits);
11560 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11561 AMP_IN_MUTE(0), bits);
11565 static void alc268_acer_mic_automute(struct hda_codec *codec)
11567 unsigned int present;
11569 present = snd_hda_codec_read(codec, 0x18, 0,
11570 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11571 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11572 present ? 0x0 : 0x6);
11575 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11578 if ((res >> 26) == ALC880_HP_EVENT)
11579 alc268_aspire_one_speaker_automute(codec);
11580 if ((res >> 26) == ALC880_MIC_EVENT)
11581 alc268_acer_mic_automute(codec);
11584 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11586 alc268_aspire_one_speaker_automute(codec);
11587 alc268_acer_mic_automute(codec);
11590 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11591 /* output mixer control */
11592 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11593 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11594 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11597 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11601 static struct hda_verb alc268_dell_verbs[] = {
11602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11604 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11608 /* mute/unmute internal speaker according to the hp jack and mute state */
11609 static void alc268_dell_init_hook(struct hda_codec *codec)
11611 struct alc_spec *spec = codec->spec;
11613 spec->autocfg.hp_pins[0] = 0x15;
11614 spec->autocfg.speaker_pins[0] = 0x14;
11615 alc_automute_pin(codec);
11618 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11619 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11620 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11621 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11622 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11623 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11624 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11625 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11626 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11630 static struct hda_verb alc267_quanta_il1_verbs[] = {
11631 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11632 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11636 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11638 unsigned int present;
11640 present = snd_hda_codec_read(codec, 0x18, 0,
11641 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11642 snd_hda_codec_write(codec, 0x23, 0,
11643 AC_VERB_SET_CONNECT_SEL,
11644 present ? 0x00 : 0x01);
11647 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11649 struct alc_spec *spec = codec->spec;
11651 spec->autocfg.hp_pins[0] = 0x15;
11652 spec->autocfg.speaker_pins[0] = 0x14;
11653 alc_automute_pin(codec);
11654 alc267_quanta_il1_mic_automute(codec);
11657 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11660 switch (res >> 26) {
11661 case ALC880_MIC_EVENT:
11662 alc267_quanta_il1_mic_automute(codec);
11665 alc_sku_unsol_event(codec, res);
11671 * generic initialization of ADC, input mixers and output mixers
11673 static struct hda_verb alc268_base_init_verbs[] = {
11674 /* Unmute DAC0-1 and set vol = 0 */
11675 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11676 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11679 * Set up output mixers (0x0c - 0x0e)
11681 /* set vol=0 to output mixers */
11682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11683 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11686 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11690 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11692 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11694 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11695 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11698 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11703 /* set PCBEEP vol = 0, mute connections */
11704 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11706 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11708 /* Unmute Selector 23h,24h and set the default input to mic-in */
11710 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11711 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11712 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11713 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11719 * generic initialization of ADC, input mixers and output mixers
11721 static struct hda_verb alc268_volume_init_verbs[] = {
11722 /* set output DAC */
11723 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11724 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11726 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11727 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11728 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11729 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11730 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11733 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11734 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11736 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11739 /* set PCBEEP vol = 0, mute connections */
11740 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11741 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11742 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11747 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11748 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11749 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11752 /* The multiple "Capture Source" controls confuse alsamixer
11753 * So call somewhat different..
11755 /* .name = "Capture Source", */
11756 .name = "Input Source",
11758 .info = alc_mux_enum_info,
11759 .get = alc_mux_enum_get,
11760 .put = alc_mux_enum_put,
11765 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11766 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11767 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11768 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11769 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11772 /* The multiple "Capture Source" controls confuse alsamixer
11773 * So call somewhat different..
11775 /* .name = "Capture Source", */
11776 .name = "Input Source",
11778 .info = alc_mux_enum_info,
11779 .get = alc_mux_enum_get,
11780 .put = alc_mux_enum_put,
11785 static struct hda_input_mux alc268_capture_source = {
11789 { "Front Mic", 0x1 },
11795 static struct hda_input_mux alc268_acer_capture_source = {
11799 { "Internal Mic", 0x1 },
11804 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11808 { "Internal Mic", 0x6 },
11813 #ifdef CONFIG_SND_DEBUG
11814 static struct snd_kcontrol_new alc268_test_mixer[] = {
11815 /* Volume widgets */
11816 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11817 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11818 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11819 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11820 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11821 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11822 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11823 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11824 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11825 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11826 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11827 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11828 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11829 /* The below appears problematic on some hardwares */
11830 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11831 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11832 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11833 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11834 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11836 /* Modes for retasking pin widgets */
11837 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11838 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11839 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11840 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11842 /* Controls for GPIO pins, assuming they are configured as outputs */
11843 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11844 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11845 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11846 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11848 /* Switches to allow the digital SPDIF output pin to be enabled.
11849 * The ALC268 does not have an SPDIF input.
11851 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11853 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11854 * this output to turn on an external amplifier.
11856 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11857 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11863 /* create input playback/capture controls for the given pin */
11864 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11865 const char *ctlname, int idx)
11870 sprintf(name, "%s Playback Volume", ctlname);
11872 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11873 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11877 } else if (nid == 0x15) {
11878 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11879 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11885 sprintf(name, "%s Playback Switch", ctlname);
11886 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11887 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11893 /* add playback controls from the parsed DAC table */
11894 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11895 const struct auto_pin_cfg *cfg)
11900 spec->multiout.num_dacs = 2; /* only use one dac */
11901 spec->multiout.dac_nids = spec->private_dac_nids;
11902 spec->multiout.dac_nids[0] = 2;
11903 spec->multiout.dac_nids[1] = 3;
11905 nid = cfg->line_out_pins[0];
11907 alc268_new_analog_output(spec, nid, "Front", 0);
11909 nid = cfg->speaker_pins[0];
11911 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11912 "Speaker Playback Volume",
11913 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11917 nid = cfg->hp_pins[0];
11919 alc268_new_analog_output(spec, nid, "Headphone", 0);
11921 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11923 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11924 "Mono Playback Switch",
11925 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11932 /* create playback/capture controls for input pins */
11933 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11934 const struct auto_pin_cfg *cfg)
11936 struct hda_input_mux *imux = &spec->private_imux[0];
11939 for (i = 0; i < AUTO_PIN_LAST; i++) {
11940 switch(cfg->input_pins[i]) {
11942 idx1 = 0; /* Mic 1 */
11945 idx1 = 1; /* Mic 2 */
11948 idx1 = 2; /* Line In */
11955 idx1 = 6; /* digital mics */
11960 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11961 imux->items[imux->num_items].index = idx1;
11967 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11969 struct alc_spec *spec = codec->spec;
11970 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11971 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11972 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11973 unsigned int dac_vol1, dac_vol2;
11976 snd_hda_codec_write(codec, speaker_nid, 0,
11977 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11978 snd_hda_codec_write(codec, 0x0f, 0,
11979 AC_VERB_SET_AMP_GAIN_MUTE,
11981 snd_hda_codec_write(codec, 0x10, 0,
11982 AC_VERB_SET_AMP_GAIN_MUTE,
11985 snd_hda_codec_write(codec, 0x0f, 0,
11986 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11987 snd_hda_codec_write(codec, 0x10, 0,
11988 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11991 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11992 if (line_nid == 0x14)
11993 dac_vol2 = AMP_OUT_ZERO;
11994 else if (line_nid == 0x15)
11995 dac_vol1 = AMP_OUT_ZERO;
11996 if (hp_nid == 0x14)
11997 dac_vol2 = AMP_OUT_ZERO;
11998 else if (hp_nid == 0x15)
11999 dac_vol1 = AMP_OUT_ZERO;
12000 if (line_nid != 0x16 || hp_nid != 0x16 ||
12001 spec->autocfg.line_out_pins[1] != 0x16 ||
12002 spec->autocfg.line_out_pins[2] != 0x16)
12003 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12005 snd_hda_codec_write(codec, 0x02, 0,
12006 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12007 snd_hda_codec_write(codec, 0x03, 0,
12008 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12011 /* pcm configuration: identiacal with ALC880 */
12012 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12013 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12014 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12015 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12018 * BIOS auto configuration
12020 static int alc268_parse_auto_config(struct hda_codec *codec)
12022 struct alc_spec *spec = codec->spec;
12024 static hda_nid_t alc268_ignore[] = { 0 };
12026 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12030 if (!spec->autocfg.line_outs) {
12031 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12032 spec->multiout.max_channels = 2;
12033 spec->no_analog = 1;
12036 return 0; /* can't find valid BIOS pin config */
12038 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12041 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
12045 spec->multiout.max_channels = 2;
12048 /* digital only support output */
12049 if (spec->autocfg.dig_outs) {
12050 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12051 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12053 if (spec->kctls.list)
12054 add_mixer(spec, spec->kctls.list);
12056 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12057 add_mixer(spec, alc268_beep_mixer);
12059 add_verb(spec, alc268_volume_init_verbs);
12060 spec->num_mux_defs = 1;
12061 spec->input_mux = &spec->private_imux[0];
12063 err = alc_auto_add_mic_boost(codec);
12070 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12071 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12072 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12074 /* init callback for auto-configuration model -- overriding the default init */
12075 static void alc268_auto_init(struct hda_codec *codec)
12077 struct alc_spec *spec = codec->spec;
12078 alc268_auto_init_multi_out(codec);
12079 alc268_auto_init_hp_out(codec);
12080 alc268_auto_init_mono_speaker_out(codec);
12081 alc268_auto_init_analog_input(codec);
12082 if (spec->unsol_event)
12083 alc_inithook(codec);
12087 * configuration and preset
12089 static const char *alc268_models[ALC268_MODEL_LAST] = {
12090 [ALC267_QUANTA_IL1] = "quanta-il1",
12091 [ALC268_3ST] = "3stack",
12092 [ALC268_TOSHIBA] = "toshiba",
12093 [ALC268_ACER] = "acer",
12094 [ALC268_ACER_DMIC] = "acer-dmic",
12095 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12096 [ALC268_DELL] = "dell",
12097 [ALC268_ZEPTO] = "zepto",
12098 #ifdef CONFIG_SND_DEBUG
12099 [ALC268_TEST] = "test",
12101 [ALC268_AUTO] = "auto",
12104 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12105 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12106 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12107 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12108 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12109 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12110 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12111 ALC268_ACER_ASPIRE_ONE),
12112 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12113 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12114 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12115 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12116 SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA),
12117 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12118 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12119 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12120 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12121 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12122 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12123 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12124 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12128 static struct alc_config_preset alc268_presets[] = {
12129 [ALC267_QUANTA_IL1] = {
12130 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12131 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12132 alc267_quanta_il1_verbs },
12133 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12134 .dac_nids = alc268_dac_nids,
12135 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12136 .adc_nids = alc268_adc_nids_alt,
12138 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12139 .channel_mode = alc268_modes,
12140 .input_mux = &alc268_capture_source,
12141 .unsol_event = alc267_quanta_il1_unsol_event,
12142 .init_hook = alc267_quanta_il1_init_hook,
12145 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12146 alc268_beep_mixer },
12147 .init_verbs = { alc268_base_init_verbs },
12148 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12149 .dac_nids = alc268_dac_nids,
12150 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12151 .adc_nids = alc268_adc_nids_alt,
12152 .capsrc_nids = alc268_capsrc_nids,
12154 .dig_out_nid = ALC268_DIGOUT_NID,
12155 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12156 .channel_mode = alc268_modes,
12157 .input_mux = &alc268_capture_source,
12159 [ALC268_TOSHIBA] = {
12160 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12161 alc268_beep_mixer },
12162 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12163 alc268_toshiba_verbs },
12164 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12165 .dac_nids = alc268_dac_nids,
12166 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12167 .adc_nids = alc268_adc_nids_alt,
12168 .capsrc_nids = alc268_capsrc_nids,
12170 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12171 .channel_mode = alc268_modes,
12172 .input_mux = &alc268_capture_source,
12173 .unsol_event = alc268_toshiba_unsol_event,
12174 .init_hook = alc268_toshiba_init_hook,
12177 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12178 alc268_beep_mixer },
12179 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12180 alc268_acer_verbs },
12181 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12182 .dac_nids = alc268_dac_nids,
12183 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12184 .adc_nids = alc268_adc_nids_alt,
12185 .capsrc_nids = alc268_capsrc_nids,
12187 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12188 .channel_mode = alc268_modes,
12189 .input_mux = &alc268_acer_capture_source,
12190 .unsol_event = alc268_acer_unsol_event,
12191 .init_hook = alc268_acer_init_hook,
12193 [ALC268_ACER_DMIC] = {
12194 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12195 alc268_beep_mixer },
12196 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12197 alc268_acer_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_dmic_capture_source,
12207 .unsol_event = alc268_acer_unsol_event,
12208 .init_hook = alc268_acer_init_hook,
12210 [ALC268_ACER_ASPIRE_ONE] = {
12211 .mixers = { alc268_acer_aspire_one_mixer,
12213 alc268_capture_alt_mixer },
12214 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12215 alc268_acer_aspire_one_verbs },
12216 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12217 .dac_nids = alc268_dac_nids,
12218 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12219 .adc_nids = alc268_adc_nids_alt,
12220 .capsrc_nids = alc268_capsrc_nids,
12222 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12223 .channel_mode = alc268_modes,
12224 .input_mux = &alc268_acer_lc_capture_source,
12225 .unsol_event = alc268_acer_lc_unsol_event,
12226 .init_hook = alc268_acer_lc_init_hook,
12229 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12230 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12231 alc268_dell_verbs },
12232 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12233 .dac_nids = alc268_dac_nids,
12235 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12236 .channel_mode = alc268_modes,
12237 .unsol_event = alc_sku_unsol_event,
12238 .init_hook = alc268_dell_init_hook,
12239 .input_mux = &alc268_capture_source,
12242 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12243 alc268_beep_mixer },
12244 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12245 alc268_toshiba_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,
12256 .unsol_event = alc268_toshiba_unsol_event,
12257 .init_hook = alc268_toshiba_init_hook
12259 #ifdef CONFIG_SND_DEBUG
12261 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12262 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12263 alc268_volume_init_verbs },
12264 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12265 .dac_nids = alc268_dac_nids,
12266 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12267 .adc_nids = alc268_adc_nids_alt,
12268 .capsrc_nids = alc268_capsrc_nids,
12270 .dig_out_nid = ALC268_DIGOUT_NID,
12271 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12272 .channel_mode = alc268_modes,
12273 .input_mux = &alc268_capture_source,
12278 static int patch_alc268(struct hda_codec *codec)
12280 struct alc_spec *spec;
12282 int i, has_beep, err;
12284 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12288 codec->spec = spec;
12290 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12294 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12295 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12296 "trying auto-probe from BIOS...\n", codec->chip_name);
12297 board_config = ALC268_AUTO;
12300 if (board_config == ALC268_AUTO) {
12301 /* automatic parse from the BIOS config */
12302 err = alc268_parse_auto_config(codec);
12308 "hda_codec: Cannot set up configuration "
12309 "from BIOS. Using base mode...\n");
12310 board_config = ALC268_3ST;
12314 if (board_config != ALC268_AUTO)
12315 setup_preset(spec, &alc268_presets[board_config]);
12317 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12318 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12319 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12321 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12324 for (i = 0; i < spec->num_mixers; i++) {
12325 if (spec->mixers[i] == alc268_beep_mixer) {
12332 err = snd_hda_attach_beep_device(codec, 0x1);
12337 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12338 /* override the amp caps for beep generator */
12339 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12340 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12341 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12342 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12343 (0 << AC_AMPCAP_MUTE_SHIFT));
12346 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12347 /* check whether NID 0x07 is valid */
12348 unsigned int wcap = get_wcaps(codec, 0x07);
12352 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12353 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12354 spec->adc_nids = alc268_adc_nids_alt;
12355 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12356 add_mixer(spec, alc268_capture_alt_mixer);
12358 spec->adc_nids = alc268_adc_nids;
12359 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12360 add_mixer(spec, alc268_capture_mixer);
12362 spec->capsrc_nids = alc268_capsrc_nids;
12363 /* set default input source */
12364 for (i = 0; i < spec->num_adc_nids; i++)
12365 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12366 0, AC_VERB_SET_CONNECT_SEL,
12367 spec->input_mux->items[0].index);
12370 spec->vmaster_nid = 0x02;
12372 codec->patch_ops = alc_patch_ops;
12373 if (board_config == ALC268_AUTO)
12374 spec->init_hook = alc268_auto_init;
12376 codec->proc_widget_hook = print_realtek_coef;
12382 * ALC269 channel source setting (2 channel)
12384 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12386 #define alc269_dac_nids alc260_dac_nids
12388 static hda_nid_t alc269_adc_nids[1] = {
12393 static hda_nid_t alc269_capsrc_nids[1] = {
12397 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12401 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12409 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12417 #define alc269_modes alc260_modes
12418 #define alc269_capture_source alc880_lg_lw_capture_source
12420 static struct snd_kcontrol_new alc269_base_mixer[] = {
12421 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12422 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12428 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12429 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12430 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12431 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12432 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12436 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12437 /* output mixer control */
12438 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12441 .name = "Master Playback Switch",
12442 .info = snd_hda_mixer_amp_switch_info,
12443 .get = snd_hda_mixer_amp_switch_get,
12444 .put = alc268_acer_master_sw_put,
12445 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12449 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12450 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12451 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12452 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12456 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12457 /* output mixer control */
12458 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12461 .name = "Master Playback Switch",
12462 .info = snd_hda_mixer_amp_switch_info,
12463 .get = snd_hda_mixer_amp_switch_get,
12464 .put = alc268_acer_master_sw_put,
12465 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12469 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12470 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12471 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12472 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12473 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12474 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12475 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12479 /* bind volumes of both NID 0x0c and 0x0d */
12480 static struct hda_bind_ctls alc269_epc_bind_vol = {
12481 .ops = &snd_hda_bind_vol,
12483 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12484 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12489 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12490 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12491 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12492 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12496 /* capture mixer elements */
12497 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12498 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12499 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12500 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12505 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12506 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12508 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12512 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12514 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12516 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12517 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12518 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12522 static struct hda_verb alc269_lifebook_verbs[] = {
12523 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12524 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12525 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12527 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12529 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12530 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12531 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12532 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12536 /* toggle speaker-output according to the hp-jack state */
12537 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12539 unsigned int present;
12540 unsigned char bits;
12542 present = snd_hda_codec_read(codec, 0x15, 0,
12543 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12544 bits = present ? AMP_IN_MUTE(0) : 0;
12545 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12546 AMP_IN_MUTE(0), bits);
12547 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12548 AMP_IN_MUTE(0), bits);
12550 snd_hda_codec_write(codec, 0x20, 0,
12551 AC_VERB_SET_COEF_INDEX, 0x0c);
12552 snd_hda_codec_write(codec, 0x20, 0,
12553 AC_VERB_SET_PROC_COEF, 0x680);
12555 snd_hda_codec_write(codec, 0x20, 0,
12556 AC_VERB_SET_COEF_INDEX, 0x0c);
12557 snd_hda_codec_write(codec, 0x20, 0,
12558 AC_VERB_SET_PROC_COEF, 0x480);
12561 /* toggle speaker-output according to the hp-jacks state */
12562 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12564 unsigned int present;
12565 unsigned char bits;
12567 /* Check laptop headphone socket */
12568 present = snd_hda_codec_read(codec, 0x15, 0,
12569 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12571 /* Check port replicator headphone socket */
12572 present |= snd_hda_codec_read(codec, 0x1a, 0,
12573 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12575 bits = present ? AMP_IN_MUTE(0) : 0;
12576 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12577 AMP_IN_MUTE(0), bits);
12578 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12579 AMP_IN_MUTE(0), bits);
12581 snd_hda_codec_write(codec, 0x20, 0,
12582 AC_VERB_SET_COEF_INDEX, 0x0c);
12583 snd_hda_codec_write(codec, 0x20, 0,
12584 AC_VERB_SET_PROC_COEF, 0x680);
12586 snd_hda_codec_write(codec, 0x20, 0,
12587 AC_VERB_SET_COEF_INDEX, 0x0c);
12588 snd_hda_codec_write(codec, 0x20, 0,
12589 AC_VERB_SET_PROC_COEF, 0x480);
12592 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12594 unsigned int present;
12596 present = snd_hda_codec_read(codec, 0x18, 0,
12597 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12598 snd_hda_codec_write(codec, 0x23, 0,
12599 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12602 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12604 unsigned int present_laptop;
12605 unsigned int present_dock;
12607 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12608 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12610 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12611 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12613 /* Laptop mic port overrides dock mic port, design decision */
12615 snd_hda_codec_write(codec, 0x23, 0,
12616 AC_VERB_SET_CONNECT_SEL, 0x3);
12617 if (present_laptop)
12618 snd_hda_codec_write(codec, 0x23, 0,
12619 AC_VERB_SET_CONNECT_SEL, 0x0);
12620 if (!present_dock && !present_laptop)
12621 snd_hda_codec_write(codec, 0x23, 0,
12622 AC_VERB_SET_CONNECT_SEL, 0x1);
12625 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12628 if ((res >> 26) == ALC880_HP_EVENT)
12629 alc269_quanta_fl1_speaker_automute(codec);
12630 if ((res >> 26) == ALC880_MIC_EVENT)
12631 alc269_quanta_fl1_mic_automute(codec);
12634 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12637 if ((res >> 26) == ALC880_HP_EVENT)
12638 alc269_lifebook_speaker_automute(codec);
12639 if ((res >> 26) == ALC880_MIC_EVENT)
12640 alc269_lifebook_mic_autoswitch(codec);
12643 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12645 alc269_quanta_fl1_speaker_automute(codec);
12646 alc269_quanta_fl1_mic_automute(codec);
12649 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12651 alc269_lifebook_speaker_automute(codec);
12652 alc269_lifebook_mic_autoswitch(codec);
12655 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12657 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12658 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12659 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12660 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12661 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12662 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12666 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12667 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12668 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12669 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12671 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12672 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12676 /* toggle speaker-output according to the hp-jack state */
12677 static void alc269_speaker_automute(struct hda_codec *codec)
12679 unsigned int present;
12680 unsigned char bits;
12682 present = snd_hda_codec_read(codec, 0x15, 0,
12683 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12684 bits = present ? AMP_IN_MUTE(0) : 0;
12685 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12686 AMP_IN_MUTE(0), bits);
12687 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12688 AMP_IN_MUTE(0), bits);
12691 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12693 unsigned int present;
12695 present = snd_hda_codec_read(codec, 0x18, 0,
12696 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12697 snd_hda_codec_write(codec, 0x23, 0,
12698 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12701 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12703 unsigned int present;
12705 present = snd_hda_codec_read(codec, 0x18, 0,
12706 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12707 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12708 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12709 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12710 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12713 /* unsolicited event for HP jack sensing */
12714 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12717 if ((res >> 26) == ALC880_HP_EVENT)
12718 alc269_speaker_automute(codec);
12720 if ((res >> 26) == ALC880_MIC_EVENT)
12721 alc269_eeepc_dmic_automute(codec);
12724 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12726 alc269_speaker_automute(codec);
12727 alc269_eeepc_dmic_automute(codec);
12730 /* unsolicited event for HP jack sensing */
12731 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12734 if ((res >> 26) == ALC880_HP_EVENT)
12735 alc269_speaker_automute(codec);
12737 if ((res >> 26) == ALC880_MIC_EVENT)
12738 alc269_eeepc_amic_automute(codec);
12741 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12743 alc269_speaker_automute(codec);
12744 alc269_eeepc_amic_automute(codec);
12748 * generic initialization of ADC, input mixers and output mixers
12750 static struct hda_verb alc269_init_verbs[] = {
12752 * Unmute ADC0 and set the default input to mic-in
12754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12756 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12757 * analog-loopback mixer widget
12758 * Note: PASD motherboards uses the Line In 2 as the input for
12759 * front panel mic (mic 2)
12761 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12762 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12763 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12764 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12765 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12769 * Set up output mixers (0x0c - 0x0e)
12771 /* set vol=0 to output mixers */
12772 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12773 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12775 /* set up input amps for analog loopback */
12776 /* Amp Indices: DAC = 0, mixer = 1 */
12777 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12780 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12781 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12782 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12786 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12787 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12788 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12789 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12794 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12796 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12797 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12800 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12803 /* FIXME: use matrix-type input source selection */
12804 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12805 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12812 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12813 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12817 /* add playback controls from the parsed DAC table */
12818 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12819 const struct auto_pin_cfg *cfg)
12824 spec->multiout.num_dacs = 1; /* only use one dac */
12825 spec->multiout.dac_nids = spec->private_dac_nids;
12826 spec->multiout.dac_nids[0] = 2;
12828 nid = cfg->line_out_pins[0];
12830 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12831 "Front Playback Volume",
12832 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12835 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12836 "Front Playback Switch",
12837 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12842 nid = cfg->speaker_pins[0];
12844 if (!cfg->line_out_pins[0]) {
12845 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12846 "Speaker Playback Volume",
12847 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12853 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12854 "Speaker Playback Switch",
12855 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12860 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12861 "Speaker Playback Switch",
12862 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12868 nid = cfg->hp_pins[0];
12870 /* spec->multiout.hp_nid = 2; */
12871 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12872 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12873 "Headphone Playback Volume",
12874 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12880 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12881 "Headphone Playback Switch",
12882 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12887 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12888 "Headphone Playback Switch",
12889 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12898 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12899 const struct auto_pin_cfg *cfg)
12903 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12906 /* digital-mic input pin is excluded in alc880_auto_create..()
12907 * because it's under 0x18
12909 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12910 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12911 struct hda_input_mux *imux = &spec->private_imux[0];
12912 imux->items[imux->num_items].label = "Int Mic";
12913 imux->items[imux->num_items].index = 0x05;
12919 #ifdef CONFIG_SND_HDA_POWER_SAVE
12920 #define alc269_loopbacks alc880_loopbacks
12923 /* pcm configuration: identiacal with ALC880 */
12924 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12925 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12926 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12927 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12929 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12933 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12934 /* NID is set in alc_build_pcms */
12936 .open = alc880_playback_pcm_open,
12937 .prepare = alc880_playback_pcm_prepare,
12938 .cleanup = alc880_playback_pcm_cleanup
12942 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12946 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12947 /* NID is set in alc_build_pcms */
12951 * BIOS auto configuration
12953 static int alc269_parse_auto_config(struct hda_codec *codec)
12955 struct alc_spec *spec = codec->spec;
12957 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12959 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12964 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12967 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12971 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12973 if (spec->autocfg.dig_outs)
12974 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12976 if (spec->kctls.list)
12977 add_mixer(spec, spec->kctls.list);
12979 add_verb(spec, alc269_init_verbs);
12980 spec->num_mux_defs = 1;
12981 spec->input_mux = &spec->private_imux[0];
12982 /* set default input source */
12983 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12984 0, AC_VERB_SET_CONNECT_SEL,
12985 spec->input_mux->items[0].index);
12987 err = alc_auto_add_mic_boost(codec);
12991 if (!spec->cap_mixer && !spec->no_analog)
12992 set_capture_mixer(spec);
12997 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12998 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12999 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13002 /* init callback for auto-configuration model -- overriding the default init */
13003 static void alc269_auto_init(struct hda_codec *codec)
13005 struct alc_spec *spec = codec->spec;
13006 alc269_auto_init_multi_out(codec);
13007 alc269_auto_init_hp_out(codec);
13008 alc269_auto_init_analog_input(codec);
13009 if (spec->unsol_event)
13010 alc_inithook(codec);
13014 * configuration and preset
13016 static const char *alc269_models[ALC269_MODEL_LAST] = {
13017 [ALC269_BASIC] = "basic",
13018 [ALC269_QUANTA_FL1] = "quanta",
13019 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13020 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13021 [ALC269_FUJITSU] = "fujitsu",
13022 [ALC269_LIFEBOOK] = "lifebook"
13025 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13026 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13027 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13028 ALC269_ASUS_EEEPC_P703),
13029 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13030 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13031 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13032 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13033 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13034 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13035 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13036 ALC269_ASUS_EEEPC_P901),
13037 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13038 ALC269_ASUS_EEEPC_P901),
13039 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13040 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13041 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13045 static struct alc_config_preset alc269_presets[] = {
13047 .mixers = { alc269_base_mixer },
13048 .init_verbs = { alc269_init_verbs },
13049 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13050 .dac_nids = alc269_dac_nids,
13052 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13053 .channel_mode = alc269_modes,
13054 .input_mux = &alc269_capture_source,
13056 [ALC269_QUANTA_FL1] = {
13057 .mixers = { alc269_quanta_fl1_mixer },
13058 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13059 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13060 .dac_nids = alc269_dac_nids,
13062 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13063 .channel_mode = alc269_modes,
13064 .input_mux = &alc269_capture_source,
13065 .unsol_event = alc269_quanta_fl1_unsol_event,
13066 .init_hook = alc269_quanta_fl1_init_hook,
13068 [ALC269_ASUS_EEEPC_P703] = {
13069 .mixers = { alc269_eeepc_mixer },
13070 .cap_mixer = alc269_epc_capture_mixer,
13071 .init_verbs = { alc269_init_verbs,
13072 alc269_eeepc_amic_init_verbs },
13073 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13074 .dac_nids = alc269_dac_nids,
13076 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13077 .channel_mode = alc269_modes,
13078 .input_mux = &alc269_eeepc_amic_capture_source,
13079 .unsol_event = alc269_eeepc_amic_unsol_event,
13080 .init_hook = alc269_eeepc_amic_inithook,
13082 [ALC269_ASUS_EEEPC_P901] = {
13083 .mixers = { alc269_eeepc_mixer },
13084 .cap_mixer = alc269_epc_capture_mixer,
13085 .init_verbs = { alc269_init_verbs,
13086 alc269_eeepc_dmic_init_verbs },
13087 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13088 .dac_nids = alc269_dac_nids,
13090 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13091 .channel_mode = alc269_modes,
13092 .input_mux = &alc269_eeepc_dmic_capture_source,
13093 .unsol_event = alc269_eeepc_dmic_unsol_event,
13094 .init_hook = alc269_eeepc_dmic_inithook,
13096 [ALC269_FUJITSU] = {
13097 .mixers = { alc269_fujitsu_mixer },
13098 .cap_mixer = alc269_epc_capture_mixer,
13099 .init_verbs = { alc269_init_verbs,
13100 alc269_eeepc_dmic_init_verbs },
13101 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13102 .dac_nids = alc269_dac_nids,
13104 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13105 .channel_mode = alc269_modes,
13106 .input_mux = &alc269_eeepc_dmic_capture_source,
13107 .unsol_event = alc269_eeepc_dmic_unsol_event,
13108 .init_hook = alc269_eeepc_dmic_inithook,
13110 [ALC269_LIFEBOOK] = {
13111 .mixers = { alc269_lifebook_mixer },
13112 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13113 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13114 .dac_nids = alc269_dac_nids,
13116 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13117 .channel_mode = alc269_modes,
13118 .input_mux = &alc269_capture_source,
13119 .unsol_event = alc269_lifebook_unsol_event,
13120 .init_hook = alc269_lifebook_init_hook,
13124 static int patch_alc269(struct hda_codec *codec)
13126 struct alc_spec *spec;
13130 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13134 codec->spec = spec;
13136 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13138 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13142 if (board_config < 0) {
13143 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13144 "trying auto-probe from BIOS...\n", codec->chip_name);
13145 board_config = ALC269_AUTO;
13148 if (board_config == ALC269_AUTO) {
13149 /* automatic parse from the BIOS config */
13150 err = alc269_parse_auto_config(codec);
13156 "hda_codec: Cannot set up configuration "
13157 "from BIOS. Using base mode...\n");
13158 board_config = ALC269_BASIC;
13162 err = snd_hda_attach_beep_device(codec, 0x1);
13168 if (board_config != ALC269_AUTO)
13169 setup_preset(spec, &alc269_presets[board_config]);
13171 if (codec->subsystem_id == 0x17aa3bf8) {
13172 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13173 * fix the sample rate of analog I/O to 44.1kHz
13175 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13176 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13178 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13179 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13181 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13182 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13184 spec->adc_nids = alc269_adc_nids;
13185 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13186 spec->capsrc_nids = alc269_capsrc_nids;
13187 if (!spec->cap_mixer)
13188 set_capture_mixer(spec);
13189 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13191 codec->patch_ops = alc_patch_ops;
13192 if (board_config == ALC269_AUTO)
13193 spec->init_hook = alc269_auto_init;
13194 #ifdef CONFIG_SND_HDA_POWER_SAVE
13195 if (!spec->loopback.amplist)
13196 spec->loopback.amplist = alc269_loopbacks;
13198 codec->proc_widget_hook = print_realtek_coef;
13204 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13208 * set the path ways for 2 channel output
13209 * need to set the codec line out and mic 1 pin widgets to inputs
13211 static struct hda_verb alc861_threestack_ch2_init[] = {
13212 /* set pin widget 1Ah (line in) for input */
13213 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13214 /* set pin widget 18h (mic1/2) for input, for mic also enable
13217 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13219 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13221 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13222 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13228 * need to set the codec line out and mic 1 pin widgets to outputs
13230 static struct hda_verb alc861_threestack_ch6_init[] = {
13231 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13232 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13233 /* set pin widget 18h (mic1) for output (CLFE)*/
13234 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13236 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13237 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13239 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13241 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13242 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13247 static struct hda_channel_mode alc861_threestack_modes[2] = {
13248 { 2, alc861_threestack_ch2_init },
13249 { 6, alc861_threestack_ch6_init },
13251 /* Set mic1 as input and unmute the mixer */
13252 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13253 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13254 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13257 /* Set mic1 as output and mute mixer */
13258 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13259 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13260 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13264 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13265 { 2, alc861_uniwill_m31_ch2_init },
13266 { 4, alc861_uniwill_m31_ch4_init },
13269 /* Set mic1 and line-in as input and unmute the mixer */
13270 static struct hda_verb alc861_asus_ch2_init[] = {
13271 /* set pin widget 1Ah (line in) for input */
13272 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13273 /* set pin widget 18h (mic1/2) for input, for mic also enable
13276 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13278 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13280 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13281 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13285 /* Set mic1 nad line-in as output and mute mixer */
13286 static struct hda_verb alc861_asus_ch6_init[] = {
13287 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13288 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13289 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13290 /* set pin widget 18h (mic1) for output (CLFE)*/
13291 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13292 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13293 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13294 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13296 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13298 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13299 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13304 static struct hda_channel_mode alc861_asus_modes[2] = {
13305 { 2, alc861_asus_ch2_init },
13306 { 6, alc861_asus_ch6_init },
13311 static struct snd_kcontrol_new alc861_base_mixer[] = {
13312 /* output mixer control */
13313 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13314 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13315 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13316 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13317 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13319 /*Input mixer control */
13320 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13321 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13322 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13323 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13324 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13325 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13326 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13327 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13328 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13334 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13335 /* output mixer control */
13336 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13337 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13338 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13339 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13340 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13342 /* Input mixer control */
13343 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13344 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13345 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13346 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13347 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13348 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13350 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13351 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13356 .name = "Channel Mode",
13357 .info = alc_ch_mode_info,
13358 .get = alc_ch_mode_get,
13359 .put = alc_ch_mode_put,
13360 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13365 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13366 /* output mixer control */
13367 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13369 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13374 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13375 /* output mixer control */
13376 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13377 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13378 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13379 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13380 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13382 /* Input mixer control */
13383 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13384 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13385 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13386 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13387 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13388 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13390 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13391 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13392 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13396 .name = "Channel Mode",
13397 .info = alc_ch_mode_info,
13398 .get = alc_ch_mode_get,
13399 .put = alc_ch_mode_put,
13400 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13405 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13406 /* output mixer control */
13407 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13408 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13409 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13410 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13411 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13413 /* Input mixer control */
13414 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13415 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13416 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13417 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13418 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13419 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13420 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13421 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13422 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13423 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13427 .name = "Channel Mode",
13428 .info = alc_ch_mode_info,
13429 .get = alc_ch_mode_get,
13430 .put = alc_ch_mode_put,
13431 .private_value = ARRAY_SIZE(alc861_asus_modes),
13436 /* additional mixer */
13437 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13438 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13439 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13444 * generic initialization of ADC, input mixers and output mixers
13446 static struct hda_verb alc861_base_init_verbs[] = {
13448 * Unmute ADC0 and set the default input to mic-in
13450 /* port-A for surround (rear panel) */
13451 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13452 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13453 /* port-B for mic-in (rear panel) with vref */
13454 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13455 /* port-C for line-in (rear panel) */
13456 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13457 /* port-D for Front */
13458 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13459 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13460 /* port-E for HP out (front panel) */
13461 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13462 /* route front PCM to HP */
13463 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13464 /* port-F for mic-in (front panel) with vref */
13465 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13466 /* port-G for CLFE (rear panel) */
13467 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13468 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13469 /* port-H for side (rear panel) */
13470 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13471 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13473 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13474 /* route front mic to ADC1*/
13475 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13476 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13478 /* Unmute DAC0~3 & spdif out*/
13479 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13480 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13481 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13482 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13485 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13486 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13487 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13488 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13491 /* Unmute Stereo Mixer 15 */
13492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13497 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13498 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13499 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13501 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13502 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13503 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13505 /* hp used DAC 3 (Front) */
13506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13507 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13512 static struct hda_verb alc861_threestack_init_verbs[] = {
13514 * Unmute ADC0 and set the default input to mic-in
13516 /* port-A for surround (rear panel) */
13517 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13518 /* port-B for mic-in (rear panel) with vref */
13519 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13520 /* port-C for line-in (rear panel) */
13521 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13522 /* port-D for Front */
13523 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13524 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13525 /* port-E for HP out (front panel) */
13526 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13527 /* route front PCM to HP */
13528 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13529 /* port-F for mic-in (front panel) with vref */
13530 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13531 /* port-G for CLFE (rear panel) */
13532 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13533 /* port-H for side (rear panel) */
13534 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13536 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13537 /* route front mic to ADC1*/
13538 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13539 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13540 /* Unmute DAC0~3 & spdif out*/
13541 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13542 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13543 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13544 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13545 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13547 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13548 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13549 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13550 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13551 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13553 /* Unmute Stereo Mixer 15 */
13554 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13557 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13559 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13560 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13561 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13562 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13563 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13564 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13565 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13567 /* hp used DAC 3 (Front) */
13568 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13569 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13573 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13575 * Unmute ADC0 and set the default input to mic-in
13577 /* port-A for surround (rear panel) */
13578 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13579 /* port-B for mic-in (rear panel) with vref */
13580 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13581 /* port-C for line-in (rear panel) */
13582 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13583 /* port-D for Front */
13584 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13585 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13586 /* port-E for HP out (front panel) */
13587 /* this has to be set to VREF80 */
13588 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13589 /* route front PCM to HP */
13590 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13591 /* port-F for mic-in (front panel) with vref */
13592 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13593 /* port-G for CLFE (rear panel) */
13594 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13595 /* port-H for side (rear panel) */
13596 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13598 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13599 /* route front mic to ADC1*/
13600 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13601 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13602 /* Unmute DAC0~3 & spdif out*/
13603 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13604 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13605 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13606 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13607 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13609 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13610 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13611 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13612 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13613 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13615 /* Unmute Stereo Mixer 15 */
13616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13618 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13619 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13621 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13622 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13623 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13624 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13626 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13628 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13629 /* hp used DAC 3 (Front) */
13630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13635 static struct hda_verb alc861_asus_init_verbs[] = {
13637 * Unmute ADC0 and set the default input to mic-in
13639 /* port-A for surround (rear panel)
13640 * according to codec#0 this is the HP jack
13642 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13643 /* route front PCM to HP */
13644 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13645 /* port-B for mic-in (rear panel) with vref */
13646 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13647 /* port-C for line-in (rear panel) */
13648 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13649 /* port-D for Front */
13650 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13651 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13652 /* port-E for HP out (front panel) */
13653 /* this has to be set to VREF80 */
13654 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13655 /* route front PCM to HP */
13656 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13657 /* port-F for mic-in (front panel) with vref */
13658 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13659 /* port-G for CLFE (rear panel) */
13660 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13661 /* port-H for side (rear panel) */
13662 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13664 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13665 /* route front mic to ADC1*/
13666 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13668 /* Unmute DAC0~3 & spdif out*/
13669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13672 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13674 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13675 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13676 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13677 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13678 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13680 /* Unmute Stereo Mixer 15 */
13681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13686 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13687 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13688 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13689 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13691 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13692 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13694 /* hp used DAC 3 (Front) */
13695 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13700 /* additional init verbs for ASUS laptops */
13701 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13702 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13703 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13708 * generic initialization of ADC, input mixers and output mixers
13710 static struct hda_verb alc861_auto_init_verbs[] = {
13712 * Unmute ADC0 and set the default input to mic-in
13714 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13715 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13717 /* Unmute DAC0~3 & spdif out*/
13718 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13719 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13720 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13721 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13722 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13724 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13725 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13726 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13727 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13728 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13730 /* Unmute Stereo Mixer 15 */
13731 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13736 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13737 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13738 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13739 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13745 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13749 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13750 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13751 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13752 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13754 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13759 static struct hda_verb alc861_toshiba_init_verbs[] = {
13760 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13765 /* toggle speaker-output according to the hp-jack state */
13766 static void alc861_toshiba_automute(struct hda_codec *codec)
13768 unsigned int present;
13770 present = snd_hda_codec_read(codec, 0x0f, 0,
13771 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13772 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13773 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13774 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13775 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13778 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13781 if ((res >> 26) == ALC880_HP_EVENT)
13782 alc861_toshiba_automute(codec);
13785 /* pcm configuration: identiacal with ALC880 */
13786 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13787 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13788 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13789 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13792 #define ALC861_DIGOUT_NID 0x07
13794 static struct hda_channel_mode alc861_8ch_modes[1] = {
13798 static hda_nid_t alc861_dac_nids[4] = {
13799 /* front, surround, clfe, side */
13800 0x03, 0x06, 0x05, 0x04
13803 static hda_nid_t alc660_dac_nids[3] = {
13804 /* front, clfe, surround */
13808 static hda_nid_t alc861_adc_nids[1] = {
13813 static struct hda_input_mux alc861_capture_source = {
13817 { "Front Mic", 0x3 },
13824 /* fill in the dac_nids table from the parsed pin configuration */
13825 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13826 const struct auto_pin_cfg *cfg)
13831 spec->multiout.dac_nids = spec->private_dac_nids;
13832 for (i = 0; i < cfg->line_outs; i++) {
13833 nid = cfg->line_out_pins[i];
13835 if (i >= ARRAY_SIZE(alc861_dac_nids))
13837 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13840 spec->multiout.num_dacs = cfg->line_outs;
13844 /* add playback controls from the parsed DAC table */
13845 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13846 const struct auto_pin_cfg *cfg)
13849 static const char *chname[4] = {
13850 "Front", "Surround", NULL /*CLFE*/, "Side"
13855 for (i = 0; i < cfg->line_outs; i++) {
13856 nid = spec->multiout.dac_nids[i];
13861 err = add_control(spec, ALC_CTL_BIND_MUTE,
13862 "Center Playback Switch",
13863 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13867 err = add_control(spec, ALC_CTL_BIND_MUTE,
13868 "LFE Playback Switch",
13869 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13874 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13876 if (nid == alc861_dac_nids[idx])
13878 sprintf(name, "%s Playback Switch", chname[idx]);
13879 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13880 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13889 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13897 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13899 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13900 "Headphone Playback Switch",
13901 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13904 spec->multiout.hp_nid = nid;
13909 /* create playback/capture controls for input pins */
13910 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13911 const struct auto_pin_cfg *cfg)
13913 struct hda_input_mux *imux = &spec->private_imux[0];
13914 int i, err, idx, idx1;
13916 for (i = 0; i < AUTO_PIN_LAST; i++) {
13917 switch (cfg->input_pins[i]) {
13920 idx = 2; /* Line In */
13924 idx = 2; /* Line In */
13928 idx = 1; /* Mic In */
13932 idx = 1; /* Mic In */
13942 err = new_analog_input(spec, cfg->input_pins[i],
13943 auto_pin_cfg_labels[i], idx, 0x15);
13947 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13948 imux->items[imux->num_items].index = idx1;
13954 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13956 int pin_type, int dac_idx)
13958 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13960 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13964 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13966 struct alc_spec *spec = codec->spec;
13969 for (i = 0; i < spec->autocfg.line_outs; i++) {
13970 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13971 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13973 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13974 spec->multiout.dac_nids[i]);
13978 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13980 struct alc_spec *spec = codec->spec;
13983 pin = spec->autocfg.hp_pins[0];
13984 if (pin) /* connect to front */
13985 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13986 spec->multiout.dac_nids[0]);
13987 pin = spec->autocfg.speaker_pins[0];
13989 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13992 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13994 struct alc_spec *spec = codec->spec;
13997 for (i = 0; i < AUTO_PIN_LAST; i++) {
13998 hda_nid_t nid = spec->autocfg.input_pins[i];
13999 if (nid >= 0x0c && nid <= 0x11)
14000 alc_set_input_pin(codec, nid, i);
14004 /* parse the BIOS configuration and set up the alc_spec */
14005 /* return 1 if successful, 0 if the proper config is not found,
14006 * or a negative error code
14008 static int alc861_parse_auto_config(struct hda_codec *codec)
14010 struct alc_spec *spec = codec->spec;
14012 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14014 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14018 if (!spec->autocfg.line_outs)
14019 return 0; /* can't find valid BIOS pin config */
14021 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
14024 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
14027 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
14030 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
14034 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14036 if (spec->autocfg.dig_outs)
14037 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14039 if (spec->kctls.list)
14040 add_mixer(spec, spec->kctls.list);
14042 add_verb(spec, alc861_auto_init_verbs);
14044 spec->num_mux_defs = 1;
14045 spec->input_mux = &spec->private_imux[0];
14047 spec->adc_nids = alc861_adc_nids;
14048 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14049 set_capture_mixer(spec);
14051 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14056 /* additional initialization for auto-configuration model */
14057 static void alc861_auto_init(struct hda_codec *codec)
14059 struct alc_spec *spec = codec->spec;
14060 alc861_auto_init_multi_out(codec);
14061 alc861_auto_init_hp_out(codec);
14062 alc861_auto_init_analog_input(codec);
14063 if (spec->unsol_event)
14064 alc_inithook(codec);
14067 #ifdef CONFIG_SND_HDA_POWER_SAVE
14068 static struct hda_amp_list alc861_loopbacks[] = {
14069 { 0x15, HDA_INPUT, 0 },
14070 { 0x15, HDA_INPUT, 1 },
14071 { 0x15, HDA_INPUT, 2 },
14072 { 0x15, HDA_INPUT, 3 },
14079 * configuration and preset
14081 static const char *alc861_models[ALC861_MODEL_LAST] = {
14082 [ALC861_3ST] = "3stack",
14083 [ALC660_3ST] = "3stack-660",
14084 [ALC861_3ST_DIG] = "3stack-dig",
14085 [ALC861_6ST_DIG] = "6stack-dig",
14086 [ALC861_UNIWILL_M31] = "uniwill-m31",
14087 [ALC861_TOSHIBA] = "toshiba",
14088 [ALC861_ASUS] = "asus",
14089 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14090 [ALC861_AUTO] = "auto",
14093 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14094 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14095 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14096 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14097 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14098 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14099 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14100 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14101 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14102 * Any other models that need this preset?
14104 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14105 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14106 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14107 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14108 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14109 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14110 /* FIXME: the below seems conflict */
14111 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14112 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14113 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14117 static struct alc_config_preset alc861_presets[] = {
14119 .mixers = { alc861_3ST_mixer },
14120 .init_verbs = { alc861_threestack_init_verbs },
14121 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14122 .dac_nids = alc861_dac_nids,
14123 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14124 .channel_mode = alc861_threestack_modes,
14126 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14127 .adc_nids = alc861_adc_nids,
14128 .input_mux = &alc861_capture_source,
14130 [ALC861_3ST_DIG] = {
14131 .mixers = { alc861_base_mixer },
14132 .init_verbs = { alc861_threestack_init_verbs },
14133 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14134 .dac_nids = alc861_dac_nids,
14135 .dig_out_nid = ALC861_DIGOUT_NID,
14136 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14137 .channel_mode = alc861_threestack_modes,
14139 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14140 .adc_nids = alc861_adc_nids,
14141 .input_mux = &alc861_capture_source,
14143 [ALC861_6ST_DIG] = {
14144 .mixers = { alc861_base_mixer },
14145 .init_verbs = { alc861_base_init_verbs },
14146 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14147 .dac_nids = alc861_dac_nids,
14148 .dig_out_nid = ALC861_DIGOUT_NID,
14149 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14150 .channel_mode = alc861_8ch_modes,
14151 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14152 .adc_nids = alc861_adc_nids,
14153 .input_mux = &alc861_capture_source,
14156 .mixers = { alc861_3ST_mixer },
14157 .init_verbs = { alc861_threestack_init_verbs },
14158 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14159 .dac_nids = alc660_dac_nids,
14160 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14161 .channel_mode = alc861_threestack_modes,
14163 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14164 .adc_nids = alc861_adc_nids,
14165 .input_mux = &alc861_capture_source,
14167 [ALC861_UNIWILL_M31] = {
14168 .mixers = { alc861_uniwill_m31_mixer },
14169 .init_verbs = { alc861_uniwill_m31_init_verbs },
14170 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14171 .dac_nids = alc861_dac_nids,
14172 .dig_out_nid = ALC861_DIGOUT_NID,
14173 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14174 .channel_mode = alc861_uniwill_m31_modes,
14176 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14177 .adc_nids = alc861_adc_nids,
14178 .input_mux = &alc861_capture_source,
14180 [ALC861_TOSHIBA] = {
14181 .mixers = { alc861_toshiba_mixer },
14182 .init_verbs = { alc861_base_init_verbs,
14183 alc861_toshiba_init_verbs },
14184 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14185 .dac_nids = alc861_dac_nids,
14186 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14187 .channel_mode = alc883_3ST_2ch_modes,
14188 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14189 .adc_nids = alc861_adc_nids,
14190 .input_mux = &alc861_capture_source,
14191 .unsol_event = alc861_toshiba_unsol_event,
14192 .init_hook = alc861_toshiba_automute,
14195 .mixers = { alc861_asus_mixer },
14196 .init_verbs = { alc861_asus_init_verbs },
14197 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14198 .dac_nids = alc861_dac_nids,
14199 .dig_out_nid = ALC861_DIGOUT_NID,
14200 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14201 .channel_mode = alc861_asus_modes,
14204 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14205 .adc_nids = alc861_adc_nids,
14206 .input_mux = &alc861_capture_source,
14208 [ALC861_ASUS_LAPTOP] = {
14209 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14210 .init_verbs = { alc861_asus_init_verbs,
14211 alc861_asus_laptop_init_verbs },
14212 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14213 .dac_nids = alc861_dac_nids,
14214 .dig_out_nid = ALC861_DIGOUT_NID,
14215 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14216 .channel_mode = alc883_3ST_2ch_modes,
14218 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14219 .adc_nids = alc861_adc_nids,
14220 .input_mux = &alc861_capture_source,
14225 static int patch_alc861(struct hda_codec *codec)
14227 struct alc_spec *spec;
14231 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14235 codec->spec = spec;
14237 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14241 if (board_config < 0) {
14242 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14243 "trying auto-probe from BIOS...\n", codec->chip_name);
14244 board_config = ALC861_AUTO;
14247 if (board_config == ALC861_AUTO) {
14248 /* automatic parse from the BIOS config */
14249 err = alc861_parse_auto_config(codec);
14255 "hda_codec: Cannot set up configuration "
14256 "from BIOS. Using base mode...\n");
14257 board_config = ALC861_3ST_DIG;
14261 err = snd_hda_attach_beep_device(codec, 0x23);
14267 if (board_config != ALC861_AUTO)
14268 setup_preset(spec, &alc861_presets[board_config]);
14270 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14271 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14273 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14274 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14276 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14278 spec->vmaster_nid = 0x03;
14280 codec->patch_ops = alc_patch_ops;
14281 if (board_config == ALC861_AUTO)
14282 spec->init_hook = alc861_auto_init;
14283 #ifdef CONFIG_SND_HDA_POWER_SAVE
14284 if (!spec->loopback.amplist)
14285 spec->loopback.amplist = alc861_loopbacks;
14287 codec->proc_widget_hook = print_realtek_coef;
14293 * ALC861-VD support
14297 * In addition, an independent DAC
14299 #define ALC861VD_DIGOUT_NID 0x06
14301 static hda_nid_t alc861vd_dac_nids[4] = {
14302 /* front, surr, clfe, side surr */
14303 0x02, 0x03, 0x04, 0x05
14306 /* dac_nids for ALC660vd are in a different order - according to
14307 * Realtek's driver.
14308 * This should probably tesult in a different mixer for 6stack models
14309 * of ALC660vd codecs, but for now there is only 3stack mixer
14310 * - and it is the same as in 861vd.
14311 * adc_nids in ALC660vd are (is) the same as in 861vd
14313 static hda_nid_t alc660vd_dac_nids[3] = {
14314 /* front, rear, clfe, rear_surr */
14318 static hda_nid_t alc861vd_adc_nids[1] = {
14323 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14326 /* FIXME: should be a matrix-type input source selection */
14327 static struct hda_input_mux alc861vd_capture_source = {
14331 { "Front Mic", 0x1 },
14337 static struct hda_input_mux alc861vd_dallas_capture_source = {
14340 { "Ext Mic", 0x0 },
14341 { "Int Mic", 0x1 },
14345 static struct hda_input_mux alc861vd_hp_capture_source = {
14348 { "Front Mic", 0x0 },
14349 { "ATAPI Mic", 0x1 },
14356 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14363 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14364 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14365 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14366 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14367 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14374 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14375 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14376 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14377 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14378 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14382 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14383 { 6, alc861vd_6stack_ch6_init },
14384 { 8, alc861vd_6stack_ch8_init },
14387 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14390 .name = "Channel Mode",
14391 .info = alc_ch_mode_info,
14392 .get = alc_ch_mode_get,
14393 .put = alc_ch_mode_put,
14398 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14399 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14401 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14402 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14403 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14406 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14408 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14410 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14412 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14413 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14415 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14416 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14418 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14421 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14422 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14424 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14431 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14432 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14437 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14438 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14439 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14441 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14443 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14444 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14445 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14447 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14448 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14449 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14454 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14455 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14460 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14461 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14462 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14463 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14465 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14467 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14471 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14472 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14475 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14476 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14481 /* Pin assignment: Speaker=0x14, HP = 0x15,
14482 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14484 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14485 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14486 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14487 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14488 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14489 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14490 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14491 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14492 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14493 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14494 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14498 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14499 * Front Mic=0x18, ATAPI Mic = 0x19,
14501 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14502 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14503 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14504 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14505 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14506 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14507 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14508 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14509 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14515 * generic initialization of ADC, input mixers and output mixers
14517 static struct hda_verb alc861vd_volume_init_verbs[] = {
14519 * Unmute ADC0 and set the default input to mic-in
14521 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14522 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14524 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14525 * the analog-loopback mixer widget
14527 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14534 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14541 * Set up output mixers (0x02 - 0x05)
14543 /* set vol=0 to output mixers */
14544 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14545 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14546 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14547 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14549 /* set up input amps for analog loopback */
14550 /* Amp Indices: DAC = 0, mixer = 1 */
14551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14553 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14554 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14555 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14556 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14557 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14558 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14564 * 3-stack pin configuration:
14565 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14567 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14569 * Set pin mode and muting
14571 /* set front pin widgets 0x14 for output */
14572 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14573 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14574 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14576 /* Mic (rear) pin: input vref at 80% */
14577 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14578 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14579 /* Front Mic pin: input vref at 80% */
14580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14582 /* Line In pin: input */
14583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14585 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14586 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14587 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14589 /* CD pin widget for input */
14590 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14596 * 6-stack pin configuration:
14598 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14600 * Set pin mode and muting
14602 /* set front pin widgets 0x14 for output */
14603 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14604 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14605 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14607 /* Rear Pin: output 1 (0x0d) */
14608 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14610 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14611 /* CLFE Pin: output 2 (0x0e) */
14612 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14613 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14614 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14615 /* Side Pin: output 3 (0x0f) */
14616 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14618 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14620 /* Mic (rear) pin: input vref at 80% */
14621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14623 /* Front Mic pin: input vref at 80% */
14624 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14625 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14626 /* Line In pin: input */
14627 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14629 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14631 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14633 /* CD pin widget for input */
14634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14639 static struct hda_verb alc861vd_eapd_verbs[] = {
14640 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14644 static struct hda_verb alc660vd_eapd_verbs[] = {
14645 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14646 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14650 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14653 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14654 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14655 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14659 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14661 unsigned int present;
14662 unsigned char bits;
14664 present = snd_hda_codec_read(codec, 0x18, 0,
14665 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14666 bits = present ? HDA_AMP_MUTE : 0;
14667 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14668 HDA_AMP_MUTE, bits);
14671 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14673 struct alc_spec *spec = codec->spec;
14675 spec->autocfg.hp_pins[0] = 0x1b;
14676 spec->autocfg.speaker_pins[0] = 0x14;
14677 alc_automute_amp(codec);
14678 alc861vd_lenovo_mic_automute(codec);
14681 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14684 switch (res >> 26) {
14685 case ALC880_MIC_EVENT:
14686 alc861vd_lenovo_mic_automute(codec);
14689 alc_automute_amp_unsol_event(codec, res);
14694 static struct hda_verb alc861vd_dallas_verbs[] = {
14695 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14696 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14697 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14698 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14705 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14706 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14707 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14713 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14714 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14715 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14716 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14718 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14719 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14720 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14721 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14722 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14723 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14724 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14725 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14733 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14734 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14739 /* toggle speaker-output according to the hp-jack state */
14740 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14742 struct alc_spec *spec = codec->spec;
14744 spec->autocfg.hp_pins[0] = 0x15;
14745 spec->autocfg.speaker_pins[0] = 0x14;
14746 alc_automute_amp(codec);
14749 #ifdef CONFIG_SND_HDA_POWER_SAVE
14750 #define alc861vd_loopbacks alc880_loopbacks
14753 /* pcm configuration: identiacal with ALC880 */
14754 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14755 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14756 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14757 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14760 * configuration and preset
14762 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14763 [ALC660VD_3ST] = "3stack-660",
14764 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14765 [ALC660VD_ASUS_V1S] = "asus-v1s",
14766 [ALC861VD_3ST] = "3stack",
14767 [ALC861VD_3ST_DIG] = "3stack-digout",
14768 [ALC861VD_6ST_DIG] = "6stack-digout",
14769 [ALC861VD_LENOVO] = "lenovo",
14770 [ALC861VD_DALLAS] = "dallas",
14771 [ALC861VD_HP] = "hp",
14772 [ALC861VD_AUTO] = "auto",
14775 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14776 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14777 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14778 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14779 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14780 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14781 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14782 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14783 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14784 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14785 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14786 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14787 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14788 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14789 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14790 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14794 static struct alc_config_preset alc861vd_presets[] = {
14796 .mixers = { alc861vd_3st_mixer },
14797 .init_verbs = { alc861vd_volume_init_verbs,
14798 alc861vd_3stack_init_verbs },
14799 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14800 .dac_nids = alc660vd_dac_nids,
14801 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14802 .channel_mode = alc861vd_3stack_2ch_modes,
14803 .input_mux = &alc861vd_capture_source,
14805 [ALC660VD_3ST_DIG] = {
14806 .mixers = { alc861vd_3st_mixer },
14807 .init_verbs = { alc861vd_volume_init_verbs,
14808 alc861vd_3stack_init_verbs },
14809 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14810 .dac_nids = alc660vd_dac_nids,
14811 .dig_out_nid = ALC861VD_DIGOUT_NID,
14812 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14813 .channel_mode = alc861vd_3stack_2ch_modes,
14814 .input_mux = &alc861vd_capture_source,
14817 .mixers = { alc861vd_3st_mixer },
14818 .init_verbs = { alc861vd_volume_init_verbs,
14819 alc861vd_3stack_init_verbs },
14820 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14821 .dac_nids = alc861vd_dac_nids,
14822 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14823 .channel_mode = alc861vd_3stack_2ch_modes,
14824 .input_mux = &alc861vd_capture_source,
14826 [ALC861VD_3ST_DIG] = {
14827 .mixers = { alc861vd_3st_mixer },
14828 .init_verbs = { alc861vd_volume_init_verbs,
14829 alc861vd_3stack_init_verbs },
14830 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14831 .dac_nids = alc861vd_dac_nids,
14832 .dig_out_nid = ALC861VD_DIGOUT_NID,
14833 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14834 .channel_mode = alc861vd_3stack_2ch_modes,
14835 .input_mux = &alc861vd_capture_source,
14837 [ALC861VD_6ST_DIG] = {
14838 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14839 .init_verbs = { alc861vd_volume_init_verbs,
14840 alc861vd_6stack_init_verbs },
14841 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14842 .dac_nids = alc861vd_dac_nids,
14843 .dig_out_nid = ALC861VD_DIGOUT_NID,
14844 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14845 .channel_mode = alc861vd_6stack_modes,
14846 .input_mux = &alc861vd_capture_source,
14848 [ALC861VD_LENOVO] = {
14849 .mixers = { alc861vd_lenovo_mixer },
14850 .init_verbs = { alc861vd_volume_init_verbs,
14851 alc861vd_3stack_init_verbs,
14852 alc861vd_eapd_verbs,
14853 alc861vd_lenovo_unsol_verbs },
14854 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14855 .dac_nids = alc660vd_dac_nids,
14856 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14857 .channel_mode = alc861vd_3stack_2ch_modes,
14858 .input_mux = &alc861vd_capture_source,
14859 .unsol_event = alc861vd_lenovo_unsol_event,
14860 .init_hook = alc861vd_lenovo_init_hook,
14862 [ALC861VD_DALLAS] = {
14863 .mixers = { alc861vd_dallas_mixer },
14864 .init_verbs = { alc861vd_dallas_verbs },
14865 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14866 .dac_nids = alc861vd_dac_nids,
14867 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14868 .channel_mode = alc861vd_3stack_2ch_modes,
14869 .input_mux = &alc861vd_dallas_capture_source,
14870 .unsol_event = alc_automute_amp_unsol_event,
14871 .init_hook = alc861vd_dallas_init_hook,
14874 .mixers = { alc861vd_hp_mixer },
14875 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14876 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14877 .dac_nids = alc861vd_dac_nids,
14878 .dig_out_nid = ALC861VD_DIGOUT_NID,
14879 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14880 .channel_mode = alc861vd_3stack_2ch_modes,
14881 .input_mux = &alc861vd_hp_capture_source,
14882 .unsol_event = alc_automute_amp_unsol_event,
14883 .init_hook = alc861vd_dallas_init_hook,
14885 [ALC660VD_ASUS_V1S] = {
14886 .mixers = { alc861vd_lenovo_mixer },
14887 .init_verbs = { alc861vd_volume_init_verbs,
14888 alc861vd_3stack_init_verbs,
14889 alc861vd_eapd_verbs,
14890 alc861vd_lenovo_unsol_verbs },
14891 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14892 .dac_nids = alc660vd_dac_nids,
14893 .dig_out_nid = ALC861VD_DIGOUT_NID,
14894 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14895 .channel_mode = alc861vd_3stack_2ch_modes,
14896 .input_mux = &alc861vd_capture_source,
14897 .unsol_event = alc861vd_lenovo_unsol_event,
14898 .init_hook = alc861vd_lenovo_init_hook,
14903 * BIOS auto configuration
14905 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14906 hda_nid_t nid, int pin_type, int dac_idx)
14908 alc_set_pin_output(codec, nid, pin_type);
14911 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14913 struct alc_spec *spec = codec->spec;
14916 for (i = 0; i <= HDA_SIDE; i++) {
14917 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14918 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14920 alc861vd_auto_set_output_and_unmute(codec, nid,
14926 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14928 struct alc_spec *spec = codec->spec;
14931 pin = spec->autocfg.hp_pins[0];
14932 if (pin) /* connect to front and use dac 0 */
14933 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14934 pin = spec->autocfg.speaker_pins[0];
14936 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14939 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14940 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14942 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14944 struct alc_spec *spec = codec->spec;
14947 for (i = 0; i < AUTO_PIN_LAST; i++) {
14948 hda_nid_t nid = spec->autocfg.input_pins[i];
14949 if (alc861vd_is_input_pin(nid)) {
14950 alc_set_input_pin(codec, nid, i);
14951 if (nid != ALC861VD_PIN_CD_NID &&
14952 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14953 snd_hda_codec_write(codec, nid, 0,
14954 AC_VERB_SET_AMP_GAIN_MUTE,
14960 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14962 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14963 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14965 /* add playback controls from the parsed DAC table */
14966 /* Based on ALC880 version. But ALC861VD has separate,
14967 * different NIDs for mute/unmute switch and volume control */
14968 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14969 const struct auto_pin_cfg *cfg)
14972 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14973 hda_nid_t nid_v, nid_s;
14976 for (i = 0; i < cfg->line_outs; i++) {
14977 if (!spec->multiout.dac_nids[i])
14979 nid_v = alc861vd_idx_to_mixer_vol(
14981 spec->multiout.dac_nids[i]));
14982 nid_s = alc861vd_idx_to_mixer_switch(
14984 spec->multiout.dac_nids[i]));
14988 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14989 "Center Playback Volume",
14990 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14994 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14995 "LFE Playback Volume",
14996 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15000 err = add_control(spec, ALC_CTL_BIND_MUTE,
15001 "Center Playback Switch",
15002 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15006 err = add_control(spec, ALC_CTL_BIND_MUTE,
15007 "LFE Playback Switch",
15008 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15013 sprintf(name, "%s Playback Volume", chname[i]);
15014 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15015 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15019 sprintf(name, "%s Playback Switch", chname[i]);
15020 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15021 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15030 /* add playback controls for speaker and HP outputs */
15031 /* Based on ALC880 version. But ALC861VD has separate,
15032 * different NIDs for mute/unmute switch and volume control */
15033 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15034 hda_nid_t pin, const char *pfx)
15036 hda_nid_t nid_v, nid_s;
15043 if (alc880_is_fixed_pin(pin)) {
15044 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15045 /* specify the DAC as the extra output */
15046 if (!spec->multiout.hp_nid)
15047 spec->multiout.hp_nid = nid_v;
15049 spec->multiout.extra_out_nid[0] = nid_v;
15050 /* control HP volume/switch on the output mixer amp */
15051 nid_v = alc861vd_idx_to_mixer_vol(
15052 alc880_fixed_pin_idx(pin));
15053 nid_s = alc861vd_idx_to_mixer_switch(
15054 alc880_fixed_pin_idx(pin));
15056 sprintf(name, "%s Playback Volume", pfx);
15057 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15058 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15061 sprintf(name, "%s Playback Switch", pfx);
15062 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15063 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15066 } else if (alc880_is_multi_pin(pin)) {
15067 /* set manual connection */
15068 /* we have only a switch on HP-out PIN */
15069 sprintf(name, "%s Playback Switch", pfx);
15070 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15071 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15078 /* parse the BIOS configuration and set up the alc_spec
15079 * return 1 if successful, 0 if the proper config is not found,
15080 * or a negative error code
15081 * Based on ALC880 version - had to change it to override
15082 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15083 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15085 struct alc_spec *spec = codec->spec;
15087 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15089 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15093 if (!spec->autocfg.line_outs)
15094 return 0; /* can't find valid BIOS pin config */
15096 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15099 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15102 err = alc861vd_auto_create_extra_out(spec,
15103 spec->autocfg.speaker_pins[0],
15107 err = alc861vd_auto_create_extra_out(spec,
15108 spec->autocfg.hp_pins[0],
15112 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15116 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15118 if (spec->autocfg.dig_outs)
15119 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15121 if (spec->kctls.list)
15122 add_mixer(spec, spec->kctls.list);
15124 add_verb(spec, alc861vd_volume_init_verbs);
15126 spec->num_mux_defs = 1;
15127 spec->input_mux = &spec->private_imux[0];
15129 err = alc_auto_add_mic_boost(codec);
15133 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15138 /* additional initialization for auto-configuration model */
15139 static void alc861vd_auto_init(struct hda_codec *codec)
15141 struct alc_spec *spec = codec->spec;
15142 alc861vd_auto_init_multi_out(codec);
15143 alc861vd_auto_init_hp_out(codec);
15144 alc861vd_auto_init_analog_input(codec);
15145 alc861vd_auto_init_input_src(codec);
15146 if (spec->unsol_event)
15147 alc_inithook(codec);
15150 static int patch_alc861vd(struct hda_codec *codec)
15152 struct alc_spec *spec;
15153 int err, board_config;
15155 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15159 codec->spec = spec;
15161 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15165 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15166 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15167 "trying auto-probe from BIOS...\n", codec->chip_name);
15168 board_config = ALC861VD_AUTO;
15171 if (board_config == ALC861VD_AUTO) {
15172 /* automatic parse from the BIOS config */
15173 err = alc861vd_parse_auto_config(codec);
15179 "hda_codec: Cannot set up configuration "
15180 "from BIOS. Using base mode...\n");
15181 board_config = ALC861VD_3ST;
15185 err = snd_hda_attach_beep_device(codec, 0x23);
15191 if (board_config != ALC861VD_AUTO)
15192 setup_preset(spec, &alc861vd_presets[board_config]);
15194 if (codec->vendor_id == 0x10ec0660) {
15195 /* always turn on EAPD */
15196 add_verb(spec, alc660vd_eapd_verbs);
15199 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15200 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15202 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15203 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15205 spec->adc_nids = alc861vd_adc_nids;
15206 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15207 spec->capsrc_nids = alc861vd_capsrc_nids;
15208 spec->capture_style = CAPT_MIX;
15210 set_capture_mixer(spec);
15211 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15213 spec->vmaster_nid = 0x02;
15215 codec->patch_ops = alc_patch_ops;
15217 if (board_config == ALC861VD_AUTO)
15218 spec->init_hook = alc861vd_auto_init;
15219 #ifdef CONFIG_SND_HDA_POWER_SAVE
15220 if (!spec->loopback.amplist)
15221 spec->loopback.amplist = alc861vd_loopbacks;
15223 codec->proc_widget_hook = print_realtek_coef;
15231 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15232 * configuration. Each pin widget can choose any input DACs and a mixer.
15233 * Each ADC is connected from a mixer of all inputs. This makes possible
15234 * 6-channel independent captures.
15236 * In addition, an independent DAC for the multi-playback (not used in this
15239 #define ALC662_DIGOUT_NID 0x06
15240 #define ALC662_DIGIN_NID 0x0a
15242 static hda_nid_t alc662_dac_nids[4] = {
15243 /* front, rear, clfe, rear_surr */
15247 static hda_nid_t alc272_dac_nids[2] = {
15251 static hda_nid_t alc662_adc_nids[1] = {
15256 static hda_nid_t alc272_adc_nids[1] = {
15261 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15262 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15266 /* FIXME: should be a matrix-type input source selection */
15267 static struct hda_input_mux alc662_capture_source = {
15271 { "Front Mic", 0x1 },
15277 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15285 static struct hda_input_mux alc662_eeepc_capture_source = {
15293 static struct hda_input_mux alc663_capture_source = {
15297 { "Front Mic", 0x1 },
15302 static struct hda_input_mux alc663_m51va_capture_source = {
15305 { "Ext-Mic", 0x0 },
15310 #if 1 /* set to 0 for testing other input sources below */
15311 static struct hda_input_mux alc272_nc10_capture_source = {
15314 { "Autoselect Mic", 0x0 },
15315 { "Internal Mic", 0x1 },
15319 static struct hda_input_mux alc272_nc10_capture_source = {
15322 { "Autoselect Mic", 0x0 },
15323 { "Internal Mic", 0x1 },
15324 { "In-0x02", 0x2 },
15325 { "In-0x03", 0x3 },
15326 { "In-0x04", 0x4 },
15327 { "In-0x05", 0x5 },
15328 { "In-0x06", 0x6 },
15329 { "In-0x07", 0x7 },
15330 { "In-0x08", 0x8 },
15331 { "In-0x09", 0x9 },
15332 { "In-0x0a", 0x0a },
15333 { "In-0x0b", 0x0b },
15334 { "In-0x0c", 0x0c },
15335 { "In-0x0d", 0x0d },
15336 { "In-0x0e", 0x0e },
15337 { "In-0x0f", 0x0f },
15345 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15352 static struct hda_verb alc662_3ST_ch2_init[] = {
15353 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15354 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15355 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15356 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15363 static struct hda_verb alc662_3ST_ch6_init[] = {
15364 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15365 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15366 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15367 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15368 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15369 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15373 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15374 { 2, alc662_3ST_ch2_init },
15375 { 6, alc662_3ST_ch6_init },
15381 static struct hda_verb alc662_sixstack_ch6_init[] = {
15382 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15383 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15384 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15391 static struct hda_verb alc662_sixstack_ch8_init[] = {
15392 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15393 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15394 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15398 static struct hda_channel_mode alc662_5stack_modes[2] = {
15399 { 2, alc662_sixstack_ch6_init },
15400 { 6, alc662_sixstack_ch8_init },
15403 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15404 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15407 static struct snd_kcontrol_new alc662_base_mixer[] = {
15408 /* output mixer control */
15409 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15412 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15416 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15417 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15419 /*Input mixer control */
15420 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15421 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15422 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15423 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15424 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15425 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15426 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15427 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15431 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15432 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15433 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15434 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15446 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15447 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15449 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15451 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15453 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15454 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15456 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15457 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15458 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15459 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15460 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15461 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15462 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15463 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15467 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15468 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15469 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15470 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15471 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15473 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15474 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15475 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15476 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15480 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15481 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15482 ALC262_HIPPO_MASTER_SWITCH,
15484 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15485 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15486 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15488 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15489 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15490 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15494 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15495 ALC262_HIPPO_MASTER_SWITCH,
15496 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15497 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15498 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15499 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15500 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15501 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15502 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15508 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15509 .ops = &snd_hda_bind_vol,
15511 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15512 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15517 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15518 .ops = &snd_hda_bind_sw,
15520 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15521 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15526 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15527 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15528 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15529 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15530 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15534 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15535 .ops = &snd_hda_bind_sw,
15537 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15538 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15539 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15544 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15545 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15546 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15549 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15550 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15555 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15556 .ops = &snd_hda_bind_sw,
15558 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15559 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15560 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15565 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15566 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15567 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15568 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15569 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15570 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15571 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15575 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15576 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15577 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15578 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15579 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15581 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15582 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15586 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15587 .ops = &snd_hda_bind_vol,
15589 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15590 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15595 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15596 .ops = &snd_hda_bind_sw,
15598 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15599 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15604 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15605 HDA_BIND_VOL("Master Playback Volume",
15606 &alc663_asus_two_bind_master_vol),
15607 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15608 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15609 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15610 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15611 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15615 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15616 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15617 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15618 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15621 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15625 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15627 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15628 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15629 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15634 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15635 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15639 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15640 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15641 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15642 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15646 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15647 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15648 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15649 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15653 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15656 .name = "Channel Mode",
15657 .info = alc_ch_mode_info,
15658 .get = alc_ch_mode_get,
15659 .put = alc_ch_mode_put,
15664 static struct hda_verb alc662_init_verbs[] = {
15665 /* ADC: mute amp left and right */
15666 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15667 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15668 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15672 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15673 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15674 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15676 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15680 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15683 /* Front Pin: output 0 (0x0c) */
15684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15687 /* Rear Pin: output 1 (0x0d) */
15688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15691 /* CLFE Pin: output 2 (0x0e) */
15692 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15693 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15695 /* Mic (rear) pin: input vref at 80% */
15696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15698 /* Front Mic pin: input vref at 80% */
15699 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15700 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15701 /* Line In pin: input */
15702 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15703 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15704 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15705 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15706 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15707 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15708 /* CD pin widget for input */
15709 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15711 /* FIXME: use matrix-type input source selection */
15712 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15714 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15717 /* always trun on EAPD */
15718 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15719 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15724 static struct hda_verb alc662_sue_init_verbs[] = {
15725 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15730 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15731 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15732 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15736 /* Set Unsolicited Event*/
15737 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15738 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15739 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15744 * generic initialization of ADC, input mixers and output mixers
15746 static struct hda_verb alc662_auto_init_verbs[] = {
15748 * Unmute ADC and set the default input to mic-in
15750 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15751 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15753 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15755 * Note: PASD motherboards uses the Line In 2 as the input for front
15756 * panel mic (mic 2)
15758 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15760 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15761 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15762 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15763 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15766 * Set up output mixers (0x0c - 0x0f)
15768 /* set vol=0 to output mixers */
15769 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15770 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15771 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15773 /* set up input amps for analog loopback */
15774 /* Amp Indices: DAC = 0, mixer = 1 */
15775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15777 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15778 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15779 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 /* FIXME: use matrix-type input source selection */
15784 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15787 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 /* additional verbs for ALC663 */
15792 static struct hda_verb alc663_auto_init_verbs[] = {
15793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15798 static struct hda_verb alc663_m51va_init_verbs[] = {
15799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15800 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15801 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15802 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15803 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15804 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15805 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15806 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15807 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15811 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15812 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15813 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15814 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15817 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15818 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15822 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15823 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15826 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15829 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15830 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15834 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15835 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15836 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15837 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15839 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15840 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15841 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15845 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15846 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15847 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15848 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15849 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15852 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15854 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15855 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15856 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15861 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15862 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15863 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15864 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15865 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15866 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15869 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15870 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15871 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15872 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15873 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15877 static struct hda_verb alc663_g71v_init_verbs[] = {
15878 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15879 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15880 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15882 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15883 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15884 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15886 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15887 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15888 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15892 static struct hda_verb alc663_g50v_init_verbs[] = {
15893 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15894 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15895 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15897 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15898 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15902 static struct hda_verb alc662_ecs_init_verbs[] = {
15903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15904 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15905 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15906 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15910 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15911 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15912 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15914 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15915 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15916 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15917 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15918 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15919 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15920 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15921 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15925 static struct hda_verb alc272_dell_init_verbs[] = {
15926 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15927 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15929 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15930 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15931 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15932 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15934 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15935 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15936 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15940 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15941 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15942 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15946 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15947 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15948 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15952 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15954 unsigned int present;
15955 unsigned char bits;
15957 present = snd_hda_codec_read(codec, 0x14, 0,
15958 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15959 bits = present ? HDA_AMP_MUTE : 0;
15960 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15961 HDA_AMP_MUTE, bits);
15964 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15966 unsigned int present;
15967 unsigned char bits;
15969 present = snd_hda_codec_read(codec, 0x1b, 0,
15970 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15971 bits = present ? HDA_AMP_MUTE : 0;
15972 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15973 HDA_AMP_MUTE, bits);
15974 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15975 HDA_AMP_MUTE, bits);
15978 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15981 if ((res >> 26) == ALC880_HP_EVENT)
15982 alc662_lenovo_101e_all_automute(codec);
15983 if ((res >> 26) == ALC880_FRONT_EVENT)
15984 alc662_lenovo_101e_ispeaker_automute(codec);
15987 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15989 unsigned int present;
15991 present = snd_hda_codec_read(codec, 0x18, 0,
15992 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15993 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15994 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15995 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15996 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15997 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15998 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15999 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16000 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16003 /* unsolicited event for HP jack sensing */
16004 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16007 if ((res >> 26) == ALC880_MIC_EVENT)
16008 alc662_eeepc_mic_automute(codec);
16010 alc262_hippo_unsol_event(codec, res);
16013 static void alc662_eeepc_inithook(struct hda_codec *codec)
16015 alc262_hippo1_init_hook(codec);
16016 alc662_eeepc_mic_automute(codec);
16019 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16021 struct alc_spec *spec = codec->spec;
16023 spec->autocfg.hp_pins[0] = 0x14;
16024 spec->autocfg.speaker_pins[0] = 0x1b;
16025 alc262_hippo_master_update(codec);
16028 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16030 unsigned int present;
16031 unsigned char bits;
16033 present = snd_hda_codec_read(codec, 0x21, 0,
16034 AC_VERB_GET_PIN_SENSE, 0)
16035 & AC_PINSENSE_PRESENCE;
16036 bits = present ? HDA_AMP_MUTE : 0;
16037 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16038 AMP_IN_MUTE(0), bits);
16039 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16040 AMP_IN_MUTE(0), bits);
16043 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16045 unsigned int present;
16046 unsigned char bits;
16048 present = snd_hda_codec_read(codec, 0x21, 0,
16049 AC_VERB_GET_PIN_SENSE, 0)
16050 & AC_PINSENSE_PRESENCE;
16051 bits = present ? HDA_AMP_MUTE : 0;
16052 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16053 AMP_IN_MUTE(0), bits);
16054 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16055 AMP_IN_MUTE(0), bits);
16056 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16057 AMP_IN_MUTE(0), bits);
16058 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16059 AMP_IN_MUTE(0), bits);
16062 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16064 unsigned int present;
16065 unsigned char bits;
16067 present = snd_hda_codec_read(codec, 0x15, 0,
16068 AC_VERB_GET_PIN_SENSE, 0)
16069 & AC_PINSENSE_PRESENCE;
16070 bits = present ? HDA_AMP_MUTE : 0;
16071 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16072 AMP_IN_MUTE(0), bits);
16073 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16074 AMP_IN_MUTE(0), bits);
16075 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16076 AMP_IN_MUTE(0), bits);
16077 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16078 AMP_IN_MUTE(0), bits);
16081 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16083 unsigned int present;
16084 unsigned char bits;
16086 present = snd_hda_codec_read(codec, 0x1b, 0,
16087 AC_VERB_GET_PIN_SENSE, 0)
16088 & AC_PINSENSE_PRESENCE;
16089 bits = present ? 0 : PIN_OUT;
16090 snd_hda_codec_write(codec, 0x14, 0,
16091 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16094 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16096 unsigned int present1, present2;
16098 present1 = snd_hda_codec_read(codec, 0x21, 0,
16099 AC_VERB_GET_PIN_SENSE, 0)
16100 & AC_PINSENSE_PRESENCE;
16101 present2 = snd_hda_codec_read(codec, 0x15, 0,
16102 AC_VERB_GET_PIN_SENSE, 0)
16103 & AC_PINSENSE_PRESENCE;
16105 if (present1 || present2) {
16106 snd_hda_codec_write_cache(codec, 0x14, 0,
16107 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16109 snd_hda_codec_write_cache(codec, 0x14, 0,
16110 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16114 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16116 unsigned int present1, present2;
16118 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16119 AC_VERB_GET_PIN_SENSE, 0)
16120 & AC_PINSENSE_PRESENCE;
16121 present2 = snd_hda_codec_read(codec, 0x15, 0,
16122 AC_VERB_GET_PIN_SENSE, 0)
16123 & AC_PINSENSE_PRESENCE;
16125 if (present1 || present2) {
16126 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16127 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16128 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16129 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16131 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16132 AMP_IN_MUTE(0), 0);
16133 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16134 AMP_IN_MUTE(0), 0);
16138 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16140 unsigned int present;
16142 present = snd_hda_codec_read(codec, 0x18, 0,
16143 AC_VERB_GET_PIN_SENSE, 0)
16144 & AC_PINSENSE_PRESENCE;
16145 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16146 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16147 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16148 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16149 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16150 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16151 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16152 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16155 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16158 switch (res >> 26) {
16159 case ALC880_HP_EVENT:
16160 alc663_m51va_speaker_automute(codec);
16162 case ALC880_MIC_EVENT:
16163 alc663_m51va_mic_automute(codec);
16168 static void alc663_m51va_inithook(struct hda_codec *codec)
16170 alc663_m51va_speaker_automute(codec);
16171 alc663_m51va_mic_automute(codec);
16174 /* ***************** Mode1 ******************************/
16175 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16178 switch (res >> 26) {
16179 case ALC880_HP_EVENT:
16180 alc663_m51va_speaker_automute(codec);
16182 case ALC880_MIC_EVENT:
16183 alc662_eeepc_mic_automute(codec);
16188 static void alc663_mode1_inithook(struct hda_codec *codec)
16190 alc663_m51va_speaker_automute(codec);
16191 alc662_eeepc_mic_automute(codec);
16193 /* ***************** Mode2 ******************************/
16194 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16197 switch (res >> 26) {
16198 case ALC880_HP_EVENT:
16199 alc662_f5z_speaker_automute(codec);
16201 case ALC880_MIC_EVENT:
16202 alc662_eeepc_mic_automute(codec);
16207 static void alc662_mode2_inithook(struct hda_codec *codec)
16209 alc662_f5z_speaker_automute(codec);
16210 alc662_eeepc_mic_automute(codec);
16212 /* ***************** Mode3 ******************************/
16213 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16216 switch (res >> 26) {
16217 case ALC880_HP_EVENT:
16218 alc663_two_hp_m1_speaker_automute(codec);
16220 case ALC880_MIC_EVENT:
16221 alc662_eeepc_mic_automute(codec);
16226 static void alc663_mode3_inithook(struct hda_codec *codec)
16228 alc663_two_hp_m1_speaker_automute(codec);
16229 alc662_eeepc_mic_automute(codec);
16231 /* ***************** Mode4 ******************************/
16232 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16235 switch (res >> 26) {
16236 case ALC880_HP_EVENT:
16237 alc663_21jd_two_speaker_automute(codec);
16239 case ALC880_MIC_EVENT:
16240 alc662_eeepc_mic_automute(codec);
16245 static void alc663_mode4_inithook(struct hda_codec *codec)
16247 alc663_21jd_two_speaker_automute(codec);
16248 alc662_eeepc_mic_automute(codec);
16250 /* ***************** Mode5 ******************************/
16251 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16254 switch (res >> 26) {
16255 case ALC880_HP_EVENT:
16256 alc663_15jd_two_speaker_automute(codec);
16258 case ALC880_MIC_EVENT:
16259 alc662_eeepc_mic_automute(codec);
16264 static void alc663_mode5_inithook(struct hda_codec *codec)
16266 alc663_15jd_two_speaker_automute(codec);
16267 alc662_eeepc_mic_automute(codec);
16269 /* ***************** Mode6 ******************************/
16270 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16273 switch (res >> 26) {
16274 case ALC880_HP_EVENT:
16275 alc663_two_hp_m2_speaker_automute(codec);
16277 case ALC880_MIC_EVENT:
16278 alc662_eeepc_mic_automute(codec);
16283 static void alc663_mode6_inithook(struct hda_codec *codec)
16285 alc663_two_hp_m2_speaker_automute(codec);
16286 alc662_eeepc_mic_automute(codec);
16289 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16291 unsigned int present;
16292 unsigned char bits;
16294 present = snd_hda_codec_read(codec, 0x21, 0,
16295 AC_VERB_GET_PIN_SENSE, 0)
16296 & AC_PINSENSE_PRESENCE;
16297 bits = present ? HDA_AMP_MUTE : 0;
16298 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16299 HDA_AMP_MUTE, bits);
16300 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16301 HDA_AMP_MUTE, bits);
16304 static void alc663_g71v_front_automute(struct hda_codec *codec)
16306 unsigned int present;
16307 unsigned char bits;
16309 present = snd_hda_codec_read(codec, 0x15, 0,
16310 AC_VERB_GET_PIN_SENSE, 0)
16311 & AC_PINSENSE_PRESENCE;
16312 bits = present ? HDA_AMP_MUTE : 0;
16313 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16314 HDA_AMP_MUTE, bits);
16317 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16320 switch (res >> 26) {
16321 case ALC880_HP_EVENT:
16322 alc663_g71v_hp_automute(codec);
16324 case ALC880_FRONT_EVENT:
16325 alc663_g71v_front_automute(codec);
16327 case ALC880_MIC_EVENT:
16328 alc662_eeepc_mic_automute(codec);
16333 static void alc663_g71v_inithook(struct hda_codec *codec)
16335 alc663_g71v_front_automute(codec);
16336 alc663_g71v_hp_automute(codec);
16337 alc662_eeepc_mic_automute(codec);
16340 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16343 switch (res >> 26) {
16344 case ALC880_HP_EVENT:
16345 alc663_m51va_speaker_automute(codec);
16347 case ALC880_MIC_EVENT:
16348 alc662_eeepc_mic_automute(codec);
16353 static void alc663_g50v_inithook(struct hda_codec *codec)
16355 alc663_m51va_speaker_automute(codec);
16356 alc662_eeepc_mic_automute(codec);
16359 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16360 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16361 ALC262_HIPPO_MASTER_SWITCH,
16363 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16364 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16365 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16367 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16368 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16369 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16373 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16374 /* Master Playback automatically created from Speaker and Headphone */
16375 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16376 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16377 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16380 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16381 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16382 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16384 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16385 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16386 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16390 #ifdef CONFIG_SND_HDA_POWER_SAVE
16391 #define alc662_loopbacks alc880_loopbacks
16395 /* pcm configuration: identiacal with ALC880 */
16396 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16397 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16398 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16399 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16402 * configuration and preset
16404 static const char *alc662_models[ALC662_MODEL_LAST] = {
16405 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16406 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16407 [ALC662_3ST_6ch] = "3stack-6ch",
16408 [ALC662_5ST_DIG] = "6stack-dig",
16409 [ALC662_LENOVO_101E] = "lenovo-101e",
16410 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16411 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16412 [ALC662_ECS] = "ecs",
16413 [ALC663_ASUS_M51VA] = "m51va",
16414 [ALC663_ASUS_G71V] = "g71v",
16415 [ALC663_ASUS_H13] = "h13",
16416 [ALC663_ASUS_G50V] = "g50v",
16417 [ALC663_ASUS_MODE1] = "asus-mode1",
16418 [ALC662_ASUS_MODE2] = "asus-mode2",
16419 [ALC663_ASUS_MODE3] = "asus-mode3",
16420 [ALC663_ASUS_MODE4] = "asus-mode4",
16421 [ALC663_ASUS_MODE5] = "asus-mode5",
16422 [ALC663_ASUS_MODE6] = "asus-mode6",
16423 [ALC272_DELL] = "dell",
16424 [ALC272_DELL_ZM1] = "dell-zm1",
16425 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16426 [ALC662_AUTO] = "auto",
16429 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16430 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16431 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16432 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16433 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16434 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16435 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16436 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16437 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16438 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16439 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16440 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16441 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16442 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16443 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16444 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16445 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16446 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16447 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16448 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16449 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16450 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16451 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16452 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16453 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16454 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16455 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16456 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16457 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16458 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16459 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16460 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16461 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16462 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16463 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16464 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16465 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16466 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16467 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16468 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16469 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16470 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16471 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16472 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16473 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16474 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16475 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16476 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16477 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16478 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16479 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16480 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16481 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16482 ALC662_3ST_6ch_DIG),
16483 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16484 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16485 ALC662_3ST_6ch_DIG),
16486 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16487 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16488 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16489 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16490 ALC662_3ST_6ch_DIG),
16491 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16496 static struct alc_config_preset alc662_presets[] = {
16497 [ALC662_3ST_2ch_DIG] = {
16498 .mixers = { alc662_3ST_2ch_mixer },
16499 .init_verbs = { alc662_init_verbs },
16500 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16501 .dac_nids = alc662_dac_nids,
16502 .dig_out_nid = ALC662_DIGOUT_NID,
16503 .dig_in_nid = ALC662_DIGIN_NID,
16504 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16505 .channel_mode = alc662_3ST_2ch_modes,
16506 .input_mux = &alc662_capture_source,
16508 [ALC662_3ST_6ch_DIG] = {
16509 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16510 .init_verbs = { alc662_init_verbs },
16511 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16512 .dac_nids = alc662_dac_nids,
16513 .dig_out_nid = ALC662_DIGOUT_NID,
16514 .dig_in_nid = ALC662_DIGIN_NID,
16515 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16516 .channel_mode = alc662_3ST_6ch_modes,
16518 .input_mux = &alc662_capture_source,
16520 [ALC662_3ST_6ch] = {
16521 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16522 .init_verbs = { alc662_init_verbs },
16523 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16524 .dac_nids = alc662_dac_nids,
16525 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16526 .channel_mode = alc662_3ST_6ch_modes,
16528 .input_mux = &alc662_capture_source,
16530 [ALC662_5ST_DIG] = {
16531 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16532 .init_verbs = { alc662_init_verbs },
16533 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16534 .dac_nids = alc662_dac_nids,
16535 .dig_out_nid = ALC662_DIGOUT_NID,
16536 .dig_in_nid = ALC662_DIGIN_NID,
16537 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16538 .channel_mode = alc662_5stack_modes,
16539 .input_mux = &alc662_capture_source,
16541 [ALC662_LENOVO_101E] = {
16542 .mixers = { alc662_lenovo_101e_mixer },
16543 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16544 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16545 .dac_nids = alc662_dac_nids,
16546 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16547 .channel_mode = alc662_3ST_2ch_modes,
16548 .input_mux = &alc662_lenovo_101e_capture_source,
16549 .unsol_event = alc662_lenovo_101e_unsol_event,
16550 .init_hook = alc662_lenovo_101e_all_automute,
16552 [ALC662_ASUS_EEEPC_P701] = {
16553 .mixers = { alc662_eeepc_p701_mixer },
16554 .init_verbs = { alc662_init_verbs,
16555 alc662_eeepc_sue_init_verbs },
16556 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16557 .dac_nids = alc662_dac_nids,
16558 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16559 .channel_mode = alc662_3ST_2ch_modes,
16560 .input_mux = &alc662_eeepc_capture_source,
16561 .unsol_event = alc662_eeepc_unsol_event,
16562 .init_hook = alc662_eeepc_inithook,
16564 [ALC662_ASUS_EEEPC_EP20] = {
16565 .mixers = { alc662_eeepc_ep20_mixer,
16566 alc662_chmode_mixer },
16567 .init_verbs = { alc662_init_verbs,
16568 alc662_eeepc_ep20_sue_init_verbs },
16569 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16570 .dac_nids = alc662_dac_nids,
16571 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16572 .channel_mode = alc662_3ST_6ch_modes,
16573 .input_mux = &alc662_lenovo_101e_capture_source,
16574 .unsol_event = alc662_eeepc_unsol_event,
16575 .init_hook = alc662_eeepc_ep20_inithook,
16578 .mixers = { alc662_ecs_mixer },
16579 .init_verbs = { alc662_init_verbs,
16580 alc662_ecs_init_verbs },
16581 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16582 .dac_nids = alc662_dac_nids,
16583 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16584 .channel_mode = alc662_3ST_2ch_modes,
16585 .input_mux = &alc662_eeepc_capture_source,
16586 .unsol_event = alc662_eeepc_unsol_event,
16587 .init_hook = alc662_eeepc_inithook,
16589 [ALC663_ASUS_M51VA] = {
16590 .mixers = { alc663_m51va_mixer },
16591 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16592 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16593 .dac_nids = alc662_dac_nids,
16594 .dig_out_nid = ALC662_DIGOUT_NID,
16595 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16596 .channel_mode = alc662_3ST_2ch_modes,
16597 .input_mux = &alc663_m51va_capture_source,
16598 .unsol_event = alc663_m51va_unsol_event,
16599 .init_hook = alc663_m51va_inithook,
16601 [ALC663_ASUS_G71V] = {
16602 .mixers = { alc663_g71v_mixer },
16603 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16604 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16605 .dac_nids = alc662_dac_nids,
16606 .dig_out_nid = ALC662_DIGOUT_NID,
16607 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16608 .channel_mode = alc662_3ST_2ch_modes,
16609 .input_mux = &alc662_eeepc_capture_source,
16610 .unsol_event = alc663_g71v_unsol_event,
16611 .init_hook = alc663_g71v_inithook,
16613 [ALC663_ASUS_H13] = {
16614 .mixers = { alc663_m51va_mixer },
16615 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16616 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16617 .dac_nids = alc662_dac_nids,
16618 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16619 .channel_mode = alc662_3ST_2ch_modes,
16620 .input_mux = &alc663_m51va_capture_source,
16621 .unsol_event = alc663_m51va_unsol_event,
16622 .init_hook = alc663_m51va_inithook,
16624 [ALC663_ASUS_G50V] = {
16625 .mixers = { alc663_g50v_mixer },
16626 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16627 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16628 .dac_nids = alc662_dac_nids,
16629 .dig_out_nid = ALC662_DIGOUT_NID,
16630 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16631 .channel_mode = alc662_3ST_6ch_modes,
16632 .input_mux = &alc663_capture_source,
16633 .unsol_event = alc663_g50v_unsol_event,
16634 .init_hook = alc663_g50v_inithook,
16636 [ALC663_ASUS_MODE1] = {
16637 .mixers = { alc663_m51va_mixer },
16638 .cap_mixer = alc662_auto_capture_mixer,
16639 .init_verbs = { alc662_init_verbs,
16640 alc663_21jd_amic_init_verbs },
16641 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16643 .dac_nids = alc662_dac_nids,
16644 .dig_out_nid = ALC662_DIGOUT_NID,
16645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16646 .channel_mode = alc662_3ST_2ch_modes,
16647 .input_mux = &alc662_eeepc_capture_source,
16648 .unsol_event = alc663_mode1_unsol_event,
16649 .init_hook = alc663_mode1_inithook,
16651 [ALC662_ASUS_MODE2] = {
16652 .mixers = { alc662_1bjd_mixer },
16653 .cap_mixer = alc662_auto_capture_mixer,
16654 .init_verbs = { alc662_init_verbs,
16655 alc662_1bjd_amic_init_verbs },
16656 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16657 .dac_nids = alc662_dac_nids,
16658 .dig_out_nid = ALC662_DIGOUT_NID,
16659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16660 .channel_mode = alc662_3ST_2ch_modes,
16661 .input_mux = &alc662_eeepc_capture_source,
16662 .unsol_event = alc662_mode2_unsol_event,
16663 .init_hook = alc662_mode2_inithook,
16665 [ALC663_ASUS_MODE3] = {
16666 .mixers = { alc663_two_hp_m1_mixer },
16667 .cap_mixer = alc662_auto_capture_mixer,
16668 .init_verbs = { alc662_init_verbs,
16669 alc663_two_hp_amic_m1_init_verbs },
16670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16672 .dac_nids = alc662_dac_nids,
16673 .dig_out_nid = ALC662_DIGOUT_NID,
16674 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16675 .channel_mode = alc662_3ST_2ch_modes,
16676 .input_mux = &alc662_eeepc_capture_source,
16677 .unsol_event = alc663_mode3_unsol_event,
16678 .init_hook = alc663_mode3_inithook,
16680 [ALC663_ASUS_MODE4] = {
16681 .mixers = { alc663_asus_21jd_clfe_mixer },
16682 .cap_mixer = alc662_auto_capture_mixer,
16683 .init_verbs = { alc662_init_verbs,
16684 alc663_21jd_amic_init_verbs},
16685 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16687 .dac_nids = alc662_dac_nids,
16688 .dig_out_nid = ALC662_DIGOUT_NID,
16689 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16690 .channel_mode = alc662_3ST_2ch_modes,
16691 .input_mux = &alc662_eeepc_capture_source,
16692 .unsol_event = alc663_mode4_unsol_event,
16693 .init_hook = alc663_mode4_inithook,
16695 [ALC663_ASUS_MODE5] = {
16696 .mixers = { alc663_asus_15jd_clfe_mixer },
16697 .cap_mixer = alc662_auto_capture_mixer,
16698 .init_verbs = { alc662_init_verbs,
16699 alc663_15jd_amic_init_verbs },
16700 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16702 .dac_nids = alc662_dac_nids,
16703 .dig_out_nid = ALC662_DIGOUT_NID,
16704 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16705 .channel_mode = alc662_3ST_2ch_modes,
16706 .input_mux = &alc662_eeepc_capture_source,
16707 .unsol_event = alc663_mode5_unsol_event,
16708 .init_hook = alc663_mode5_inithook,
16710 [ALC663_ASUS_MODE6] = {
16711 .mixers = { alc663_two_hp_m2_mixer },
16712 .cap_mixer = alc662_auto_capture_mixer,
16713 .init_verbs = { alc662_init_verbs,
16714 alc663_two_hp_amic_m2_init_verbs },
16715 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16717 .dac_nids = alc662_dac_nids,
16718 .dig_out_nid = ALC662_DIGOUT_NID,
16719 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16720 .channel_mode = alc662_3ST_2ch_modes,
16721 .input_mux = &alc662_eeepc_capture_source,
16722 .unsol_event = alc663_mode6_unsol_event,
16723 .init_hook = alc663_mode6_inithook,
16726 .mixers = { alc663_m51va_mixer },
16727 .cap_mixer = alc272_auto_capture_mixer,
16728 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16729 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16730 .dac_nids = alc662_dac_nids,
16731 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16732 .adc_nids = alc272_adc_nids,
16733 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16734 .capsrc_nids = alc272_capsrc_nids,
16735 .channel_mode = alc662_3ST_2ch_modes,
16736 .input_mux = &alc663_m51va_capture_source,
16737 .unsol_event = alc663_m51va_unsol_event,
16738 .init_hook = alc663_m51va_inithook,
16740 [ALC272_DELL_ZM1] = {
16741 .mixers = { alc663_m51va_mixer },
16742 .cap_mixer = alc662_auto_capture_mixer,
16743 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16744 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16745 .dac_nids = alc662_dac_nids,
16746 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16747 .adc_nids = alc662_adc_nids,
16748 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16749 .capsrc_nids = alc662_capsrc_nids,
16750 .channel_mode = alc662_3ST_2ch_modes,
16751 .input_mux = &alc663_m51va_capture_source,
16752 .unsol_event = alc663_m51va_unsol_event,
16753 .init_hook = alc663_m51va_inithook,
16755 [ALC272_SAMSUNG_NC10] = {
16756 .mixers = { alc272_nc10_mixer },
16757 .init_verbs = { alc662_init_verbs,
16758 alc663_21jd_amic_init_verbs },
16759 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16760 .dac_nids = alc272_dac_nids,
16761 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16762 .channel_mode = alc662_3ST_2ch_modes,
16763 .input_mux = &alc272_nc10_capture_source,
16764 .unsol_event = alc663_mode4_unsol_event,
16765 .init_hook = alc663_mode4_inithook,
16771 * BIOS auto configuration
16774 /* add playback controls from the parsed DAC table */
16775 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16776 const struct auto_pin_cfg *cfg)
16779 static const char *chname[4] = {
16780 "Front", "Surround", NULL /*CLFE*/, "Side"
16785 for (i = 0; i < cfg->line_outs; i++) {
16786 if (!spec->multiout.dac_nids[i])
16788 nid = alc880_idx_to_dac(i);
16791 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16792 "Center Playback Volume",
16793 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16797 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16798 "LFE Playback Volume",
16799 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16803 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16804 "Center Playback Switch",
16805 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16809 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16810 "LFE Playback Switch",
16811 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16816 sprintf(name, "%s Playback Volume", chname[i]);
16817 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16818 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16822 sprintf(name, "%s Playback Switch", chname[i]);
16823 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16824 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16833 /* add playback controls for speaker and HP outputs */
16834 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16845 /* ALC663 has a mono output pin on 0x17 */
16846 sprintf(name, "%s Playback Switch", pfx);
16847 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16848 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16852 if (alc880_is_fixed_pin(pin)) {
16853 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16854 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16855 /* specify the DAC as the extra output */
16856 if (!spec->multiout.hp_nid)
16857 spec->multiout.hp_nid = nid;
16859 spec->multiout.extra_out_nid[0] = nid;
16860 /* control HP volume/switch on the output mixer amp */
16861 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16862 sprintf(name, "%s Playback Volume", pfx);
16863 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16864 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16867 sprintf(name, "%s Playback Switch", pfx);
16868 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16869 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16872 } else if (alc880_is_multi_pin(pin)) {
16873 /* set manual connection */
16874 /* we have only a switch on HP-out PIN */
16875 sprintf(name, "%s Playback Switch", pfx);
16876 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16877 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16884 /* return the index of the src widget from the connection list of the nid.
16885 * return -1 if not found
16887 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16890 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16893 conns = snd_hda_get_connections(codec, nid, conn_list,
16894 ARRAY_SIZE(conn_list));
16897 for (i = 0; i < conns; i++)
16898 if (conn_list[i] == src)
16903 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16905 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16906 return (pincap & AC_PINCAP_IN) != 0;
16909 /* create playback/capture controls for input pins */
16910 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16911 const struct auto_pin_cfg *cfg)
16913 struct alc_spec *spec = codec->spec;
16914 struct hda_input_mux *imux = &spec->private_imux[0];
16917 for (i = 0; i < AUTO_PIN_LAST; i++) {
16918 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16919 idx = alc662_input_pin_idx(codec, 0x0b,
16920 cfg->input_pins[i]);
16922 err = new_analog_input(spec, cfg->input_pins[i],
16923 auto_pin_cfg_labels[i],
16928 idx = alc662_input_pin_idx(codec, 0x22,
16929 cfg->input_pins[i]);
16931 imux->items[imux->num_items].label =
16932 auto_pin_cfg_labels[i];
16933 imux->items[imux->num_items].index = idx;
16941 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16942 hda_nid_t nid, int pin_type,
16945 alc_set_pin_output(codec, nid, pin_type);
16946 /* need the manual connection? */
16947 if (alc880_is_multi_pin(nid)) {
16948 struct alc_spec *spec = codec->spec;
16949 int idx = alc880_multi_pin_idx(nid);
16950 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16951 AC_VERB_SET_CONNECT_SEL,
16952 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16956 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16958 struct alc_spec *spec = codec->spec;
16961 for (i = 0; i <= HDA_SIDE; i++) {
16962 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16963 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16965 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16970 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16972 struct alc_spec *spec = codec->spec;
16975 pin = spec->autocfg.hp_pins[0];
16976 if (pin) /* connect to front */
16978 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16979 pin = spec->autocfg.speaker_pins[0];
16981 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16984 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16986 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16988 struct alc_spec *spec = codec->spec;
16991 for (i = 0; i < AUTO_PIN_LAST; i++) {
16992 hda_nid_t nid = spec->autocfg.input_pins[i];
16993 if (alc662_is_input_pin(codec, nid)) {
16994 alc_set_input_pin(codec, nid, i);
16995 if (nid != ALC662_PIN_CD_NID &&
16996 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16997 snd_hda_codec_write(codec, nid, 0,
16998 AC_VERB_SET_AMP_GAIN_MUTE,
17004 #define alc662_auto_init_input_src alc882_auto_init_input_src
17006 static int alc662_parse_auto_config(struct hda_codec *codec)
17008 struct alc_spec *spec = codec->spec;
17010 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17012 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17016 if (!spec->autocfg.line_outs)
17017 return 0; /* can't find valid BIOS pin config */
17019 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17022 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17025 err = alc662_auto_create_extra_out(spec,
17026 spec->autocfg.speaker_pins[0],
17030 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17034 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17038 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17040 if (spec->autocfg.dig_outs)
17041 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17043 if (spec->kctls.list)
17044 add_mixer(spec, spec->kctls.list);
17046 spec->num_mux_defs = 1;
17047 spec->input_mux = &spec->private_imux[0];
17049 add_verb(spec, alc662_auto_init_verbs);
17050 if (codec->vendor_id == 0x10ec0663)
17051 add_verb(spec, alc663_auto_init_verbs);
17053 err = alc_auto_add_mic_boost(codec);
17057 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17062 /* additional initialization for auto-configuration model */
17063 static void alc662_auto_init(struct hda_codec *codec)
17065 struct alc_spec *spec = codec->spec;
17066 alc662_auto_init_multi_out(codec);
17067 alc662_auto_init_hp_out(codec);
17068 alc662_auto_init_analog_input(codec);
17069 alc662_auto_init_input_src(codec);
17070 if (spec->unsol_event)
17071 alc_inithook(codec);
17074 static int patch_alc662(struct hda_codec *codec)
17076 struct alc_spec *spec;
17077 int err, board_config;
17079 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17083 codec->spec = spec;
17085 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17087 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17090 if (board_config < 0) {
17091 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17092 "trying auto-probe from BIOS...\n", codec->chip_name);
17093 board_config = ALC662_AUTO;
17096 if (board_config == ALC662_AUTO) {
17097 /* automatic parse from the BIOS config */
17098 err = alc662_parse_auto_config(codec);
17104 "hda_codec: Cannot set up configuration "
17105 "from BIOS. Using base mode...\n");
17106 board_config = ALC662_3ST_2ch_DIG;
17110 err = snd_hda_attach_beep_device(codec, 0x1);
17116 if (board_config != ALC662_AUTO)
17117 setup_preset(spec, &alc662_presets[board_config]);
17119 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17120 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17122 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17123 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17125 spec->adc_nids = alc662_adc_nids;
17126 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17127 spec->capsrc_nids = alc662_capsrc_nids;
17128 spec->capture_style = CAPT_MIX;
17130 if (!spec->cap_mixer)
17131 set_capture_mixer(spec);
17132 if (codec->vendor_id == 0x10ec0662)
17133 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17135 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17137 spec->vmaster_nid = 0x02;
17139 codec->patch_ops = alc_patch_ops;
17140 if (board_config == ALC662_AUTO)
17141 spec->init_hook = alc662_auto_init;
17142 #ifdef CONFIG_SND_HDA_POWER_SAVE
17143 if (!spec->loopback.amplist)
17144 spec->loopback.amplist = alc662_loopbacks;
17146 codec->proc_widget_hook = print_realtek_coef;
17154 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17155 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17156 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17157 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17158 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17159 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17160 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17161 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17162 .patch = patch_alc861 },
17163 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17164 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17165 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17166 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17167 .patch = patch_alc883 },
17168 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17169 .patch = patch_alc662 },
17170 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17171 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17172 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17173 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17174 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17175 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17176 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17177 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17178 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17179 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17180 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17181 .patch = patch_alc883 },
17182 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17183 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17184 {} /* terminator */
17187 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17189 MODULE_LICENSE("GPL");
17190 MODULE_DESCRIPTION("Realtek HD-audio codec");
17192 static struct hda_codec_preset_list realtek_list = {
17193 .preset = snd_hda_preset_realtek,
17194 .owner = THIS_MODULE,
17197 static int __init patch_realtek_init(void)
17199 return snd_hda_add_codec_preset(&realtek_list);
17202 static void __exit patch_realtek_exit(void)
17204 snd_hda_delete_codec_preset(&realtek_list);
17207 module_init(patch_realtek_init)
17208 module_exit(patch_realtek_exit)