2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
216 ALC883_TARGA_2ch_DIG,
217 ALC883_TARGA_8ch_DIG,
220 ALC888_ACER_ASPIRE_4930G,
221 ALC888_ACER_ASPIRE_6530G,
222 ALC888_ACER_ASPIRE_8930G,
223 ALC888_ACER_ASPIRE_7730G,
227 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763,
229 ALC888_LENOVO_MS7195_DIG,
237 ALC883_FUJITSU_PI2515,
238 ALC888_FUJITSU_XA3530,
239 ALC883_3ST_6ch_INTEL,
252 #define GPIO_MASK 0x03
254 /* extra amp-initialization sequence types */
263 struct alc_mic_route {
265 unsigned char mux_idx;
266 unsigned char amix_idx;
269 #define MUX_IDX_UNDEF ((unsigned char)-1)
272 /* codec parameterization */
273 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
274 unsigned int num_mixers;
275 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
276 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
278 const struct hda_verb *init_verbs[10]; /* initialization verbs
282 unsigned int num_init_verbs;
284 char stream_name_analog[32]; /* analog PCM stream */
285 struct hda_pcm_stream *stream_analog_playback;
286 struct hda_pcm_stream *stream_analog_capture;
287 struct hda_pcm_stream *stream_analog_alt_playback;
288 struct hda_pcm_stream *stream_analog_alt_capture;
290 char stream_name_digital[32]; /* digital PCM stream */
291 struct hda_pcm_stream *stream_digital_playback;
292 struct hda_pcm_stream *stream_digital_capture;
295 struct hda_multi_out multiout; /* playback set-up
296 * max_channels, dacs must be set
297 * dig_out_nid and hp_nid are optional
299 hda_nid_t alt_dac_nid;
300 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
304 unsigned int num_adc_nids;
306 hda_nid_t *capsrc_nids;
307 hda_nid_t dig_in_nid; /* digital-in NID; optional */
310 unsigned int num_mux_defs;
311 const struct hda_input_mux *input_mux;
312 unsigned int cur_mux[3];
313 struct alc_mic_route ext_mic;
314 struct alc_mic_route int_mic;
317 const struct hda_channel_mode *channel_mode;
318 int num_channel_mode;
320 int const_channel_count;
321 int ext_channel_count;
323 /* PCM information */
324 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
326 /* dynamic controls, init_verbs and input_mux */
327 struct auto_pin_cfg autocfg;
328 struct snd_array kctls;
329 struct hda_input_mux private_imux[3];
330 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
331 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
332 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
335 void (*init_hook)(struct hda_codec *codec);
336 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
338 /* for pin sensing */
339 unsigned int sense_updated: 1;
340 unsigned int jack_present: 1;
341 unsigned int master_sw: 1;
342 unsigned int auto_mic:1;
345 unsigned int no_analog :1; /* digital I/O only */
348 /* for virtual master */
349 hda_nid_t vmaster_nid;
350 #ifdef CONFIG_SND_HDA_POWER_SAVE
351 struct hda_loopback_check loopback;
356 unsigned int pll_coef_idx, pll_coef_bit;
360 * configuration template - to be copied to the spec instance
362 struct alc_config_preset {
363 struct snd_kcontrol_new *mixers[5]; /* should be identical size
366 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
367 const struct hda_verb *init_verbs[5];
368 unsigned int num_dacs;
370 hda_nid_t dig_out_nid; /* optional */
371 hda_nid_t hp_nid; /* optional */
372 hda_nid_t *slave_dig_outs;
373 unsigned int num_adc_nids;
375 hda_nid_t *capsrc_nids;
376 hda_nid_t dig_in_nid;
377 unsigned int num_channel_mode;
378 const struct hda_channel_mode *channel_mode;
380 int const_channel_count;
381 unsigned int num_mux_defs;
382 const struct hda_input_mux *input_mux;
383 void (*unsol_event)(struct hda_codec *, unsigned int);
384 void (*setup)(struct hda_codec *);
385 void (*init_hook)(struct hda_codec *);
386 #ifdef CONFIG_SND_HDA_POWER_SAVE
387 struct hda_amp_list *loopbacks;
395 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_info *uinfo)
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct alc_spec *spec = codec->spec;
400 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
401 if (mux_idx >= spec->num_mux_defs)
403 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
406 static int alc_mux_enum_get(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 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
413 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
417 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_value *ucontrol)
420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421 struct alc_spec *spec = codec->spec;
422 const struct hda_input_mux *imux;
423 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
424 unsigned int mux_idx;
425 hda_nid_t nid = spec->capsrc_nids ?
426 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
429 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
430 imux = &spec->input_mux[mux_idx];
432 type = get_wcaps_type(get_wcaps(codec, nid));
433 if (type == AC_WID_AUD_MIX) {
434 /* Matrix-mixer style (e.g. ALC882) */
435 unsigned int *cur_val = &spec->cur_mux[adc_idx];
438 idx = ucontrol->value.enumerated.item[0];
439 if (idx >= imux->num_items)
440 idx = imux->num_items - 1;
443 for (i = 0; i < imux->num_items; i++) {
444 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
445 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
446 imux->items[i].index,
452 /* MUX style (e.g. ALC880) */
453 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
454 &spec->cur_mux[adc_idx]);
459 * channel mode setting
461 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
462 struct snd_ctl_elem_info *uinfo)
464 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
465 struct alc_spec *spec = codec->spec;
466 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
467 spec->num_channel_mode);
470 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
475 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
476 spec->num_channel_mode,
477 spec->ext_channel_count);
480 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
481 struct snd_ctl_elem_value *ucontrol)
483 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
484 struct alc_spec *spec = codec->spec;
485 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
486 spec->num_channel_mode,
487 &spec->ext_channel_count);
488 if (err >= 0 && !spec->const_channel_count) {
489 spec->multiout.max_channels = spec->ext_channel_count;
490 if (spec->need_dac_fix)
491 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
497 * Control the mode of pin widget settings via the mixer. "pc" is used
498 * instead of "%" to avoid consequences of accidently treating the % as
499 * being part of a format specifier. Maximum allowed length of a value is
500 * 63 characters plus NULL terminator.
502 * Note: some retasking pin complexes seem to ignore requests for input
503 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
504 * are requested. Therefore order this list so that this behaviour will not
505 * cause problems when mixer clients move through the enum sequentially.
506 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
509 static char *alc_pin_mode_names[] = {
510 "Mic 50pc bias", "Mic 80pc bias",
511 "Line in", "Line out", "Headphone out",
513 static unsigned char alc_pin_mode_values[] = {
514 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
516 /* The control can present all 5 options, or it can limit the options based
517 * in the pin being assumed to be exclusively an input or an output pin. In
518 * addition, "input" pins may or may not process the mic bias option
519 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
520 * accept requests for bias as of chip versions up to March 2006) and/or
521 * wiring in the computer.
523 #define ALC_PIN_DIR_IN 0x00
524 #define ALC_PIN_DIR_OUT 0x01
525 #define ALC_PIN_DIR_INOUT 0x02
526 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
527 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
529 /* Info about the pin modes supported by the different pin direction modes.
530 * For each direction the minimum and maximum values are given.
532 static signed char alc_pin_mode_dir_info[5][2] = {
533 { 0, 2 }, /* ALC_PIN_DIR_IN */
534 { 3, 4 }, /* ALC_PIN_DIR_OUT */
535 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
536 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
537 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
539 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
540 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
541 #define alc_pin_mode_n_items(_dir) \
542 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
544 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_info *uinfo)
547 unsigned int item_num = uinfo->value.enumerated.item;
548 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
550 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
552 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
554 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
555 item_num = alc_pin_mode_min(dir);
556 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
560 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 hda_nid_t nid = kcontrol->private_value & 0xffff;
566 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
567 long *valp = ucontrol->value.integer.value;
568 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
569 AC_VERB_GET_PIN_WIDGET_CONTROL,
572 /* Find enumerated value for current pinctl setting */
573 i = alc_pin_mode_min(dir);
574 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
576 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
580 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
588 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_PIN_WIDGET_CONTROL,
592 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
593 val = alc_pin_mode_min(dir);
595 change = pinctl != alc_pin_mode_values[val];
597 /* Set pin mode to that requested */
598 snd_hda_codec_write_cache(codec, nid, 0,
599 AC_VERB_SET_PIN_WIDGET_CONTROL,
600 alc_pin_mode_values[val]);
602 /* Also enable the retasking pin's input/output as required
603 * for the requested pin mode. Enum values of 2 or less are
606 * Dynamically switching the input/output buffers probably
607 * reduces noise slightly (particularly on input) so we'll
608 * do it. However, having both input and output buffers
609 * enabled simultaneously doesn't seem to be problematic if
610 * this turns out to be necessary in the future.
613 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
614 HDA_AMP_MUTE, HDA_AMP_MUTE);
615 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
618 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
619 HDA_AMP_MUTE, HDA_AMP_MUTE);
620 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
627 #define ALC_PIN_MODE(xname, nid, dir) \
628 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
629 .info = alc_pin_mode_info, \
630 .get = alc_pin_mode_get, \
631 .put = alc_pin_mode_put, \
632 .private_value = nid | (dir<<16) }
634 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
635 * together using a mask with more than one bit set. This control is
636 * currently used only by the ALC260 test model. At this stage they are not
637 * needed for any "production" models.
639 #ifdef CONFIG_SND_DEBUG
640 #define alc_gpio_data_info snd_ctl_boolean_mono_info
642 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 hda_nid_t nid = kcontrol->private_value & 0xffff;
647 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
648 long *valp = ucontrol->value.integer.value;
649 unsigned int val = snd_hda_codec_read(codec, nid, 0,
650 AC_VERB_GET_GPIO_DATA, 0x00);
652 *valp = (val & mask) != 0;
655 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
656 struct snd_ctl_elem_value *ucontrol)
659 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
660 hda_nid_t nid = kcontrol->private_value & 0xffff;
661 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
662 long val = *ucontrol->value.integer.value;
663 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
664 AC_VERB_GET_GPIO_DATA,
667 /* Set/unset the masked GPIO bit(s) as needed */
668 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
673 snd_hda_codec_write_cache(codec, nid, 0,
674 AC_VERB_SET_GPIO_DATA, gpio_data);
678 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
679 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
680 .info = alc_gpio_data_info, \
681 .get = alc_gpio_data_get, \
682 .put = alc_gpio_data_put, \
683 .private_value = nid | (mask<<16) }
684 #endif /* CONFIG_SND_DEBUG */
686 /* A switch control to allow the enabling of the digital IO pins on the
687 * ALC260. This is incredibly simplistic; the intention of this control is
688 * to provide something in the test model allowing digital outputs to be
689 * identified if present. If models are found which can utilise these
690 * outputs a more complete mixer control can be devised for those models if
693 #ifdef CONFIG_SND_DEBUG
694 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
696 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
697 struct snd_ctl_elem_value *ucontrol)
699 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
700 hda_nid_t nid = kcontrol->private_value & 0xffff;
701 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
702 long *valp = ucontrol->value.integer.value;
703 unsigned int val = snd_hda_codec_read(codec, nid, 0,
704 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
706 *valp = (val & mask) != 0;
709 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
710 struct snd_ctl_elem_value *ucontrol)
713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
714 hda_nid_t nid = kcontrol->private_value & 0xffff;
715 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
716 long val = *ucontrol->value.integer.value;
717 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
718 AC_VERB_GET_DIGI_CONVERT_1,
721 /* Set/unset the masked control bit(s) as needed */
722 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
727 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
732 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
733 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
734 .info = alc_spdif_ctrl_info, \
735 .get = alc_spdif_ctrl_get, \
736 .put = alc_spdif_ctrl_put, \
737 .private_value = nid | (mask<<16) }
738 #endif /* CONFIG_SND_DEBUG */
740 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
741 * Again, this is only used in the ALC26x test models to help identify when
742 * the EAPD line must be asserted for features to work.
744 #ifdef CONFIG_SND_DEBUG
745 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
747 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
748 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 *valp = ucontrol->value.integer.value;
754 unsigned int val = snd_hda_codec_read(codec, nid, 0,
755 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
757 *valp = (val & mask) != 0;
761 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
762 struct snd_ctl_elem_value *ucontrol)
765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
766 hda_nid_t nid = kcontrol->private_value & 0xffff;
767 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
768 long val = *ucontrol->value.integer.value;
769 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
770 AC_VERB_GET_EAPD_BTLENABLE,
773 /* Set/unset the masked control bit(s) as needed */
774 change = (!val ? 0 : mask) != (ctrl_data & mask);
779 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
785 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
786 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
787 .info = alc_eapd_ctrl_info, \
788 .get = alc_eapd_ctrl_get, \
789 .put = alc_eapd_ctrl_put, \
790 .private_value = nid | (mask<<16) }
791 #endif /* CONFIG_SND_DEBUG */
794 * set up the input pin config (depending on the given auto-pin type)
796 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
799 unsigned int val = PIN_IN;
801 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
803 pincap = snd_hda_query_pin_caps(codec, nid);
804 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
805 if (pincap & AC_PINCAP_VREF_80)
807 else if (pincap & AC_PINCAP_VREF_50)
809 else if (pincap & AC_PINCAP_VREF_100)
811 else if (pincap & AC_PINCAP_VREF_GRD)
814 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
819 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
821 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
823 spec->mixers[spec->num_mixers++] = mix;
826 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
828 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
830 spec->init_verbs[spec->num_init_verbs++] = verb;
833 #ifdef CONFIG_PROC_FS
837 static void print_realtek_coef(struct snd_info_buffer *buffer,
838 struct hda_codec *codec, hda_nid_t nid)
844 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
845 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
846 coeff = snd_hda_codec_read(codec, nid, 0,
847 AC_VERB_GET_COEF_INDEX, 0);
848 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
851 #define print_realtek_coef NULL
855 * set up from the preset table
857 static void setup_preset(struct hda_codec *codec,
858 const struct alc_config_preset *preset)
860 struct alc_spec *spec = codec->spec;
863 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
864 add_mixer(spec, preset->mixers[i]);
865 spec->cap_mixer = preset->cap_mixer;
866 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
868 add_verb(spec, preset->init_verbs[i]);
870 spec->channel_mode = preset->channel_mode;
871 spec->num_channel_mode = preset->num_channel_mode;
872 spec->need_dac_fix = preset->need_dac_fix;
873 spec->const_channel_count = preset->const_channel_count;
875 if (preset->const_channel_count)
876 spec->multiout.max_channels = preset->const_channel_count;
878 spec->multiout.max_channels = spec->channel_mode[0].channels;
879 spec->ext_channel_count = spec->channel_mode[0].channels;
881 spec->multiout.num_dacs = preset->num_dacs;
882 spec->multiout.dac_nids = preset->dac_nids;
883 spec->multiout.dig_out_nid = preset->dig_out_nid;
884 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
885 spec->multiout.hp_nid = preset->hp_nid;
887 spec->num_mux_defs = preset->num_mux_defs;
888 if (!spec->num_mux_defs)
889 spec->num_mux_defs = 1;
890 spec->input_mux = preset->input_mux;
892 spec->num_adc_nids = preset->num_adc_nids;
893 spec->adc_nids = preset->adc_nids;
894 spec->capsrc_nids = preset->capsrc_nids;
895 spec->dig_in_nid = preset->dig_in_nid;
897 spec->unsol_event = preset->unsol_event;
898 spec->init_hook = preset->init_hook;
899 #ifdef CONFIG_SND_HDA_POWER_SAVE
900 spec->loopback.amplist = preset->loopbacks;
904 preset->setup(codec);
907 /* Enable GPIO mask and set output */
908 static struct hda_verb alc_gpio1_init_verbs[] = {
909 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
910 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
911 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
915 static struct hda_verb alc_gpio2_init_verbs[] = {
916 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
917 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
918 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
922 static struct hda_verb alc_gpio3_init_verbs[] = {
923 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
924 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
925 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
930 * Fix hardware PLL issue
931 * On some codecs, the analog PLL gating control must be off while
932 * the default value is 1.
934 static void alc_fix_pll(struct hda_codec *codec)
936 struct alc_spec *spec = codec->spec;
941 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
943 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
944 AC_VERB_GET_PROC_COEF, 0);
945 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
947 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
948 val & ~(1 << spec->pll_coef_bit));
951 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
952 unsigned int coef_idx, unsigned int coef_bit)
954 struct alc_spec *spec = codec->spec;
956 spec->pll_coef_idx = coef_idx;
957 spec->pll_coef_bit = coef_bit;
961 static void alc_automute_pin(struct hda_codec *codec)
963 struct alc_spec *spec = codec->spec;
964 unsigned int nid = spec->autocfg.hp_pins[0];
969 spec->jack_present = snd_hda_jack_detect(codec, nid);
970 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
971 nid = spec->autocfg.speaker_pins[i];
974 snd_hda_codec_write(codec, nid, 0,
975 AC_VERB_SET_PIN_WIDGET_CONTROL,
976 spec->jack_present ? 0 : PIN_OUT);
980 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
983 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
986 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
987 for (i = 0; i < nums; i++)
993 static void alc_mic_automute(struct hda_codec *codec)
995 struct alc_spec *spec = codec->spec;
996 struct alc_mic_route *dead, *alive;
997 unsigned int present, type;
1000 if (!spec->auto_mic)
1002 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1004 if (snd_BUG_ON(!spec->adc_nids))
1007 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1009 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1011 alive = &spec->ext_mic;
1012 dead = &spec->int_mic;
1014 alive = &spec->int_mic;
1015 dead = &spec->ext_mic;
1018 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1019 if (type == AC_WID_AUD_MIX) {
1020 /* Matrix-mixer style (e.g. ALC882) */
1021 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1024 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1026 HDA_AMP_MUTE, HDA_AMP_MUTE);
1028 /* MUX style (e.g. ALC880) */
1029 snd_hda_codec_write_cache(codec, cap_nid, 0,
1030 AC_VERB_SET_CONNECT_SEL,
1034 /* FIXME: analog mixer */
1037 /* unsolicited event for HP jack sensing */
1038 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1040 if (codec->vendor_id == 0x10ec0880)
1045 case ALC880_HP_EVENT:
1046 alc_automute_pin(codec);
1048 case ALC880_MIC_EVENT:
1049 alc_mic_automute(codec);
1054 static void alc_inithook(struct hda_codec *codec)
1056 alc_automute_pin(codec);
1057 alc_mic_automute(codec);
1060 /* additional initialization for ALC888 variants */
1061 static void alc888_coef_init(struct hda_codec *codec)
1065 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1066 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1067 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1068 if ((tmp & 0xf0) == 0x20)
1070 snd_hda_codec_read(codec, 0x20, 0,
1071 AC_VERB_SET_PROC_COEF, 0x830);
1074 snd_hda_codec_read(codec, 0x20, 0,
1075 AC_VERB_SET_PROC_COEF, 0x3030);
1078 static void alc889_coef_init(struct hda_codec *codec)
1082 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1083 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1084 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1085 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1088 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1093 case ALC_INIT_GPIO1:
1094 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1096 case ALC_INIT_GPIO2:
1097 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1099 case ALC_INIT_GPIO3:
1100 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1102 case ALC_INIT_DEFAULT:
1103 switch (codec->vendor_id) {
1105 snd_hda_codec_write(codec, 0x0f, 0,
1106 AC_VERB_SET_EAPD_BTLENABLE, 2);
1107 snd_hda_codec_write(codec, 0x10, 0,
1108 AC_VERB_SET_EAPD_BTLENABLE, 2);
1120 snd_hda_codec_write(codec, 0x14, 0,
1121 AC_VERB_SET_EAPD_BTLENABLE, 2);
1122 snd_hda_codec_write(codec, 0x15, 0,
1123 AC_VERB_SET_EAPD_BTLENABLE, 2);
1126 switch (codec->vendor_id) {
1128 snd_hda_codec_write(codec, 0x1a, 0,
1129 AC_VERB_SET_COEF_INDEX, 7);
1130 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1131 AC_VERB_GET_PROC_COEF, 0);
1132 snd_hda_codec_write(codec, 0x1a, 0,
1133 AC_VERB_SET_COEF_INDEX, 7);
1134 snd_hda_codec_write(codec, 0x1a, 0,
1135 AC_VERB_SET_PROC_COEF,
1145 alc889_coef_init(codec);
1148 alc888_coef_init(codec);
1152 snd_hda_codec_write(codec, 0x20, 0,
1153 AC_VERB_SET_COEF_INDEX, 7);
1154 tmp = snd_hda_codec_read(codec, 0x20, 0,
1155 AC_VERB_GET_PROC_COEF, 0);
1156 snd_hda_codec_write(codec, 0x20, 0,
1157 AC_VERB_SET_COEF_INDEX, 7);
1158 snd_hda_codec_write(codec, 0x20, 0,
1159 AC_VERB_SET_PROC_COEF,
1167 static void alc_init_auto_hp(struct hda_codec *codec)
1169 struct alc_spec *spec = codec->spec;
1171 if (!spec->autocfg.hp_pins[0])
1174 if (!spec->autocfg.speaker_pins[0]) {
1175 if (spec->autocfg.line_out_pins[0] &&
1176 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1177 spec->autocfg.speaker_pins[0] =
1178 spec->autocfg.line_out_pins[0];
1183 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1184 spec->autocfg.hp_pins[0]);
1185 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1186 AC_VERB_SET_UNSOLICITED_ENABLE,
1187 AC_USRSP_EN | ALC880_HP_EVENT);
1188 spec->unsol_event = alc_sku_unsol_event;
1191 static void alc_init_auto_mic(struct hda_codec *codec)
1193 struct alc_spec *spec = codec->spec;
1194 struct auto_pin_cfg *cfg = &spec->autocfg;
1195 hda_nid_t fixed, ext;
1198 /* there must be only two mic inputs exclusively */
1199 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1200 if (cfg->input_pins[i])
1204 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1205 hda_nid_t nid = cfg->input_pins[i];
1206 unsigned int defcfg;
1209 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1210 switch (get_defcfg_connect(defcfg)) {
1211 case AC_JACK_PORT_FIXED:
1213 return; /* already occupied */
1216 case AC_JACK_PORT_COMPLEX:
1218 return; /* already occupied */
1222 return; /* invalid entry */
1225 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1226 return; /* no unsol support */
1227 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1229 spec->ext_mic.pin = ext;
1230 spec->int_mic.pin = fixed;
1231 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1232 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1234 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1235 AC_VERB_SET_UNSOLICITED_ENABLE,
1236 AC_USRSP_EN | ALC880_MIC_EVENT);
1237 spec->unsol_event = alc_sku_unsol_event;
1240 /* check subsystem ID and set up device-specific initialization;
1241 * return 1 if initialized, 0 if invalid SSID
1243 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1244 * 31 ~ 16 : Manufacture ID
1246 * 7 ~ 0 : Assembly ID
1247 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1249 static int alc_subsystem_id(struct hda_codec *codec,
1250 hda_nid_t porta, hda_nid_t porte,
1253 unsigned int ass, tmp, i;
1255 struct alc_spec *spec = codec->spec;
1257 ass = codec->subsystem_id & 0xffff;
1258 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1261 /* invalid SSID, check the special NID pin defcfg instead */
1263 * 31~30 : port connectivity
1266 * 19~16 : Check sum (15:1)
1271 if (codec->vendor_id == 0x10ec0260)
1273 ass = snd_hda_codec_get_pincfg(codec, nid);
1274 snd_printd("realtek: No valid SSID, "
1275 "checking pincfg 0x%08x for NID 0x%x\n",
1277 if (!(ass & 1) && !(ass & 0x100000))
1279 if ((ass >> 30) != 1) /* no physical connection */
1284 for (i = 1; i < 16; i++) {
1288 if (((ass >> 16) & 0xf) != tmp)
1291 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1292 ass & 0xffff, codec->vendor_id);
1296 * 2 : 0 --> Desktop, 1 --> Laptop
1297 * 3~5 : External Amplifier control
1300 tmp = (ass & 0x38) >> 3; /* external Amp control */
1303 spec->init_amp = ALC_INIT_GPIO1;
1306 spec->init_amp = ALC_INIT_GPIO2;
1309 spec->init_amp = ALC_INIT_GPIO3;
1312 spec->init_amp = ALC_INIT_DEFAULT;
1316 /* is laptop or Desktop and enable the function "Mute internal speaker
1317 * when the external headphone out jack is plugged"
1319 if (!(ass & 0x8000))
1322 * 10~8 : Jack location
1323 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1325 * 15 : 1 --> enable the function "Mute internal speaker
1326 * when the external headphone out jack is plugged"
1328 if (!spec->autocfg.hp_pins[0]) {
1330 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1339 for (i = 0; i < spec->autocfg.line_outs; i++)
1340 if (spec->autocfg.line_out_pins[i] == nid)
1342 spec->autocfg.hp_pins[0] = nid;
1345 alc_init_auto_hp(codec);
1346 alc_init_auto_mic(codec);
1350 static void alc_ssid_check(struct hda_codec *codec,
1351 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1353 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1354 struct alc_spec *spec = codec->spec;
1355 snd_printd("realtek: "
1356 "Enable default setup for auto mode as fallback\n");
1357 spec->init_amp = ALC_INIT_DEFAULT;
1358 alc_init_auto_hp(codec);
1359 alc_init_auto_mic(codec);
1364 * Fix-up pin default configurations and add default verbs
1373 const struct alc_pincfg *pins;
1374 const struct hda_verb *verbs;
1377 static void alc_pick_fixup(struct hda_codec *codec,
1378 const struct snd_pci_quirk *quirk,
1379 const struct alc_fixup *fix)
1381 const struct alc_pincfg *cfg;
1383 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1387 fix += quirk->value;
1390 for (; cfg->nid; cfg++)
1391 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1394 add_verb(codec->spec, fix->verbs);
1404 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1405 /* Mic-in jack as mic in */
1406 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1407 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1408 /* Line-in jack as Line in */
1409 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1410 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1411 /* Line-Out as Front */
1412 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1419 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1420 /* Mic-in jack as mic in */
1421 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1422 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1423 /* Line-in jack as Surround */
1424 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1425 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1426 /* Line-Out as Front */
1427 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1434 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1435 /* Mic-in jack as CLFE */
1436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1438 /* Line-in jack as Surround */
1439 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1440 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1441 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1442 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1449 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1450 /* Mic-in jack as CLFE */
1451 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1452 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1453 /* Line-in jack as Surround */
1454 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1455 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1456 /* Line-Out as Side */
1457 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1461 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1462 { 2, alc888_4ST_ch2_intel_init },
1463 { 4, alc888_4ST_ch4_intel_init },
1464 { 6, alc888_4ST_ch6_intel_init },
1465 { 8, alc888_4ST_ch8_intel_init },
1469 * ALC888 Fujitsu Siemens Amillo xa3530
1472 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1473 /* Front Mic: set to PIN_IN (empty by default) */
1474 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1475 /* Connect Internal HP to Front */
1476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1478 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1479 /* Connect Bass HP to Front */
1480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1483 /* Connect Line-Out side jack (SPDIF) to Side */
1484 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1485 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1486 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1487 /* Connect Mic jack to CLFE */
1488 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1489 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1490 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1491 /* Connect Line-in jack to Surround */
1492 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1493 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1495 /* Connect HP out jack to Front */
1496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1499 /* Enable unsolicited event for HP jack and Line-out jack */
1500 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1501 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1505 static void alc_automute_amp(struct hda_codec *codec)
1507 struct alc_spec *spec = codec->spec;
1512 spec->jack_present = 0;
1513 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1514 nid = spec->autocfg.hp_pins[i];
1517 if (snd_hda_jack_detect(codec, nid)) {
1518 spec->jack_present = 1;
1523 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1524 /* Toggle internal speakers muting */
1525 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1526 nid = spec->autocfg.speaker_pins[i];
1529 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1530 HDA_AMP_MUTE, mute);
1534 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1537 if (codec->vendor_id == 0x10ec0880)
1541 if (res == ALC880_HP_EVENT)
1542 alc_automute_amp(codec);
1545 static void alc889_automute_setup(struct hda_codec *codec)
1547 struct alc_spec *spec = codec->spec;
1549 spec->autocfg.hp_pins[0] = 0x15;
1550 spec->autocfg.speaker_pins[0] = 0x14;
1551 spec->autocfg.speaker_pins[1] = 0x16;
1552 spec->autocfg.speaker_pins[2] = 0x17;
1553 spec->autocfg.speaker_pins[3] = 0x19;
1554 spec->autocfg.speaker_pins[4] = 0x1a;
1557 static void alc889_intel_init_hook(struct hda_codec *codec)
1559 alc889_coef_init(codec);
1560 alc_automute_amp(codec);
1563 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1565 struct alc_spec *spec = codec->spec;
1567 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1568 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1569 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1570 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1574 * ALC888 Acer Aspire 4930G model
1577 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1578 /* Front Mic: set to PIN_IN (empty by default) */
1579 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1580 /* Unselect Front Mic by default in input mixer 3 */
1581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1582 /* Enable unsolicited event for HP jack */
1583 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1584 /* Connect Internal HP to front */
1585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1588 /* Connect HP out to front */
1589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1596 * ALC888 Acer Aspire 6530G model
1599 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1600 /* Bias voltage on for external mic port */
1601 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1602 /* Front Mic: set to PIN_IN (empty by default) */
1603 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1604 /* Unselect Front Mic by default in input mixer 3 */
1605 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1606 /* Enable unsolicited event for HP jack */
1607 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1608 /* Enable speaker output */
1609 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1610 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1611 /* Enable headphone output */
1612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1614 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1619 * ALC889 Acer Aspire 8930G model
1622 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1623 /* Front Mic: set to PIN_IN (empty by default) */
1624 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1625 /* Unselect Front Mic by default in input mixer 3 */
1626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1627 /* Enable unsolicited event for HP jack */
1628 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1629 /* Connect Internal Front to Front */
1630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1631 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1632 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1633 /* Connect Internal Rear to Rear */
1634 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1635 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1636 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1637 /* Connect Internal CLFE to CLFE */
1638 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1640 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1641 /* Connect HP out to Front */
1642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1645 /* Enable all DACs */
1646 /* DAC DISABLE/MUTE 1? */
1647 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1648 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1649 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1650 /* DAC DISABLE/MUTE 2? */
1651 /* some bit here disables the other DACs. Init=0x4900 */
1652 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1653 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1654 /* Enable amplifiers */
1655 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1656 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1658 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1659 * which makes the stereo useless. However, either the mic or the ALC889
1660 * makes the signal become a difference/sum signal instead of standard
1661 * stereo, which is annoying. So instead we flip this bit which makes the
1662 * codec replicate the sum signal to both channels, turning it into a
1665 /* DMIC_CONTROL? Init value = 0x0001 */
1666 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1667 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1671 static struct hda_input_mux alc888_2_capture_sources[2] = {
1672 /* Front mic only available on one ADC */
1679 { "Front Mic", 0xb },
1692 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1693 /* Interal mic only available on one ADC */
1700 { "Input Mix", 0xa },
1710 { "Input Mix", 0xa },
1715 static struct hda_input_mux alc889_capture_sources[3] = {
1716 /* Digital mic only available on first "ADC" */
1723 { "Front Mic", 0xb },
1724 { "Input Mix", 0xa },
1733 { "Input Mix", 0xa },
1742 { "Input Mix", 0xa },
1747 static struct snd_kcontrol_new alc888_base_mixer[] = {
1748 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1749 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1750 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1751 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1752 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1754 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1755 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1756 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1757 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1758 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1759 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1760 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1761 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1762 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1764 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1769 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1771 struct alc_spec *spec = codec->spec;
1773 spec->autocfg.hp_pins[0] = 0x15;
1774 spec->autocfg.speaker_pins[0] = 0x14;
1777 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1779 struct alc_spec *spec = codec->spec;
1781 spec->autocfg.hp_pins[0] = 0x15;
1782 spec->autocfg.speaker_pins[0] = 0x14;
1783 spec->autocfg.speaker_pins[1] = 0x16;
1784 spec->autocfg.speaker_pins[2] = 0x17;
1787 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1789 struct alc_spec *spec = codec->spec;
1791 spec->autocfg.hp_pins[0] = 0x15;
1792 spec->autocfg.speaker_pins[0] = 0x14;
1793 spec->autocfg.speaker_pins[1] = 0x16;
1794 spec->autocfg.speaker_pins[2] = 0x1b;
1798 * ALC880 3-stack model
1800 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1801 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1802 * F-Mic = 0x1b, HP = 0x19
1805 static hda_nid_t alc880_dac_nids[4] = {
1806 /* front, rear, clfe, rear_surr */
1807 0x02, 0x05, 0x04, 0x03
1810 static hda_nid_t alc880_adc_nids[3] = {
1815 /* The datasheet says the node 0x07 is connected from inputs,
1816 * but it shows zero connection in the real implementation on some devices.
1817 * Note: this is a 915GAV bug, fixed on 915GLV
1819 static hda_nid_t alc880_adc_nids_alt[2] = {
1824 #define ALC880_DIGOUT_NID 0x06
1825 #define ALC880_DIGIN_NID 0x0a
1827 static struct hda_input_mux alc880_capture_source = {
1831 { "Front Mic", 0x3 },
1837 /* channel source setting (2/6 channel selection for 3-stack) */
1839 static struct hda_verb alc880_threestack_ch2_init[] = {
1840 /* set line-in to input, mute it */
1841 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1842 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1843 /* set mic-in to input vref 80%, mute it */
1844 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1845 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1850 static struct hda_verb alc880_threestack_ch6_init[] = {
1851 /* set line-in to output, unmute it */
1852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1854 /* set mic-in to output, unmute it */
1855 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1856 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1860 static struct hda_channel_mode alc880_threestack_modes[2] = {
1861 { 2, alc880_threestack_ch2_init },
1862 { 6, alc880_threestack_ch6_init },
1865 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1866 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1867 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1868 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1869 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1870 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1871 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1872 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1873 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1874 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1875 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1876 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1877 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1881 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1885 .name = "Channel Mode",
1886 .info = alc_ch_mode_info,
1887 .get = alc_ch_mode_get,
1888 .put = alc_ch_mode_put,
1893 /* capture mixer elements */
1894 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1895 struct snd_ctl_elem_info *uinfo)
1897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1898 struct alc_spec *spec = codec->spec;
1901 mutex_lock(&codec->control_mutex);
1902 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1904 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1905 mutex_unlock(&codec->control_mutex);
1909 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1910 unsigned int size, unsigned int __user *tlv)
1912 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1913 struct alc_spec *spec = codec->spec;
1916 mutex_lock(&codec->control_mutex);
1917 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1919 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1920 mutex_unlock(&codec->control_mutex);
1924 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1925 struct snd_ctl_elem_value *ucontrol);
1927 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1928 struct snd_ctl_elem_value *ucontrol,
1931 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1932 struct alc_spec *spec = codec->spec;
1933 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1936 mutex_lock(&codec->control_mutex);
1937 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1939 err = func(kcontrol, ucontrol);
1940 mutex_unlock(&codec->control_mutex);
1944 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1945 struct snd_ctl_elem_value *ucontrol)
1947 return alc_cap_getput_caller(kcontrol, ucontrol,
1948 snd_hda_mixer_amp_volume_get);
1951 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1952 struct snd_ctl_elem_value *ucontrol)
1954 return alc_cap_getput_caller(kcontrol, ucontrol,
1955 snd_hda_mixer_amp_volume_put);
1958 /* capture mixer elements */
1959 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1961 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1962 struct snd_ctl_elem_value *ucontrol)
1964 return alc_cap_getput_caller(kcontrol, ucontrol,
1965 snd_hda_mixer_amp_switch_get);
1968 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1969 struct snd_ctl_elem_value *ucontrol)
1971 return alc_cap_getput_caller(kcontrol, ucontrol,
1972 snd_hda_mixer_amp_switch_put);
1975 #define _DEFINE_CAPMIX(num) \
1977 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1978 .name = "Capture Switch", \
1979 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1981 .info = alc_cap_sw_info, \
1982 .get = alc_cap_sw_get, \
1983 .put = alc_cap_sw_put, \
1986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1987 .name = "Capture Volume", \
1988 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1989 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1990 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1992 .info = alc_cap_vol_info, \
1993 .get = alc_cap_vol_get, \
1994 .put = alc_cap_vol_put, \
1995 .tlv = { .c = alc_cap_vol_tlv }, \
1998 #define _DEFINE_CAPSRC(num) \
2000 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2001 /* .name = "Capture Source", */ \
2002 .name = "Input Source", \
2004 .info = alc_mux_enum_info, \
2005 .get = alc_mux_enum_get, \
2006 .put = alc_mux_enum_put, \
2009 #define DEFINE_CAPMIX(num) \
2010 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2011 _DEFINE_CAPMIX(num), \
2012 _DEFINE_CAPSRC(num), \
2016 #define DEFINE_CAPMIX_NOSRC(num) \
2017 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2018 _DEFINE_CAPMIX(num), \
2022 /* up to three ADCs */
2026 DEFINE_CAPMIX_NOSRC(1);
2027 DEFINE_CAPMIX_NOSRC(2);
2028 DEFINE_CAPMIX_NOSRC(3);
2031 * ALC880 5-stack model
2033 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2035 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2036 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2039 /* additional mixers to alc880_three_stack_mixer */
2040 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2041 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2042 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2046 /* channel source setting (6/8 channel selection for 5-stack) */
2048 static struct hda_verb alc880_fivestack_ch6_init[] = {
2049 /* set line-in to input, mute it */
2050 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2051 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2056 static struct hda_verb alc880_fivestack_ch8_init[] = {
2057 /* set line-in to output, unmute it */
2058 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2059 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2063 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2064 { 6, alc880_fivestack_ch6_init },
2065 { 8, alc880_fivestack_ch8_init },
2070 * ALC880 6-stack model
2072 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2073 * Side = 0x05 (0x0f)
2074 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2075 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2078 static hda_nid_t alc880_6st_dac_nids[4] = {
2079 /* front, rear, clfe, rear_surr */
2080 0x02, 0x03, 0x04, 0x05
2083 static struct hda_input_mux alc880_6stack_capture_source = {
2087 { "Front Mic", 0x1 },
2093 /* fixed 8-channels */
2094 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2098 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2107 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2109 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2110 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2119 .name = "Channel Mode",
2120 .info = alc_ch_mode_info,
2121 .get = alc_ch_mode_get,
2122 .put = alc_ch_mode_put,
2131 * W810 has rear IO for:
2134 * Center/LFE (DAC 04)
2137 * The system also has a pair of internal speakers, and a headphone jack.
2138 * These are both connected to Line2 on the codec, hence to DAC 02.
2140 * There is a variable resistor to control the speaker or headphone
2141 * volume. This is a hardware-only device without a software API.
2143 * Plugging headphones in will disable the internal speakers. This is
2144 * implemented in hardware, not via the driver using jack sense. In
2145 * a similar fashion, plugging into the rear socket marked "front" will
2146 * disable both the speakers and headphones.
2148 * For input, there's a microphone jack, and an "audio in" jack.
2149 * These may not do anything useful with this driver yet, because I
2150 * haven't setup any initialization verbs for these yet...
2153 static hda_nid_t alc880_w810_dac_nids[3] = {
2154 /* front, rear/surround, clfe */
2158 /* fixed 6 channels */
2159 static struct hda_channel_mode alc880_w810_modes[1] = {
2163 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2164 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2165 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2166 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2167 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2168 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2169 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2170 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2171 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2172 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2181 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2182 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2186 static hda_nid_t alc880_z71v_dac_nids[1] = {
2189 #define ALC880_Z71V_HP_DAC 0x03
2191 /* fixed 2 channels */
2192 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2196 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2197 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2198 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2200 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2201 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2202 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2203 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2204 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2210 * ALC880 F1734 model
2212 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2213 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2216 static hda_nid_t alc880_f1734_dac_nids[1] = {
2219 #define ALC880_F1734_HP_DAC 0x02
2221 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2222 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2225 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2226 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2227 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2233 static struct hda_input_mux alc880_f1734_capture_source = {
2245 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2246 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2247 * Mic = 0x18, Line = 0x1a
2250 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2251 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2253 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2255 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2257 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2258 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2259 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2260 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2261 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2270 .name = "Channel Mode",
2271 .info = alc_ch_mode_info,
2272 .get = alc_ch_mode_get,
2273 .put = alc_ch_mode_put,
2279 * ALC880 ASUS W1V model
2281 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2282 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2283 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2286 /* additional mixers to alc880_asus_mixer */
2287 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2288 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2289 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2294 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2296 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2299 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2302 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2303 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2308 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2309 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2310 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2311 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2312 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2313 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2314 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2315 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2316 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2317 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2318 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2319 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2320 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2322 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2323 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2326 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2327 .name = "Channel Mode",
2328 .info = alc_ch_mode_info,
2329 .get = alc_ch_mode_get,
2330 .put = alc_ch_mode_put,
2335 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2336 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2337 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2339 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2340 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2341 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2342 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2343 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2344 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2345 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2349 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2351 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2352 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2353 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2354 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2355 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2360 * virtual master controls
2364 * slave controls for virtual master
2366 static const char *alc_slave_vols[] = {
2367 "Front Playback Volume",
2368 "Surround Playback Volume",
2369 "Center Playback Volume",
2370 "LFE Playback Volume",
2371 "Side Playback Volume",
2372 "Headphone Playback Volume",
2373 "Speaker Playback Volume",
2374 "Mono Playback Volume",
2375 "Line-Out Playback Volume",
2376 "PCM Playback Volume",
2380 static const char *alc_slave_sws[] = {
2381 "Front Playback Switch",
2382 "Surround Playback Switch",
2383 "Center Playback Switch",
2384 "LFE Playback Switch",
2385 "Side Playback Switch",
2386 "Headphone Playback Switch",
2387 "Speaker Playback Switch",
2388 "Mono Playback Switch",
2389 "IEC958 Playback Switch",
2394 * build control elements
2397 static void alc_free_kctls(struct hda_codec *codec);
2399 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2400 /* additional beep mixers; the actual parameters are overwritten at build */
2401 static struct snd_kcontrol_new alc_beep_mixer[] = {
2402 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2403 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2408 static int alc_build_controls(struct hda_codec *codec)
2410 struct alc_spec *spec = codec->spec;
2414 for (i = 0; i < spec->num_mixers; i++) {
2415 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2419 if (spec->cap_mixer) {
2420 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2424 if (spec->multiout.dig_out_nid) {
2425 err = snd_hda_create_spdif_out_ctls(codec,
2426 spec->multiout.dig_out_nid);
2429 if (!spec->no_analog) {
2430 err = snd_hda_create_spdif_share_sw(codec,
2434 spec->multiout.share_spdif = 1;
2437 if (spec->dig_in_nid) {
2438 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2443 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2444 /* create beep controls if needed */
2445 if (spec->beep_amp) {
2446 struct snd_kcontrol_new *knew;
2447 for (knew = alc_beep_mixer; knew->name; knew++) {
2448 struct snd_kcontrol *kctl;
2449 kctl = snd_ctl_new1(knew, codec);
2452 kctl->private_value = spec->beep_amp;
2453 err = snd_hda_ctl_add(codec,
2454 get_amp_nid_(spec->beep_amp), kctl);
2461 /* if we have no master control, let's create it */
2462 if (!spec->no_analog &&
2463 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2464 unsigned int vmaster_tlv[4];
2465 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2466 HDA_OUTPUT, vmaster_tlv);
2467 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2468 vmaster_tlv, alc_slave_vols);
2472 if (!spec->no_analog &&
2473 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2474 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2475 NULL, alc_slave_sws);
2480 alc_free_kctls(codec); /* no longer needed */
2486 * initialize the codec volumes, etc
2490 * generic initialization of ADC, input mixers and output mixers
2492 static struct hda_verb alc880_volume_init_verbs[] = {
2494 * Unmute ADC0-2 and set the default input to mic-in
2496 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2498 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2499 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2500 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2501 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2503 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2505 * Note: PASD motherboards uses the Line In 2 as the input for front
2508 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2509 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2510 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2511 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2512 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2518 * Set up output mixers (0x0c - 0x0f)
2520 /* set vol=0 to output mixers */
2521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2522 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2524 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2525 /* set up input amps for analog loopback */
2526 /* Amp Indices: DAC = 0, mixer = 1 */
2527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2529 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2530 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2531 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2532 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2534 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2540 * 3-stack pin configuration:
2541 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2543 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2545 * preset connection lists of input pins
2546 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2548 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2549 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2550 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2553 * Set pin mode and muting
2555 /* set front pin widgets 0x14 for output */
2556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2557 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2558 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2561 /* Mic2 (as headphone out) for HP output */
2562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2564 /* Line In pin widget for input */
2565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2567 /* Line2 (as front mic) pin widget for input and vref at 80% */
2568 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2569 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2570 /* CD pin widget for input */
2571 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2577 * 5-stack pin configuration:
2578 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2579 * line-in/side = 0x1a, f-mic = 0x1b
2581 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2583 * preset connection lists of input pins
2584 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2586 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2587 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2590 * Set pin mode and muting
2592 /* set pin widgets 0x14-0x17 for output */
2593 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2595 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2596 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2597 /* unmute pins for output (no gain on this amp) */
2598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2599 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2600 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2601 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2603 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2604 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2605 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2606 /* Mic2 (as headphone out) for HP output */
2607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2608 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2609 /* Line In pin widget for input */
2610 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2611 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2612 /* Line2 (as front mic) pin widget for input and vref at 80% */
2613 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2614 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2615 /* CD pin widget for input */
2616 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2622 * W810 pin configuration:
2623 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2625 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2626 /* hphone/speaker input selector: front DAC */
2627 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2629 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2630 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2633 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2634 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2636 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2637 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2643 * Z71V pin configuration:
2644 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2646 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2652 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2653 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2654 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2655 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2661 * 6-stack pin configuration:
2662 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2663 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2665 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2666 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2669 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2670 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2672 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2673 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2674 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2675 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2677 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2678 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2679 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2680 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2681 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2682 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2683 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2684 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2685 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2691 * Uniwill pin configuration:
2692 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2695 static struct hda_verb alc880_uniwill_init_verbs[] = {
2696 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2698 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2699 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2702 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2703 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2704 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2705 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2710 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2713 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2714 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2717 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2718 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2719 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2720 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2721 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2723 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2724 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2731 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2733 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2734 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2738 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2740 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2741 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2749 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2751 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2752 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2753 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2756 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2757 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2762 static struct hda_verb alc880_beep_init_verbs[] = {
2763 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2767 /* auto-toggle front mic */
2768 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2770 unsigned int present;
2773 present = snd_hda_jack_detect(codec, 0x18);
2774 bits = present ? HDA_AMP_MUTE : 0;
2775 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2778 static void alc880_uniwill_setup(struct hda_codec *codec)
2780 struct alc_spec *spec = codec->spec;
2782 spec->autocfg.hp_pins[0] = 0x14;
2783 spec->autocfg.speaker_pins[0] = 0x15;
2784 spec->autocfg.speaker_pins[0] = 0x16;
2787 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2789 alc_automute_amp(codec);
2790 alc880_uniwill_mic_automute(codec);
2793 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2796 /* Looks like the unsol event is incompatible with the standard
2797 * definition. 4bit tag is placed at 28 bit!
2799 switch (res >> 28) {
2800 case ALC880_MIC_EVENT:
2801 alc880_uniwill_mic_automute(codec);
2804 alc_automute_amp_unsol_event(codec, res);
2809 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
2811 struct alc_spec *spec = codec->spec;
2813 spec->autocfg.hp_pins[0] = 0x14;
2814 spec->autocfg.speaker_pins[0] = 0x15;
2817 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2819 unsigned int present;
2821 present = snd_hda_codec_read(codec, 0x21, 0,
2822 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2823 present &= HDA_AMP_VOLMASK;
2824 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2825 HDA_AMP_VOLMASK, present);
2826 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2827 HDA_AMP_VOLMASK, present);
2830 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2833 /* Looks like the unsol event is incompatible with the standard
2834 * definition. 4bit tag is placed at 28 bit!
2836 if ((res >> 28) == ALC880_DCVOL_EVENT)
2837 alc880_uniwill_p53_dcvol_automute(codec);
2839 alc_automute_amp_unsol_event(codec, res);
2843 * F1734 pin configuration:
2844 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2846 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2847 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2848 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2849 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2850 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2851 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2858 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2860 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2862 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2864 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2865 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2866 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2868 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2869 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2875 * ASUS pin configuration:
2876 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2878 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2879 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2880 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2881 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2882 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2884 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2885 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2886 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2887 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2888 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2889 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2890 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2893 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2895 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2897 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2898 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2900 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2906 /* Enable GPIO mask and set output */
2907 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2908 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2909 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2911 /* Clevo m520g init */
2912 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2913 /* headphone output */
2914 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2917 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2922 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2923 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2924 /* Mic1 (rear panel) */
2925 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2926 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2927 /* Mic2 (front panel) */
2928 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2929 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2931 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2932 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2933 /* change to EAPD mode */
2934 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2935 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2940 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2941 /* change to EAPD mode */
2942 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2943 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2945 /* Headphone output */
2946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2948 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2949 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2951 /* Line In pin widget for input */
2952 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2953 /* CD pin widget for input */
2954 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2955 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2956 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2958 /* change to EAPD mode */
2959 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2960 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2966 * LG m1 express dual
2969 * Rear Line-In/Out (blue): 0x14
2970 * Build-in Mic-In: 0x15
2972 * HP-Out (green): 0x1b
2973 * Mic-In/Out (red): 0x19
2977 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2978 static hda_nid_t alc880_lg_dac_nids[3] = {
2982 /* seems analog CD is not working */
2983 static struct hda_input_mux alc880_lg_capture_source = {
2988 { "Internal Mic", 0x6 },
2992 /* 2,4,6 channel modes */
2993 static struct hda_verb alc880_lg_ch2_init[] = {
2994 /* set line-in and mic-in to input */
2995 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2996 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3000 static struct hda_verb alc880_lg_ch4_init[] = {
3001 /* set line-in to out and mic-in to input */
3002 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3003 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3007 static struct hda_verb alc880_lg_ch6_init[] = {
3008 /* set line-in and mic-in to output */
3009 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3010 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3014 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3015 { 2, alc880_lg_ch2_init },
3016 { 4, alc880_lg_ch4_init },
3017 { 6, alc880_lg_ch6_init },
3020 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3021 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3022 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3023 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3024 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3025 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3026 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3027 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3028 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3033 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3034 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3037 .name = "Channel Mode",
3038 .info = alc_ch_mode_info,
3039 .get = alc_ch_mode_get,
3040 .put = alc_ch_mode_put,
3045 static struct hda_verb alc880_lg_init_verbs[] = {
3046 /* set capture source to mic-in */
3047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3050 /* mute all amp mixer inputs */
3051 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3052 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3053 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3054 /* line-in to input */
3055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3059 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3061 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3062 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3063 /* mic-in to input */
3064 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3065 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3066 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3068 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3069 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3070 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3076 /* toggle speaker-output according to the hp-jack state */
3077 static void alc880_lg_setup(struct hda_codec *codec)
3079 struct alc_spec *spec = codec->spec;
3081 spec->autocfg.hp_pins[0] = 0x1b;
3082 spec->autocfg.speaker_pins[0] = 0x17;
3091 * Built-in Mic-In: 0x19
3097 static struct hda_input_mux alc880_lg_lw_capture_source = {
3101 { "Internal Mic", 0x1 },
3106 #define alc880_lg_lw_modes alc880_threestack_modes
3108 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3110 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3111 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3112 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3113 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3114 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3115 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3116 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3121 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3122 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3125 .name = "Channel Mode",
3126 .info = alc_ch_mode_info,
3127 .get = alc_ch_mode_get,
3128 .put = alc_ch_mode_put,
3133 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3134 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3135 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3136 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3138 /* set capture source to mic-in */
3139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3140 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3141 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3142 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3145 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3147 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3148 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3149 /* mic-in to input */
3150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3151 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3153 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3154 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3156 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3160 /* toggle speaker-output according to the hp-jack state */
3161 static void alc880_lg_lw_setup(struct hda_codec *codec)
3163 struct alc_spec *spec = codec->spec;
3165 spec->autocfg.hp_pins[0] = 0x1b;
3166 spec->autocfg.speaker_pins[0] = 0x14;
3169 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3170 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3171 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3173 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3174 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3175 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3179 static struct hda_input_mux alc880_medion_rim_capture_source = {
3183 { "Internal Mic", 0x1 },
3187 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3188 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3190 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3193 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3196 /* Mic2 (as headphone out) for HP output */
3197 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3199 /* Internal Speaker */
3200 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3201 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3203 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3204 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3206 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3210 /* toggle speaker-output according to the hp-jack state */
3211 static void alc880_medion_rim_automute(struct hda_codec *codec)
3213 struct alc_spec *spec = codec->spec;
3214 alc_automute_amp(codec);
3216 if (spec->jack_present)
3217 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3219 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3222 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3225 /* Looks like the unsol event is incompatible with the standard
3226 * definition. 4bit tag is placed at 28 bit!
3228 if ((res >> 28) == ALC880_HP_EVENT)
3229 alc880_medion_rim_automute(codec);
3232 static void alc880_medion_rim_setup(struct hda_codec *codec)
3234 struct alc_spec *spec = codec->spec;
3236 spec->autocfg.hp_pins[0] = 0x14;
3237 spec->autocfg.speaker_pins[0] = 0x1b;
3240 #ifdef CONFIG_SND_HDA_POWER_SAVE
3241 static struct hda_amp_list alc880_loopbacks[] = {
3242 { 0x0b, HDA_INPUT, 0 },
3243 { 0x0b, HDA_INPUT, 1 },
3244 { 0x0b, HDA_INPUT, 2 },
3245 { 0x0b, HDA_INPUT, 3 },
3246 { 0x0b, HDA_INPUT, 4 },
3250 static struct hda_amp_list alc880_lg_loopbacks[] = {
3251 { 0x0b, HDA_INPUT, 1 },
3252 { 0x0b, HDA_INPUT, 6 },
3253 { 0x0b, HDA_INPUT, 7 },
3262 static int alc_init(struct hda_codec *codec)
3264 struct alc_spec *spec = codec->spec;
3268 alc_auto_init_amp(codec, spec->init_amp);
3270 for (i = 0; i < spec->num_init_verbs; i++)
3271 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3273 if (spec->init_hook)
3274 spec->init_hook(codec);
3279 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3281 struct alc_spec *spec = codec->spec;
3283 if (spec->unsol_event)
3284 spec->unsol_event(codec, res);
3287 #ifdef CONFIG_SND_HDA_POWER_SAVE
3288 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3290 struct alc_spec *spec = codec->spec;
3291 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3296 * Analog playback callbacks
3298 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3299 struct hda_codec *codec,
3300 struct snd_pcm_substream *substream)
3302 struct alc_spec *spec = codec->spec;
3303 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3307 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3308 struct hda_codec *codec,
3309 unsigned int stream_tag,
3310 unsigned int format,
3311 struct snd_pcm_substream *substream)
3313 struct alc_spec *spec = codec->spec;
3314 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3315 stream_tag, format, substream);
3318 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3319 struct hda_codec *codec,
3320 struct snd_pcm_substream *substream)
3322 struct alc_spec *spec = codec->spec;
3323 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3329 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3330 struct hda_codec *codec,
3331 struct snd_pcm_substream *substream)
3333 struct alc_spec *spec = codec->spec;
3334 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3337 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3338 struct hda_codec *codec,
3339 unsigned int stream_tag,
3340 unsigned int format,
3341 struct snd_pcm_substream *substream)
3343 struct alc_spec *spec = codec->spec;
3344 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3345 stream_tag, format, substream);
3348 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3349 struct hda_codec *codec,
3350 struct snd_pcm_substream *substream)
3352 struct alc_spec *spec = codec->spec;
3353 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3356 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3357 struct hda_codec *codec,
3358 struct snd_pcm_substream *substream)
3360 struct alc_spec *spec = codec->spec;
3361 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3367 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3368 struct hda_codec *codec,
3369 unsigned int stream_tag,
3370 unsigned int format,
3371 struct snd_pcm_substream *substream)
3373 struct alc_spec *spec = codec->spec;
3375 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3376 stream_tag, 0, format);
3380 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3381 struct hda_codec *codec,
3382 struct snd_pcm_substream *substream)
3384 struct alc_spec *spec = codec->spec;
3386 snd_hda_codec_cleanup_stream(codec,
3387 spec->adc_nids[substream->number + 1]);
3394 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3398 /* NID is set in alc_build_pcms */
3400 .open = alc880_playback_pcm_open,
3401 .prepare = alc880_playback_pcm_prepare,
3402 .cleanup = alc880_playback_pcm_cleanup
3406 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3410 /* NID is set in alc_build_pcms */
3413 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3417 /* NID is set in alc_build_pcms */
3420 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3421 .substreams = 2, /* can be overridden */
3424 /* NID is set in alc_build_pcms */
3426 .prepare = alc880_alt_capture_pcm_prepare,
3427 .cleanup = alc880_alt_capture_pcm_cleanup
3431 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3435 /* NID is set in alc_build_pcms */
3437 .open = alc880_dig_playback_pcm_open,
3438 .close = alc880_dig_playback_pcm_close,
3439 .prepare = alc880_dig_playback_pcm_prepare,
3440 .cleanup = alc880_dig_playback_pcm_cleanup
3444 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3448 /* NID is set in alc_build_pcms */
3451 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3452 static struct hda_pcm_stream alc_pcm_null_stream = {
3458 static int alc_build_pcms(struct hda_codec *codec)
3460 struct alc_spec *spec = codec->spec;
3461 struct hda_pcm *info = spec->pcm_rec;
3464 codec->num_pcms = 1;
3465 codec->pcm_info = info;
3467 if (spec->no_analog)
3470 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3471 "%s Analog", codec->chip_name);
3472 info->name = spec->stream_name_analog;
3474 if (spec->stream_analog_playback) {
3475 if (snd_BUG_ON(!spec->multiout.dac_nids))
3477 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3478 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3480 if (spec->stream_analog_capture) {
3481 if (snd_BUG_ON(!spec->adc_nids))
3483 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3484 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3487 if (spec->channel_mode) {
3488 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3489 for (i = 0; i < spec->num_channel_mode; i++) {
3490 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3491 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3497 /* SPDIF for stream index #1 */
3498 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3499 snprintf(spec->stream_name_digital,
3500 sizeof(spec->stream_name_digital),
3501 "%s Digital", codec->chip_name);
3502 codec->num_pcms = 2;
3503 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3504 info = spec->pcm_rec + 1;
3505 info->name = spec->stream_name_digital;
3506 if (spec->dig_out_type)
3507 info->pcm_type = spec->dig_out_type;
3509 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3510 if (spec->multiout.dig_out_nid &&
3511 spec->stream_digital_playback) {
3512 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3513 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3515 if (spec->dig_in_nid &&
3516 spec->stream_digital_capture) {
3517 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3518 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3520 /* FIXME: do we need this for all Realtek codec models? */
3521 codec->spdif_status_reset = 1;
3524 if (spec->no_analog)
3527 /* If the use of more than one ADC is requested for the current
3528 * model, configure a second analog capture-only PCM.
3530 /* Additional Analaog capture for index #2 */
3531 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3532 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3533 codec->num_pcms = 3;
3534 info = spec->pcm_rec + 2;
3535 info->name = spec->stream_name_analog;
3536 if (spec->alt_dac_nid) {
3537 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3538 *spec->stream_analog_alt_playback;
3539 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3542 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3543 alc_pcm_null_stream;
3544 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3546 if (spec->num_adc_nids > 1) {
3547 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3548 *spec->stream_analog_alt_capture;
3549 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3551 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3552 spec->num_adc_nids - 1;
3554 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3555 alc_pcm_null_stream;
3556 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3563 static void alc_free_kctls(struct hda_codec *codec)
3565 struct alc_spec *spec = codec->spec;
3567 if (spec->kctls.list) {
3568 struct snd_kcontrol_new *kctl = spec->kctls.list;
3570 for (i = 0; i < spec->kctls.used; i++)
3571 kfree(kctl[i].name);
3573 snd_array_free(&spec->kctls);
3576 static void alc_free(struct hda_codec *codec)
3578 struct alc_spec *spec = codec->spec;
3583 alc_free_kctls(codec);
3585 snd_hda_detach_beep_device(codec);
3588 #ifdef SND_HDA_NEEDS_RESUME
3589 static int alc_resume(struct hda_codec *codec)
3591 codec->patch_ops.init(codec);
3592 snd_hda_codec_resume_amp(codec);
3593 snd_hda_codec_resume_cache(codec);
3600 static struct hda_codec_ops alc_patch_ops = {
3601 .build_controls = alc_build_controls,
3602 .build_pcms = alc_build_pcms,
3605 .unsol_event = alc_unsol_event,
3606 #ifdef SND_HDA_NEEDS_RESUME
3607 .resume = alc_resume,
3609 #ifdef CONFIG_SND_HDA_POWER_SAVE
3610 .check_power_status = alc_check_power_status,
3616 * Test configuration for debugging
3618 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3621 #ifdef CONFIG_SND_DEBUG
3622 static hda_nid_t alc880_test_dac_nids[4] = {
3623 0x02, 0x03, 0x04, 0x05
3626 static struct hda_input_mux alc880_test_capture_source = {
3635 { "Surround", 0x6 },
3639 static struct hda_channel_mode alc880_test_modes[4] = {
3646 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3647 struct snd_ctl_elem_info *uinfo)
3649 static char *texts[] = {
3650 "N/A", "Line Out", "HP Out",
3651 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3653 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3655 uinfo->value.enumerated.items = 8;
3656 if (uinfo->value.enumerated.item >= 8)
3657 uinfo->value.enumerated.item = 7;
3658 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3662 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3663 struct snd_ctl_elem_value *ucontrol)
3665 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3666 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3667 unsigned int pin_ctl, item = 0;
3669 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3670 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3671 if (pin_ctl & AC_PINCTL_OUT_EN) {
3672 if (pin_ctl & AC_PINCTL_HP_EN)
3676 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3677 switch (pin_ctl & AC_PINCTL_VREFEN) {
3678 case AC_PINCTL_VREF_HIZ: item = 3; break;
3679 case AC_PINCTL_VREF_50: item = 4; break;
3680 case AC_PINCTL_VREF_GRD: item = 5; break;
3681 case AC_PINCTL_VREF_80: item = 6; break;
3682 case AC_PINCTL_VREF_100: item = 7; break;
3685 ucontrol->value.enumerated.item[0] = item;
3689 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3690 struct snd_ctl_elem_value *ucontrol)
3692 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3693 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3694 static unsigned int ctls[] = {
3695 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3696 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3697 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3698 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3699 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3700 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3702 unsigned int old_ctl, new_ctl;
3704 old_ctl = snd_hda_codec_read(codec, nid, 0,
3705 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3706 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3707 if (old_ctl != new_ctl) {
3709 snd_hda_codec_write_cache(codec, nid, 0,
3710 AC_VERB_SET_PIN_WIDGET_CONTROL,
3712 val = ucontrol->value.enumerated.item[0] >= 3 ?
3714 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3721 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3722 struct snd_ctl_elem_info *uinfo)
3724 static char *texts[] = {
3725 "Front", "Surround", "CLFE", "Side"
3727 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3729 uinfo->value.enumerated.items = 4;
3730 if (uinfo->value.enumerated.item >= 4)
3731 uinfo->value.enumerated.item = 3;
3732 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3736 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3737 struct snd_ctl_elem_value *ucontrol)
3739 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3740 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3743 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3744 ucontrol->value.enumerated.item[0] = sel & 3;
3748 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3749 struct snd_ctl_elem_value *ucontrol)
3751 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3752 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3755 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3756 if (ucontrol->value.enumerated.item[0] != sel) {
3757 sel = ucontrol->value.enumerated.item[0] & 3;
3758 snd_hda_codec_write_cache(codec, nid, 0,
3759 AC_VERB_SET_CONNECT_SEL, sel);
3765 #define PIN_CTL_TEST(xname,nid) { \
3766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3768 .info = alc_test_pin_ctl_info, \
3769 .get = alc_test_pin_ctl_get, \
3770 .put = alc_test_pin_ctl_put, \
3771 .private_value = nid \
3774 #define PIN_SRC_TEST(xname,nid) { \
3775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3777 .info = alc_test_pin_src_info, \
3778 .get = alc_test_pin_src_get, \
3779 .put = alc_test_pin_src_put, \
3780 .private_value = nid \
3783 static struct snd_kcontrol_new alc880_test_mixer[] = {
3784 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3785 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3786 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3787 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3788 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3789 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3790 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3791 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3792 PIN_CTL_TEST("Front Pin Mode", 0x14),
3793 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3794 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3795 PIN_CTL_TEST("Side Pin Mode", 0x17),
3796 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3797 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3798 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3799 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3800 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3801 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3802 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3803 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3804 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3805 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3806 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3807 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3808 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3809 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3810 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3811 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3816 .name = "Channel Mode",
3817 .info = alc_ch_mode_info,
3818 .get = alc_ch_mode_get,
3819 .put = alc_ch_mode_put,
3824 static struct hda_verb alc880_test_init_verbs[] = {
3825 /* Unmute inputs of 0x0c - 0x0f */
3826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3827 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3828 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3829 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3830 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3831 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3832 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3833 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3834 /* Vol output for 0x0c-0x0f */
3835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3836 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3837 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3838 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3839 /* Set output pins 0x14-0x17 */
3840 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3841 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3842 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3843 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3844 /* Unmute output pins 0x14-0x17 */
3845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3847 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3848 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3849 /* Set input pins 0x18-0x1c */
3850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3851 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3852 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3853 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3854 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3855 /* Mute input pins 0x18-0x1b */
3856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3857 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3859 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3862 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3863 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3864 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3865 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3866 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3867 /* Analog input/passthru */
3868 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3869 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3880 static const char *alc880_models[ALC880_MODEL_LAST] = {
3881 [ALC880_3ST] = "3stack",
3882 [ALC880_TCL_S700] = "tcl",
3883 [ALC880_3ST_DIG] = "3stack-digout",
3884 [ALC880_CLEVO] = "clevo",
3885 [ALC880_5ST] = "5stack",
3886 [ALC880_5ST_DIG] = "5stack-digout",
3887 [ALC880_W810] = "w810",
3888 [ALC880_Z71V] = "z71v",
3889 [ALC880_6ST] = "6stack",
3890 [ALC880_6ST_DIG] = "6stack-digout",
3891 [ALC880_ASUS] = "asus",
3892 [ALC880_ASUS_W1V] = "asus-w1v",
3893 [ALC880_ASUS_DIG] = "asus-dig",
3894 [ALC880_ASUS_DIG2] = "asus-dig2",
3895 [ALC880_UNIWILL_DIG] = "uniwill",
3896 [ALC880_UNIWILL_P53] = "uniwill-p53",
3897 [ALC880_FUJITSU] = "fujitsu",
3898 [ALC880_F1734] = "F1734",
3900 [ALC880_LG_LW] = "lg-lw",
3901 [ALC880_MEDION_RIM] = "medion",
3902 #ifdef CONFIG_SND_DEBUG
3903 [ALC880_TEST] = "test",
3905 [ALC880_AUTO] = "auto",
3908 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3909 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3910 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3911 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3912 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3913 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3914 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3915 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3916 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3917 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3918 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3919 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3920 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3921 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3922 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3923 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3924 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3925 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3926 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3927 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3928 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3929 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3930 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3931 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3932 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3933 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3934 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3935 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3936 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3937 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3938 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3939 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3940 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3941 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3942 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3943 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3944 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3945 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3946 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3947 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3948 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3949 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3950 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3951 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3952 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3953 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3954 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3955 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3956 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3957 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3958 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3959 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3960 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3961 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3962 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3963 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3964 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3965 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3966 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3967 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3968 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3969 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3970 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3971 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3972 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3973 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3974 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3975 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3976 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3978 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3979 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3980 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3985 * ALC880 codec presets
3987 static struct alc_config_preset alc880_presets[] = {
3989 .mixers = { alc880_three_stack_mixer },
3990 .init_verbs = { alc880_volume_init_verbs,
3991 alc880_pin_3stack_init_verbs },
3992 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3993 .dac_nids = alc880_dac_nids,
3994 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3995 .channel_mode = alc880_threestack_modes,
3997 .input_mux = &alc880_capture_source,
3999 [ALC880_3ST_DIG] = {
4000 .mixers = { alc880_three_stack_mixer },
4001 .init_verbs = { alc880_volume_init_verbs,
4002 alc880_pin_3stack_init_verbs },
4003 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4004 .dac_nids = alc880_dac_nids,
4005 .dig_out_nid = ALC880_DIGOUT_NID,
4006 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4007 .channel_mode = alc880_threestack_modes,
4009 .input_mux = &alc880_capture_source,
4011 [ALC880_TCL_S700] = {
4012 .mixers = { alc880_tcl_s700_mixer },
4013 .init_verbs = { alc880_volume_init_verbs,
4014 alc880_pin_tcl_S700_init_verbs,
4015 alc880_gpio2_init_verbs },
4016 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4017 .dac_nids = alc880_dac_nids,
4018 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4019 .num_adc_nids = 1, /* single ADC */
4021 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4022 .channel_mode = alc880_2_jack_modes,
4023 .input_mux = &alc880_capture_source,
4026 .mixers = { alc880_three_stack_mixer,
4027 alc880_five_stack_mixer},
4028 .init_verbs = { alc880_volume_init_verbs,
4029 alc880_pin_5stack_init_verbs },
4030 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4031 .dac_nids = alc880_dac_nids,
4032 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4033 .channel_mode = alc880_fivestack_modes,
4034 .input_mux = &alc880_capture_source,
4036 [ALC880_5ST_DIG] = {
4037 .mixers = { alc880_three_stack_mixer,
4038 alc880_five_stack_mixer },
4039 .init_verbs = { alc880_volume_init_verbs,
4040 alc880_pin_5stack_init_verbs },
4041 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4042 .dac_nids = alc880_dac_nids,
4043 .dig_out_nid = ALC880_DIGOUT_NID,
4044 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4045 .channel_mode = alc880_fivestack_modes,
4046 .input_mux = &alc880_capture_source,
4049 .mixers = { alc880_six_stack_mixer },
4050 .init_verbs = { alc880_volume_init_verbs,
4051 alc880_pin_6stack_init_verbs },
4052 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4053 .dac_nids = alc880_6st_dac_nids,
4054 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4055 .channel_mode = alc880_sixstack_modes,
4056 .input_mux = &alc880_6stack_capture_source,
4058 [ALC880_6ST_DIG] = {
4059 .mixers = { alc880_six_stack_mixer },
4060 .init_verbs = { alc880_volume_init_verbs,
4061 alc880_pin_6stack_init_verbs },
4062 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4063 .dac_nids = alc880_6st_dac_nids,
4064 .dig_out_nid = ALC880_DIGOUT_NID,
4065 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4066 .channel_mode = alc880_sixstack_modes,
4067 .input_mux = &alc880_6stack_capture_source,
4070 .mixers = { alc880_w810_base_mixer },
4071 .init_verbs = { alc880_volume_init_verbs,
4072 alc880_pin_w810_init_verbs,
4073 alc880_gpio2_init_verbs },
4074 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4075 .dac_nids = alc880_w810_dac_nids,
4076 .dig_out_nid = ALC880_DIGOUT_NID,
4077 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4078 .channel_mode = alc880_w810_modes,
4079 .input_mux = &alc880_capture_source,
4082 .mixers = { alc880_z71v_mixer },
4083 .init_verbs = { alc880_volume_init_verbs,
4084 alc880_pin_z71v_init_verbs },
4085 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4086 .dac_nids = alc880_z71v_dac_nids,
4087 .dig_out_nid = ALC880_DIGOUT_NID,
4089 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4090 .channel_mode = alc880_2_jack_modes,
4091 .input_mux = &alc880_capture_source,
4094 .mixers = { alc880_f1734_mixer },
4095 .init_verbs = { alc880_volume_init_verbs,
4096 alc880_pin_f1734_init_verbs },
4097 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4098 .dac_nids = alc880_f1734_dac_nids,
4100 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4101 .channel_mode = alc880_2_jack_modes,
4102 .input_mux = &alc880_f1734_capture_source,
4103 .unsol_event = alc880_uniwill_p53_unsol_event,
4104 .setup = alc880_uniwill_p53_setup,
4105 .init_hook = alc_automute_amp,
4108 .mixers = { alc880_asus_mixer },
4109 .init_verbs = { alc880_volume_init_verbs,
4110 alc880_pin_asus_init_verbs,
4111 alc880_gpio1_init_verbs },
4112 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4113 .dac_nids = alc880_asus_dac_nids,
4114 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4115 .channel_mode = alc880_asus_modes,
4117 .input_mux = &alc880_capture_source,
4119 [ALC880_ASUS_DIG] = {
4120 .mixers = { alc880_asus_mixer },
4121 .init_verbs = { alc880_volume_init_verbs,
4122 alc880_pin_asus_init_verbs,
4123 alc880_gpio1_init_verbs },
4124 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4125 .dac_nids = alc880_asus_dac_nids,
4126 .dig_out_nid = ALC880_DIGOUT_NID,
4127 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4128 .channel_mode = alc880_asus_modes,
4130 .input_mux = &alc880_capture_source,
4132 [ALC880_ASUS_DIG2] = {
4133 .mixers = { alc880_asus_mixer },
4134 .init_verbs = { alc880_volume_init_verbs,
4135 alc880_pin_asus_init_verbs,
4136 alc880_gpio2_init_verbs }, /* use GPIO2 */
4137 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4138 .dac_nids = alc880_asus_dac_nids,
4139 .dig_out_nid = ALC880_DIGOUT_NID,
4140 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4141 .channel_mode = alc880_asus_modes,
4143 .input_mux = &alc880_capture_source,
4145 [ALC880_ASUS_W1V] = {
4146 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4147 .init_verbs = { alc880_volume_init_verbs,
4148 alc880_pin_asus_init_verbs,
4149 alc880_gpio1_init_verbs },
4150 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4151 .dac_nids = alc880_asus_dac_nids,
4152 .dig_out_nid = ALC880_DIGOUT_NID,
4153 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4154 .channel_mode = alc880_asus_modes,
4156 .input_mux = &alc880_capture_source,
4158 [ALC880_UNIWILL_DIG] = {
4159 .mixers = { alc880_asus_mixer },
4160 .init_verbs = { alc880_volume_init_verbs,
4161 alc880_pin_asus_init_verbs },
4162 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4163 .dac_nids = alc880_asus_dac_nids,
4164 .dig_out_nid = ALC880_DIGOUT_NID,
4165 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4166 .channel_mode = alc880_asus_modes,
4168 .input_mux = &alc880_capture_source,
4170 [ALC880_UNIWILL] = {
4171 .mixers = { alc880_uniwill_mixer },
4172 .init_verbs = { alc880_volume_init_verbs,
4173 alc880_uniwill_init_verbs },
4174 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4175 .dac_nids = alc880_asus_dac_nids,
4176 .dig_out_nid = ALC880_DIGOUT_NID,
4177 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4178 .channel_mode = alc880_threestack_modes,
4180 .input_mux = &alc880_capture_source,
4181 .unsol_event = alc880_uniwill_unsol_event,
4182 .setup = alc880_uniwill_setup,
4183 .init_hook = alc880_uniwill_init_hook,
4185 [ALC880_UNIWILL_P53] = {
4186 .mixers = { alc880_uniwill_p53_mixer },
4187 .init_verbs = { alc880_volume_init_verbs,
4188 alc880_uniwill_p53_init_verbs },
4189 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4190 .dac_nids = alc880_asus_dac_nids,
4191 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4192 .channel_mode = alc880_threestack_modes,
4193 .input_mux = &alc880_capture_source,
4194 .unsol_event = alc880_uniwill_p53_unsol_event,
4195 .setup = alc880_uniwill_p53_setup,
4196 .init_hook = alc_automute_amp,
4198 [ALC880_FUJITSU] = {
4199 .mixers = { alc880_fujitsu_mixer },
4200 .init_verbs = { alc880_volume_init_verbs,
4201 alc880_uniwill_p53_init_verbs,
4202 alc880_beep_init_verbs },
4203 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4204 .dac_nids = alc880_dac_nids,
4205 .dig_out_nid = ALC880_DIGOUT_NID,
4206 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4207 .channel_mode = alc880_2_jack_modes,
4208 .input_mux = &alc880_capture_source,
4209 .unsol_event = alc880_uniwill_p53_unsol_event,
4210 .setup = alc880_uniwill_p53_setup,
4211 .init_hook = alc_automute_amp,
4214 .mixers = { alc880_three_stack_mixer },
4215 .init_verbs = { alc880_volume_init_verbs,
4216 alc880_pin_clevo_init_verbs },
4217 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4218 .dac_nids = alc880_dac_nids,
4220 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4221 .channel_mode = alc880_threestack_modes,
4223 .input_mux = &alc880_capture_source,
4226 .mixers = { alc880_lg_mixer },
4227 .init_verbs = { alc880_volume_init_verbs,
4228 alc880_lg_init_verbs },
4229 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4230 .dac_nids = alc880_lg_dac_nids,
4231 .dig_out_nid = ALC880_DIGOUT_NID,
4232 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4233 .channel_mode = alc880_lg_ch_modes,
4235 .input_mux = &alc880_lg_capture_source,
4236 .unsol_event = alc_automute_amp_unsol_event,
4237 .setup = alc880_lg_setup,
4238 .init_hook = alc_automute_amp,
4239 #ifdef CONFIG_SND_HDA_POWER_SAVE
4240 .loopbacks = alc880_lg_loopbacks,
4244 .mixers = { alc880_lg_lw_mixer },
4245 .init_verbs = { alc880_volume_init_verbs,
4246 alc880_lg_lw_init_verbs },
4247 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4248 .dac_nids = alc880_dac_nids,
4249 .dig_out_nid = ALC880_DIGOUT_NID,
4250 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4251 .channel_mode = alc880_lg_lw_modes,
4252 .input_mux = &alc880_lg_lw_capture_source,
4253 .unsol_event = alc_automute_amp_unsol_event,
4254 .setup = alc880_lg_lw_setup,
4255 .init_hook = alc_automute_amp,
4257 [ALC880_MEDION_RIM] = {
4258 .mixers = { alc880_medion_rim_mixer },
4259 .init_verbs = { alc880_volume_init_verbs,
4260 alc880_medion_rim_init_verbs,
4261 alc_gpio2_init_verbs },
4262 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4263 .dac_nids = alc880_dac_nids,
4264 .dig_out_nid = ALC880_DIGOUT_NID,
4265 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4266 .channel_mode = alc880_2_jack_modes,
4267 .input_mux = &alc880_medion_rim_capture_source,
4268 .unsol_event = alc880_medion_rim_unsol_event,
4269 .setup = alc880_medion_rim_setup,
4270 .init_hook = alc880_medion_rim_automute,
4272 #ifdef CONFIG_SND_DEBUG
4274 .mixers = { alc880_test_mixer },
4275 .init_verbs = { alc880_test_init_verbs },
4276 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4277 .dac_nids = alc880_test_dac_nids,
4278 .dig_out_nid = ALC880_DIGOUT_NID,
4279 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4280 .channel_mode = alc880_test_modes,
4281 .input_mux = &alc880_test_capture_source,
4287 * Automatic parse of I/O pins from the BIOS configuration
4292 ALC_CTL_WIDGET_MUTE,
4295 static struct snd_kcontrol_new alc880_control_templates[] = {
4296 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4297 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4298 HDA_BIND_MUTE(NULL, 0, 0, 0),
4301 /* add dynamic controls */
4302 static int add_control(struct alc_spec *spec, int type, const char *name,
4305 struct snd_kcontrol_new *knew;
4307 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4308 knew = snd_array_new(&spec->kctls);
4311 *knew = alc880_control_templates[type];
4312 knew->name = kstrdup(name, GFP_KERNEL);
4315 if (get_amp_nid_(val))
4316 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val);
4317 knew->private_value = val;
4321 static int add_control_with_pfx(struct alc_spec *spec, int type,
4322 const char *pfx, const char *dir,
4323 const char *sfx, unsigned long val)
4326 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4327 return add_control(spec, type, name, val);
4330 #define add_pb_vol_ctrl(spec, type, pfx, val) \
4331 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4332 #define add_pb_sw_ctrl(spec, type, pfx, val) \
4333 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4335 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4336 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4337 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4338 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4339 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4340 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4341 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4342 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4343 #define ALC880_PIN_CD_NID 0x1c
4345 /* fill in the dac_nids table from the parsed pin configuration */
4346 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4347 const struct auto_pin_cfg *cfg)
4353 memset(assigned, 0, sizeof(assigned));
4354 spec->multiout.dac_nids = spec->private_dac_nids;
4356 /* check the pins hardwired to audio widget */
4357 for (i = 0; i < cfg->line_outs; i++) {
4358 nid = cfg->line_out_pins[i];
4359 if (alc880_is_fixed_pin(nid)) {
4360 int idx = alc880_fixed_pin_idx(nid);
4361 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4365 /* left pins can be connect to any audio widget */
4366 for (i = 0; i < cfg->line_outs; i++) {
4367 nid = cfg->line_out_pins[i];
4368 if (alc880_is_fixed_pin(nid))
4370 /* search for an empty channel */
4371 for (j = 0; j < cfg->line_outs; j++) {
4373 spec->multiout.dac_nids[i] =
4374 alc880_idx_to_dac(j);
4380 spec->multiout.num_dacs = cfg->line_outs;
4384 /* add playback controls from the parsed DAC table */
4385 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4386 const struct auto_pin_cfg *cfg)
4388 static const char *chname[4] = {
4389 "Front", "Surround", NULL /*CLFE*/, "Side"
4394 for (i = 0; i < cfg->line_outs; i++) {
4395 if (!spec->multiout.dac_nids[i])
4397 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4400 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4402 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4406 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4408 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4412 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4414 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4418 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4420 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4426 if (cfg->line_outs == 1 &&
4427 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4431 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4432 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4436 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4437 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4446 /* add playback controls for speaker and HP outputs */
4447 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4456 if (alc880_is_fixed_pin(pin)) {
4457 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4458 /* specify the DAC as the extra output */
4459 if (!spec->multiout.hp_nid)
4460 spec->multiout.hp_nid = nid;
4462 spec->multiout.extra_out_nid[0] = nid;
4463 /* control HP volume/switch on the output mixer amp */
4464 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4465 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4466 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4469 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4470 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4473 } else if (alc880_is_multi_pin(pin)) {
4474 /* set manual connection */
4475 /* we have only a switch on HP-out PIN */
4476 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4477 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4484 /* create input playback/capture controls for the given pin */
4485 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4486 const char *ctlname,
4487 int idx, hda_nid_t mix_nid)
4491 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4492 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4495 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4496 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4502 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4504 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4505 return (pincap & AC_PINCAP_IN) != 0;
4508 /* create playback/capture controls for input pins */
4509 static int alc_auto_create_input_ctls(struct hda_codec *codec,
4510 const struct auto_pin_cfg *cfg,
4512 hda_nid_t cap1, hda_nid_t cap2)
4514 struct alc_spec *spec = codec->spec;
4515 struct hda_input_mux *imux = &spec->private_imux[0];
4518 for (i = 0; i < AUTO_PIN_LAST; i++) {
4521 pin = cfg->input_pins[i];
4522 if (!alc_is_input_pin(codec, pin))
4526 idx = get_connection_index(codec, mixer, pin);
4528 err = new_analog_input(spec, pin,
4529 auto_pin_cfg_labels[i],
4538 idx = get_connection_index(codec, cap1, pin);
4539 if (idx < 0 && cap2)
4540 idx = get_connection_index(codec, cap2, pin);
4542 imux->items[imux->num_items].label =
4543 auto_pin_cfg_labels[i];
4544 imux->items[imux->num_items].index = idx;
4551 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4552 const struct auto_pin_cfg *cfg)
4554 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4557 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4558 unsigned int pin_type)
4560 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4563 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4567 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4568 hda_nid_t nid, int pin_type,
4571 alc_set_pin_output(codec, nid, pin_type);
4572 /* need the manual connection? */
4573 if (alc880_is_multi_pin(nid)) {
4574 struct alc_spec *spec = codec->spec;
4575 int idx = alc880_multi_pin_idx(nid);
4576 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4577 AC_VERB_SET_CONNECT_SEL,
4578 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4582 static int get_pin_type(int line_out_type)
4584 if (line_out_type == AUTO_PIN_HP_OUT)
4590 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4592 struct alc_spec *spec = codec->spec;
4595 for (i = 0; i < spec->autocfg.line_outs; i++) {
4596 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4597 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4598 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4602 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4604 struct alc_spec *spec = codec->spec;
4607 pin = spec->autocfg.speaker_pins[0];
4608 if (pin) /* connect to front */
4609 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4610 pin = spec->autocfg.hp_pins[0];
4611 if (pin) /* connect to front */
4612 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4615 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4617 struct alc_spec *spec = codec->spec;
4620 for (i = 0; i < AUTO_PIN_LAST; i++) {
4621 hda_nid_t nid = spec->autocfg.input_pins[i];
4622 if (alc_is_input_pin(codec, nid)) {
4623 alc_set_input_pin(codec, nid, i);
4624 if (nid != ALC880_PIN_CD_NID &&
4625 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4626 snd_hda_codec_write(codec, nid, 0,
4627 AC_VERB_SET_AMP_GAIN_MUTE,
4633 /* parse the BIOS configuration and set up the alc_spec */
4634 /* return 1 if successful, 0 if the proper config is not found,
4635 * or a negative error code
4637 static int alc880_parse_auto_config(struct hda_codec *codec)
4639 struct alc_spec *spec = codec->spec;
4641 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4643 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4647 if (!spec->autocfg.line_outs)
4648 return 0; /* can't find valid BIOS pin config */
4650 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4653 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4656 err = alc880_auto_create_extra_out(spec,
4657 spec->autocfg.speaker_pins[0],
4661 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4665 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4669 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4671 /* check multiple SPDIF-out (for recent codecs) */
4672 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4674 err = snd_hda_get_connections(codec,
4675 spec->autocfg.dig_out_pins[i],
4680 spec->multiout.dig_out_nid = dig_nid;
4682 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4683 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4685 spec->slave_dig_outs[i - 1] = dig_nid;
4688 if (spec->autocfg.dig_in_pin)
4689 spec->dig_in_nid = ALC880_DIGIN_NID;
4691 if (spec->kctls.list)
4692 add_mixer(spec, spec->kctls.list);
4694 add_verb(spec, alc880_volume_init_verbs);
4696 spec->num_mux_defs = 1;
4697 spec->input_mux = &spec->private_imux[0];
4699 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4704 /* additional initialization for auto-configuration model */
4705 static void alc880_auto_init(struct hda_codec *codec)
4707 struct alc_spec *spec = codec->spec;
4708 alc880_auto_init_multi_out(codec);
4709 alc880_auto_init_extra_out(codec);
4710 alc880_auto_init_analog_input(codec);
4711 if (spec->unsol_event)
4712 alc_inithook(codec);
4715 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4716 * one of two digital mic pins, e.g. on ALC272
4718 static void fixup_automic_adc(struct hda_codec *codec)
4720 struct alc_spec *spec = codec->spec;
4723 for (i = 0; i < spec->num_adc_nids; i++) {
4724 hda_nid_t cap = spec->capsrc_nids ?
4725 spec->capsrc_nids[i] : spec->adc_nids[i];
4728 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4731 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4734 spec->int_mic.mux_idx = iidx;
4735 spec->ext_mic.mux_idx = eidx;
4736 if (spec->capsrc_nids)
4737 spec->capsrc_nids += i;
4738 spec->adc_nids += i;
4739 spec->num_adc_nids = 1;
4742 snd_printd(KERN_INFO "hda_codec: %s: "
4743 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4744 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4745 spec->auto_mic = 0; /* disable auto-mic to be sure */
4748 static void set_capture_mixer(struct hda_codec *codec)
4750 struct alc_spec *spec = codec->spec;
4751 static struct snd_kcontrol_new *caps[2][3] = {
4752 { alc_capture_mixer_nosrc1,
4753 alc_capture_mixer_nosrc2,
4754 alc_capture_mixer_nosrc3 },
4755 { alc_capture_mixer1,
4757 alc_capture_mixer3 },
4759 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4761 if (spec->auto_mic) {
4763 fixup_automic_adc(codec);
4764 } else if (spec->input_mux && spec->input_mux->num_items > 1)
4768 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4772 #ifdef CONFIG_SND_HDA_INPUT_BEEP
4773 #define set_beep_amp(spec, nid, idx, dir) \
4774 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4776 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
4780 * OK, here we have finally the patch for ALC880
4783 static int patch_alc880(struct hda_codec *codec)
4785 struct alc_spec *spec;
4789 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4795 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4798 if (board_config < 0) {
4799 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4801 board_config = ALC880_AUTO;
4804 if (board_config == ALC880_AUTO) {
4805 /* automatic parse from the BIOS config */
4806 err = alc880_parse_auto_config(codec);
4812 "hda_codec: Cannot set up configuration "
4813 "from BIOS. Using 3-stack mode...\n");
4814 board_config = ALC880_3ST;
4818 err = snd_hda_attach_beep_device(codec, 0x1);
4824 if (board_config != ALC880_AUTO)
4825 setup_preset(codec, &alc880_presets[board_config]);
4827 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4828 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4829 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4831 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4832 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4834 if (!spec->adc_nids && spec->input_mux) {
4835 /* check whether NID 0x07 is valid */
4836 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4838 wcap = get_wcaps_type(wcap);
4839 if (wcap != AC_WID_AUD_IN) {
4840 spec->adc_nids = alc880_adc_nids_alt;
4841 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4843 spec->adc_nids = alc880_adc_nids;
4844 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4847 set_capture_mixer(codec);
4848 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4850 spec->vmaster_nid = 0x0c;
4852 codec->patch_ops = alc_patch_ops;
4853 if (board_config == ALC880_AUTO)
4854 spec->init_hook = alc880_auto_init;
4855 #ifdef CONFIG_SND_HDA_POWER_SAVE
4856 if (!spec->loopback.amplist)
4857 spec->loopback.amplist = alc880_loopbacks;
4859 codec->proc_widget_hook = print_realtek_coef;
4869 static hda_nid_t alc260_dac_nids[1] = {
4874 static hda_nid_t alc260_adc_nids[1] = {
4879 static hda_nid_t alc260_adc_nids_alt[1] = {
4884 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4885 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4887 static hda_nid_t alc260_dual_adc_nids[2] = {
4892 #define ALC260_DIGOUT_NID 0x03
4893 #define ALC260_DIGIN_NID 0x06
4895 static struct hda_input_mux alc260_capture_source = {
4899 { "Front Mic", 0x1 },
4905 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4906 * headphone jack and the internal CD lines since these are the only pins at
4907 * which audio can appear. For flexibility, also allow the option of
4908 * recording the mixer output on the second ADC (ADC0 doesn't have a
4909 * connection to the mixer output).
4911 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4915 { "Mic/Line", 0x0 },
4917 { "Headphone", 0x2 },
4923 { "Mic/Line", 0x0 },
4925 { "Headphone", 0x2 },
4932 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4933 * the Fujitsu S702x, but jacks are marked differently.
4935 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4942 { "Headphone", 0x5 },
4951 { "Headphone", 0x6 },
4957 /* Maxdata Favorit 100XS */
4958 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4962 { "Line/Mic", 0x0 },
4969 { "Line/Mic", 0x0 },
4977 * This is just place-holder, so there's something for alc_build_pcms to look
4978 * at when it calculates the maximum number of channels. ALC260 has no mixer
4979 * element which allows changing the channel mode, so the verb list is
4982 static struct hda_channel_mode alc260_modes[1] = {
4987 /* Mixer combinations
4989 * basic: base_output + input + pc_beep + capture
4990 * HP: base_output + input + capture_alt
4991 * HP_3013: hp_3013 + input + capture
4992 * fujitsu: fujitsu + capture
4993 * acer: acer + capture
4996 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4997 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4998 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4999 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5000 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5001 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5002 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5006 static struct snd_kcontrol_new alc260_input_mixer[] = {
5007 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5008 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5009 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5010 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5012 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5013 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5014 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5018 /* update HP, line and mono out pins according to the master switch */
5019 static void alc260_hp_master_update(struct hda_codec *codec,
5020 hda_nid_t hp, hda_nid_t line,
5023 struct alc_spec *spec = codec->spec;
5024 unsigned int val = spec->master_sw ? PIN_HP : 0;
5025 /* change HP and line-out pins */
5026 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5028 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5030 /* mono (speaker) depending on the HP jack sense */
5031 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5032 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5036 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5037 struct snd_ctl_elem_value *ucontrol)
5039 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5040 struct alc_spec *spec = codec->spec;
5041 *ucontrol->value.integer.value = spec->master_sw;
5045 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5046 struct snd_ctl_elem_value *ucontrol)
5048 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5049 struct alc_spec *spec = codec->spec;
5050 int val = !!*ucontrol->value.integer.value;
5051 hda_nid_t hp, line, mono;
5053 if (val == spec->master_sw)
5055 spec->master_sw = val;
5056 hp = (kcontrol->private_value >> 16) & 0xff;
5057 line = (kcontrol->private_value >> 8) & 0xff;
5058 mono = kcontrol->private_value & 0xff;
5059 alc260_hp_master_update(codec, hp, line, mono);
5063 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5065 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5066 .name = "Master Playback Switch",
5067 .info = snd_ctl_boolean_mono_info,
5068 .get = alc260_hp_master_sw_get,
5069 .put = alc260_hp_master_sw_put,
5070 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5072 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5073 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5074 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5075 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5076 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5078 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5082 static struct hda_verb alc260_hp_unsol_verbs[] = {
5083 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5087 static void alc260_hp_automute(struct hda_codec *codec)
5089 struct alc_spec *spec = codec->spec;
5091 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5092 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5095 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5097 if ((res >> 26) == ALC880_HP_EVENT)
5098 alc260_hp_automute(codec);
5101 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5104 .name = "Master Playback Switch",
5105 .info = snd_ctl_boolean_mono_info,
5106 .get = alc260_hp_master_sw_get,
5107 .put = alc260_hp_master_sw_put,
5108 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5110 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5111 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5112 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5113 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5114 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5116 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5117 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5121 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5122 .ops = &snd_hda_bind_vol,
5124 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5125 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5126 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5131 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5132 .ops = &snd_hda_bind_sw,
5134 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5135 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5140 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5141 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5142 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5143 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5144 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5148 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5153 static void alc260_hp_3013_automute(struct hda_codec *codec)
5155 struct alc_spec *spec = codec->spec;
5157 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5158 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5161 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5164 if ((res >> 26) == ALC880_HP_EVENT)
5165 alc260_hp_3013_automute(codec);
5168 static void alc260_hp_3012_automute(struct hda_codec *codec)
5170 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5172 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5174 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5176 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5180 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5183 if ((res >> 26) == ALC880_HP_EVENT)
5184 alc260_hp_3012_automute(codec);
5187 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5188 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5190 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5191 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5192 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5193 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5194 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5195 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5196 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5197 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5198 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5199 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5200 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5204 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5205 * versions of the ALC260 don't act on requests to enable mic bias from NID
5206 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5207 * datasheet doesn't mention this restriction. At this stage it's not clear
5208 * whether this behaviour is intentional or is a hardware bug in chip
5209 * revisions available in early 2006. Therefore for now allow the
5210 * "Headphone Jack Mode" control to span all choices, but if it turns out
5211 * that the lack of mic bias for this NID is intentional we could change the
5212 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5214 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5215 * don't appear to make the mic bias available from the "line" jack, even
5216 * though the NID used for this jack (0x14) can supply it. The theory is
5217 * that perhaps Acer have included blocking capacitors between the ALC260
5218 * and the output jack. If this turns out to be the case for all such
5219 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5220 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5222 * The C20x Tablet series have a mono internal speaker which is controlled
5223 * via the chip's Mono sum widget and pin complex, so include the necessary
5224 * controls for such models. On models without a "mono speaker" the control
5225 * won't do anything.
5227 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5228 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5229 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5230 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5231 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5233 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5235 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5236 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5238 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5239 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5240 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5241 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5242 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5246 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5248 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5249 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5250 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5251 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5252 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5253 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5254 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5258 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5259 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5261 static struct snd_kcontrol_new alc260_will_mixer[] = {
5262 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5263 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5265 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5266 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5267 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5268 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5269 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5270 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5271 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5275 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5276 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5278 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5279 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5280 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5282 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5283 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5284 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5285 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5286 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5287 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5288 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5293 * initialization verbs
5295 static struct hda_verb alc260_init_verbs[] = {
5296 /* Line In pin widget for input */
5297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5298 /* CD pin widget for input */
5299 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5300 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5301 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5302 /* Mic2 (front panel) pin widget for input and vref at 80% */
5303 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5304 /* LINE-2 is used for line-out in rear */
5305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5306 /* select line-out */
5307 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5309 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5311 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5313 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5314 /* mute capture amp left and right */
5315 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5316 /* set connection select to line in (default select for this ADC) */
5317 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5318 /* mute capture amp left and right */
5319 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5320 /* set connection select to line in (default select for this ADC) */
5321 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5322 /* set vol=0 Line-Out mixer amp left and right */
5323 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5324 /* unmute pin widget amp left and right (no gain on this amp) */
5325 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5326 /* set vol=0 HP mixer amp left and right */
5327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5328 /* unmute pin widget amp left and right (no gain on this amp) */
5329 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5330 /* set vol=0 Mono mixer amp left and right */
5331 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5332 /* unmute pin widget amp left and right (no gain on this amp) */
5333 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5334 /* unmute LINE-2 out pin */
5335 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5336 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5339 /* mute analog inputs */
5340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5341 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5345 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5346 /* mute Front out path */
5347 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5348 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5349 /* mute Headphone out path */
5350 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5351 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5352 /* mute Mono out path */
5353 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5354 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5358 #if 0 /* should be identical with alc260_init_verbs? */
5359 static struct hda_verb alc260_hp_init_verbs[] = {
5360 /* Headphone and output */
5361 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5363 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5364 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5365 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5366 /* Mic2 (front panel) pin widget for input and vref at 80% */
5367 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5368 /* Line In pin widget for input */
5369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5370 /* Line-2 pin widget for output */
5371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5372 /* CD pin widget for input */
5373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5374 /* unmute amp left and right */
5375 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5376 /* set connection select to line in (default select for this ADC) */
5377 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5378 /* unmute Line-Out mixer amp left and right (volume = 0) */
5379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5380 /* mute pin widget amp left and right (no gain on this amp) */
5381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5382 /* unmute HP mixer amp left and right (volume = 0) */
5383 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5384 /* mute pin widget amp left and right (no gain on this amp) */
5385 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5386 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5389 /* mute analog inputs */
5390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5391 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5393 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5395 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5396 /* Unmute Front out path */
5397 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5398 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5399 /* Unmute Headphone out path */
5400 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5401 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5402 /* Unmute Mono out path */
5403 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5404 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5409 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5410 /* Line out and output */
5411 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5413 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5414 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5415 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5416 /* Mic2 (front panel) pin widget for input and vref at 80% */
5417 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5418 /* Line In pin widget for input */
5419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5420 /* Headphone pin widget for output */
5421 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5422 /* CD pin widget for input */
5423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5424 /* unmute amp left and right */
5425 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5426 /* set connection select to line in (default select for this ADC) */
5427 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5428 /* unmute Line-Out mixer amp left and right (volume = 0) */
5429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5430 /* mute pin widget amp left and right (no gain on this amp) */
5431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5432 /* unmute HP mixer amp left and right (volume = 0) */
5433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5434 /* mute pin widget amp left and right (no gain on this amp) */
5435 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5436 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5439 /* mute analog inputs */
5440 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5441 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5442 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5445 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5446 /* Unmute Front out path */
5447 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5449 /* Unmute Headphone out path */
5450 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5452 /* Unmute Mono out path */
5453 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5454 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5458 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5459 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5460 * audio = 0x16, internal speaker = 0x10.
5462 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5463 /* Disable all GPIOs */
5464 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5465 /* Internal speaker is connected to headphone pin */
5466 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5467 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5469 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5470 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5471 /* Ensure all other unused pins are disabled and muted. */
5472 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5474 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5475 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5476 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5477 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5478 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5479 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5481 /* Disable digital (SPDIF) pins */
5482 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5483 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5485 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5486 * when acting as an output.
5488 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5490 /* Start with output sum widgets muted and their output gains at min */
5491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5494 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5497 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5501 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5502 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5503 /* Unmute Line1 pin widget output buffer since it starts as an output.
5504 * If the pin mode is changed by the user the pin mode control will
5505 * take care of enabling the pin's input/output buffers as needed.
5506 * Therefore there's no need to enable the input buffer at this
5509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5510 /* Unmute input buffer of pin widget used for Line-in (no equiv
5513 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5515 /* Mute capture amp left and right */
5516 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5517 /* Set ADC connection select to match default mixer setting - line
5520 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5522 /* Do the same for the second ADC: mute capture input amp and
5523 * set ADC connection to line in (on mic1 pin)
5525 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5526 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5528 /* Mute all inputs to mixer widget (even unconnected ones) */
5529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5541 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5542 * similar laptops (adapted from Fujitsu init verbs).
5544 static struct hda_verb alc260_acer_init_verbs[] = {
5545 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5546 * the headphone jack. Turn this on and rely on the standard mute
5547 * methods whenever the user wants to turn these outputs off.
5549 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5550 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5551 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5552 /* Internal speaker/Headphone jack is connected to Line-out pin */
5553 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5554 /* Internal microphone/Mic jack is connected to Mic1 pin */
5555 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5556 /* Line In jack is connected to Line1 pin */
5557 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5558 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5559 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5560 /* Ensure all other unused pins are disabled and muted. */
5561 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5562 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5563 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5564 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5567 /* Disable digital (SPDIF) pins */
5568 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5569 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5571 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5572 * bus when acting as outputs.
5574 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5575 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5577 /* Start with output sum widgets muted and their output gains at min */
5578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5584 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5588 /* Unmute Line-out pin widget amp left and right
5589 * (no equiv mixer ctrl)
5591 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5592 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5593 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5594 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5595 * inputs. If the pin mode is changed by the user the pin mode control
5596 * will take care of enabling the pin's input/output buffers as needed.
5597 * Therefore there's no need to enable the input buffer at this
5600 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5603 /* Mute capture amp left and right */
5604 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5605 /* Set ADC connection select to match default mixer setting - mic
5608 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5610 /* Do similar with the second ADC: mute capture input amp and
5611 * set ADC connection to mic to match ALSA's default state.
5613 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5614 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5616 /* Mute all inputs to mixer widget (even unconnected ones) */
5617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5629 /* Initialisation sequence for Maxdata Favorit 100XS
5630 * (adapted from Acer init verbs).
5632 static struct hda_verb alc260_favorit100_init_verbs[] = {
5633 /* GPIO 0 enables the output jack.
5634 * Turn this on and rely on the standard mute
5635 * methods whenever the user wants to turn these outputs off.
5637 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5638 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5639 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5640 /* Line/Mic input jack is connected to Mic1 pin */
5641 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5642 /* Ensure all other unused pins are disabled and muted. */
5643 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5644 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5645 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5646 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5647 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5648 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5649 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5652 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5653 /* Disable digital (SPDIF) pins */
5654 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5655 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5657 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5658 * bus when acting as outputs.
5660 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5661 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5663 /* Start with output sum widgets muted and their output gains at min */
5664 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5665 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5666 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5667 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5670 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5672 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5674 /* Unmute Line-out pin widget amp left and right
5675 * (no equiv mixer ctrl)
5677 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5678 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5679 * inputs. If the pin mode is changed by the user the pin mode control
5680 * will take care of enabling the pin's input/output buffers as needed.
5681 * Therefore there's no need to enable the input buffer at this
5684 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5686 /* Mute capture amp left and right */
5687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5688 /* Set ADC connection select to match default mixer setting - mic
5691 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5693 /* Do similar with the second ADC: mute capture input amp and
5694 * set ADC connection to mic to match ALSA's default state.
5696 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5697 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5699 /* Mute all inputs to mixer widget (even unconnected ones) */
5700 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5701 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5702 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5712 static struct hda_verb alc260_will_verbs[] = {
5713 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5714 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5715 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5716 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5717 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5718 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5722 static struct hda_verb alc260_replacer_672v_verbs[] = {
5723 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5724 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5725 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5727 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5728 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5729 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5731 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5735 /* toggle speaker-output according to the hp-jack state */
5736 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5738 unsigned int present;
5740 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5741 present = snd_hda_jack_detect(codec, 0x0f);
5743 snd_hda_codec_write_cache(codec, 0x01, 0,
5744 AC_VERB_SET_GPIO_DATA, 1);
5745 snd_hda_codec_write_cache(codec, 0x0f, 0,
5746 AC_VERB_SET_PIN_WIDGET_CONTROL,
5749 snd_hda_codec_write_cache(codec, 0x01, 0,
5750 AC_VERB_SET_GPIO_DATA, 0);
5751 snd_hda_codec_write_cache(codec, 0x0f, 0,
5752 AC_VERB_SET_PIN_WIDGET_CONTROL,
5757 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5760 if ((res >> 26) == ALC880_HP_EVENT)
5761 alc260_replacer_672v_automute(codec);
5764 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5765 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5766 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5767 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5768 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5769 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5771 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5772 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5773 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5774 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5778 /* Test configuration for debugging, modelled after the ALC880 test
5781 #ifdef CONFIG_SND_DEBUG
5782 static hda_nid_t alc260_test_dac_nids[1] = {
5785 static hda_nid_t alc260_test_adc_nids[2] = {
5788 /* For testing the ALC260, each input MUX needs its own definition since
5789 * the signal assignments are different. This assumes that the first ADC
5792 static struct hda_input_mux alc260_test_capture_sources[2] = {
5796 { "MIC1 pin", 0x0 },
5797 { "MIC2 pin", 0x1 },
5798 { "LINE1 pin", 0x2 },
5799 { "LINE2 pin", 0x3 },
5801 { "LINE-OUT pin", 0x5 },
5802 { "HP-OUT pin", 0x6 },
5808 { "MIC1 pin", 0x0 },
5809 { "MIC2 pin", 0x1 },
5810 { "LINE1 pin", 0x2 },
5811 { "LINE2 pin", 0x3 },
5814 { "LINE-OUT pin", 0x6 },
5815 { "HP-OUT pin", 0x7 },
5819 static struct snd_kcontrol_new alc260_test_mixer[] = {
5820 /* Output driver widgets */
5821 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5822 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5823 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5824 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5825 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5826 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5828 /* Modes for retasking pin widgets
5829 * Note: the ALC260 doesn't seem to act on requests to enable mic
5830 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5831 * mention this restriction. At this stage it's not clear whether
5832 * this behaviour is intentional or is a hardware bug in chip
5833 * revisions available at least up until early 2006. Therefore for
5834 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5835 * choices, but if it turns out that the lack of mic bias for these
5836 * NIDs is intentional we could change their modes from
5837 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5839 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5840 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5841 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5842 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5843 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5844 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5846 /* Loopback mixer controls */
5847 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5848 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5849 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5850 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5851 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5852 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5853 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5854 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5855 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5856 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5857 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5858 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5859 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5860 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5862 /* Controls for GPIO pins, assuming they are configured as outputs */
5863 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5864 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5865 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5866 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5868 /* Switches to allow the digital IO pins to be enabled. The datasheet
5869 * is ambigious as to which NID is which; testing on laptops which
5870 * make this output available should provide clarification.
5872 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5873 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5875 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5876 * this output to turn on an external amplifier.
5878 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5879 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5883 static struct hda_verb alc260_test_init_verbs[] = {
5884 /* Enable all GPIOs as outputs with an initial value of 0 */
5885 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5886 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5887 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5889 /* Enable retasking pins as output, initially without power amp */
5890 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5891 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5894 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5895 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5897 /* Disable digital (SPDIF) pins initially, but users can enable
5898 * them via a mixer switch. In the case of SPDIF-out, this initverb
5899 * payload also sets the generation to 0, output to be in "consumer"
5900 * PCM format, copyright asserted, no pre-emphasis and no validity
5903 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5904 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5906 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5907 * OUT1 sum bus when acting as an output.
5909 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5910 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5911 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5912 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5914 /* Start with output sum widgets muted and their output gains at min */
5915 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5916 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5921 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5922 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5925 /* Unmute retasking pin widget output buffers since the default
5926 * state appears to be output. As the pin mode is changed by the
5927 * user the pin mode control will take care of enabling the pin's
5928 * input/output buffers as needed.
5930 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5932 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5933 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5934 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5935 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5936 /* Also unmute the mono-out pin widget */
5937 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5939 /* Mute capture amp left and right */
5940 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5941 /* Set ADC connection select to match default mixer setting (mic1
5944 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5946 /* Do the same for the second ADC: mute capture input amp and
5947 * set ADC connection to mic1 pin
5949 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5950 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5952 /* Mute all inputs to mixer widget (even unconnected ones) */
5953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5954 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5956 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5966 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5967 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5969 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5970 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5973 * for BIOS auto-configuration
5976 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5977 const char *pfx, int *vol_bits)
5980 unsigned long vol_val, sw_val;
5983 if (nid >= 0x0f && nid < 0x11) {
5984 nid_vol = nid - 0x7;
5985 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5986 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5987 } else if (nid == 0x11) {
5988 nid_vol = nid - 0x7;
5989 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5990 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5991 } else if (nid >= 0x12 && nid <= 0x15) {
5993 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5994 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5998 if (!(*vol_bits & (1 << nid_vol))) {
5999 /* first control for the volume widget */
6000 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6003 *vol_bits |= (1 << nid_vol);
6005 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6011 /* add playback controls from the parsed DAC table */
6012 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6013 const struct auto_pin_cfg *cfg)
6019 spec->multiout.num_dacs = 1;
6020 spec->multiout.dac_nids = spec->private_dac_nids;
6021 spec->multiout.dac_nids[0] = 0x02;
6023 nid = cfg->line_out_pins[0];
6026 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6028 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6032 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6037 nid = cfg->speaker_pins[0];
6039 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6044 nid = cfg->hp_pins[0];
6046 err = alc260_add_playback_controls(spec, nid, "Headphone",
6054 /* create playback/capture controls for input pins */
6055 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6056 const struct auto_pin_cfg *cfg)
6058 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6061 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6062 hda_nid_t nid, int pin_type,
6065 alc_set_pin_output(codec, nid, pin_type);
6066 /* need the manual connection? */
6068 int idx = nid - 0x12;
6069 snd_hda_codec_write(codec, idx + 0x0b, 0,
6070 AC_VERB_SET_CONNECT_SEL, sel_idx);
6074 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6076 struct alc_spec *spec = codec->spec;
6079 nid = spec->autocfg.line_out_pins[0];
6081 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6082 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6085 nid = spec->autocfg.speaker_pins[0];
6087 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6089 nid = spec->autocfg.hp_pins[0];
6091 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6094 #define ALC260_PIN_CD_NID 0x16
6095 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6097 struct alc_spec *spec = codec->spec;
6100 for (i = 0; i < AUTO_PIN_LAST; i++) {
6101 hda_nid_t nid = spec->autocfg.input_pins[i];
6103 alc_set_input_pin(codec, nid, i);
6104 if (nid != ALC260_PIN_CD_NID &&
6105 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6106 snd_hda_codec_write(codec, nid, 0,
6107 AC_VERB_SET_AMP_GAIN_MUTE,
6114 * generic initialization of ADC, input mixers and output mixers
6116 static struct hda_verb alc260_volume_init_verbs[] = {
6118 * Unmute ADC0-1 and set the default input to mic-in
6120 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6121 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6122 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6123 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6125 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6127 * Note: PASD motherboards uses the Line In 2 as the input for
6128 * front panel mic (mic 2)
6130 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6131 /* mute analog inputs */
6132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6134 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6139 * Set up output mixers (0x08 - 0x0a)
6141 /* set vol=0 to output mixers */
6142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6143 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6144 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6145 /* set up input amps for analog loopback */
6146 /* Amp Indices: DAC = 0, mixer = 1 */
6147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6149 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6151 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6152 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6157 static int alc260_parse_auto_config(struct hda_codec *codec)
6159 struct alc_spec *spec = codec->spec;
6161 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6163 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6167 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6170 if (!spec->kctls.list)
6171 return 0; /* can't find valid BIOS pin config */
6172 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6176 spec->multiout.max_channels = 2;
6178 if (spec->autocfg.dig_outs)
6179 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6180 if (spec->kctls.list)
6181 add_mixer(spec, spec->kctls.list);
6183 add_verb(spec, alc260_volume_init_verbs);
6185 spec->num_mux_defs = 1;
6186 spec->input_mux = &spec->private_imux[0];
6188 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6193 /* additional initialization for auto-configuration model */
6194 static void alc260_auto_init(struct hda_codec *codec)
6196 struct alc_spec *spec = codec->spec;
6197 alc260_auto_init_multi_out(codec);
6198 alc260_auto_init_analog_input(codec);
6199 if (spec->unsol_event)
6200 alc_inithook(codec);
6203 #ifdef CONFIG_SND_HDA_POWER_SAVE
6204 static struct hda_amp_list alc260_loopbacks[] = {
6205 { 0x07, HDA_INPUT, 0 },
6206 { 0x07, HDA_INPUT, 1 },
6207 { 0x07, HDA_INPUT, 2 },
6208 { 0x07, HDA_INPUT, 3 },
6209 { 0x07, HDA_INPUT, 4 },
6215 * ALC260 configurations
6217 static const char *alc260_models[ALC260_MODEL_LAST] = {
6218 [ALC260_BASIC] = "basic",
6220 [ALC260_HP_3013] = "hp-3013",
6221 [ALC260_HP_DC7600] = "hp-dc7600",
6222 [ALC260_FUJITSU_S702X] = "fujitsu",
6223 [ALC260_ACER] = "acer",
6224 [ALC260_WILL] = "will",
6225 [ALC260_REPLACER_672V] = "replacer",
6226 [ALC260_FAVORIT100] = "favorit100",
6227 #ifdef CONFIG_SND_DEBUG
6228 [ALC260_TEST] = "test",
6230 [ALC260_AUTO] = "auto",
6233 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6234 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6235 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6236 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6237 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6238 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6239 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6240 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6241 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6242 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6243 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6244 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6245 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6246 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6247 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6248 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6249 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6250 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6251 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6252 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6256 static struct alc_config_preset alc260_presets[] = {
6258 .mixers = { alc260_base_output_mixer,
6259 alc260_input_mixer },
6260 .init_verbs = { alc260_init_verbs },
6261 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6262 .dac_nids = alc260_dac_nids,
6263 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6264 .adc_nids = alc260_adc_nids,
6265 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6266 .channel_mode = alc260_modes,
6267 .input_mux = &alc260_capture_source,
6270 .mixers = { alc260_hp_output_mixer,
6271 alc260_input_mixer },
6272 .init_verbs = { alc260_init_verbs,
6273 alc260_hp_unsol_verbs },
6274 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6275 .dac_nids = alc260_dac_nids,
6276 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6277 .adc_nids = alc260_adc_nids_alt,
6278 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6279 .channel_mode = alc260_modes,
6280 .input_mux = &alc260_capture_source,
6281 .unsol_event = alc260_hp_unsol_event,
6282 .init_hook = alc260_hp_automute,
6284 [ALC260_HP_DC7600] = {
6285 .mixers = { alc260_hp_dc7600_mixer,
6286 alc260_input_mixer },
6287 .init_verbs = { alc260_init_verbs,
6288 alc260_hp_dc7600_verbs },
6289 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6290 .dac_nids = alc260_dac_nids,
6291 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6292 .adc_nids = alc260_adc_nids_alt,
6293 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6294 .channel_mode = alc260_modes,
6295 .input_mux = &alc260_capture_source,
6296 .unsol_event = alc260_hp_3012_unsol_event,
6297 .init_hook = alc260_hp_3012_automute,
6299 [ALC260_HP_3013] = {
6300 .mixers = { alc260_hp_3013_mixer,
6301 alc260_input_mixer },
6302 .init_verbs = { alc260_hp_3013_init_verbs,
6303 alc260_hp_3013_unsol_verbs },
6304 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6305 .dac_nids = alc260_dac_nids,
6306 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6307 .adc_nids = alc260_adc_nids_alt,
6308 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6309 .channel_mode = alc260_modes,
6310 .input_mux = &alc260_capture_source,
6311 .unsol_event = alc260_hp_3013_unsol_event,
6312 .init_hook = alc260_hp_3013_automute,
6314 [ALC260_FUJITSU_S702X] = {
6315 .mixers = { alc260_fujitsu_mixer },
6316 .init_verbs = { alc260_fujitsu_init_verbs },
6317 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6318 .dac_nids = alc260_dac_nids,
6319 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6320 .adc_nids = alc260_dual_adc_nids,
6321 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6322 .channel_mode = alc260_modes,
6323 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6324 .input_mux = alc260_fujitsu_capture_sources,
6327 .mixers = { alc260_acer_mixer },
6328 .init_verbs = { alc260_acer_init_verbs },
6329 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6330 .dac_nids = alc260_dac_nids,
6331 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6332 .adc_nids = alc260_dual_adc_nids,
6333 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6334 .channel_mode = alc260_modes,
6335 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6336 .input_mux = alc260_acer_capture_sources,
6338 [ALC260_FAVORIT100] = {
6339 .mixers = { alc260_favorit100_mixer },
6340 .init_verbs = { alc260_favorit100_init_verbs },
6341 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6342 .dac_nids = alc260_dac_nids,
6343 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6344 .adc_nids = alc260_dual_adc_nids,
6345 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6346 .channel_mode = alc260_modes,
6347 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6348 .input_mux = alc260_favorit100_capture_sources,
6351 .mixers = { alc260_will_mixer },
6352 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6353 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6354 .dac_nids = alc260_dac_nids,
6355 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6356 .adc_nids = alc260_adc_nids,
6357 .dig_out_nid = ALC260_DIGOUT_NID,
6358 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6359 .channel_mode = alc260_modes,
6360 .input_mux = &alc260_capture_source,
6362 [ALC260_REPLACER_672V] = {
6363 .mixers = { alc260_replacer_672v_mixer },
6364 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6365 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6366 .dac_nids = alc260_dac_nids,
6367 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6368 .adc_nids = alc260_adc_nids,
6369 .dig_out_nid = ALC260_DIGOUT_NID,
6370 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6371 .channel_mode = alc260_modes,
6372 .input_mux = &alc260_capture_source,
6373 .unsol_event = alc260_replacer_672v_unsol_event,
6374 .init_hook = alc260_replacer_672v_automute,
6376 #ifdef CONFIG_SND_DEBUG
6378 .mixers = { alc260_test_mixer },
6379 .init_verbs = { alc260_test_init_verbs },
6380 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6381 .dac_nids = alc260_test_dac_nids,
6382 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6383 .adc_nids = alc260_test_adc_nids,
6384 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6385 .channel_mode = alc260_modes,
6386 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6387 .input_mux = alc260_test_capture_sources,
6392 static int patch_alc260(struct hda_codec *codec)
6394 struct alc_spec *spec;
6395 int err, board_config;
6397 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6403 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6406 if (board_config < 0) {
6407 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6409 board_config = ALC260_AUTO;
6412 if (board_config == ALC260_AUTO) {
6413 /* automatic parse from the BIOS config */
6414 err = alc260_parse_auto_config(codec);
6420 "hda_codec: Cannot set up configuration "
6421 "from BIOS. Using base mode...\n");
6422 board_config = ALC260_BASIC;
6426 err = snd_hda_attach_beep_device(codec, 0x1);
6432 if (board_config != ALC260_AUTO)
6433 setup_preset(codec, &alc260_presets[board_config]);
6435 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6436 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6438 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6439 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6441 if (!spec->adc_nids && spec->input_mux) {
6442 /* check whether NID 0x04 is valid */
6443 unsigned int wcap = get_wcaps(codec, 0x04);
6444 wcap = get_wcaps_type(wcap);
6446 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6447 spec->adc_nids = alc260_adc_nids_alt;
6448 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6450 spec->adc_nids = alc260_adc_nids;
6451 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6454 set_capture_mixer(codec);
6455 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6457 spec->vmaster_nid = 0x08;
6459 codec->patch_ops = alc_patch_ops;
6460 if (board_config == ALC260_AUTO)
6461 spec->init_hook = alc260_auto_init;
6462 #ifdef CONFIG_SND_HDA_POWER_SAVE
6463 if (!spec->loopback.amplist)
6464 spec->loopback.amplist = alc260_loopbacks;
6466 codec->proc_widget_hook = print_realtek_coef;
6473 * ALC882/883/885/888/889 support
6475 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6476 * configuration. Each pin widget can choose any input DACs and a mixer.
6477 * Each ADC is connected from a mixer of all inputs. This makes possible
6478 * 6-channel independent captures.
6480 * In addition, an independent DAC for the multi-playback (not used in this
6483 #define ALC882_DIGOUT_NID 0x06
6484 #define ALC882_DIGIN_NID 0x0a
6485 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6486 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
6487 #define ALC1200_DIGOUT_NID 0x10
6490 static struct hda_channel_mode alc882_ch_modes[1] = {
6495 static hda_nid_t alc882_dac_nids[4] = {
6496 /* front, rear, clfe, rear_surr */
6497 0x02, 0x03, 0x04, 0x05
6499 #define alc883_dac_nids alc882_dac_nids
6502 #define alc882_adc_nids alc880_adc_nids
6503 #define alc882_adc_nids_alt alc880_adc_nids_alt
6504 #define alc883_adc_nids alc882_adc_nids_alt
6505 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6506 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6507 #define alc889_adc_nids alc880_adc_nids
6509 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6510 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6511 #define alc883_capsrc_nids alc882_capsrc_nids_alt
6512 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6513 #define alc889_capsrc_nids alc882_capsrc_nids
6516 /* FIXME: should be a matrix-type input source selection */
6518 static struct hda_input_mux alc882_capture_source = {
6522 { "Front Mic", 0x1 },
6528 #define alc883_capture_source alc882_capture_source
6530 static struct hda_input_mux alc889_capture_source = {
6533 { "Front Mic", 0x0 },
6539 static struct hda_input_mux mb5_capture_source = {
6548 static struct hda_input_mux alc883_3stack_6ch_intel = {
6552 { "Front Mic", 0x0 },
6558 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6566 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6576 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6584 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6588 { "Front Mic", 0x1 },
6593 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6601 static struct hda_input_mux alc889A_mb31_capture_source = {
6605 /* Front Mic (0x01) unused */
6607 /* Line 2 (0x03) unused */
6608 /* CD (0x04) unsused? */
6615 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6622 static struct hda_verb alc882_3ST_ch2_init[] = {
6623 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6624 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6625 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6626 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6633 static struct hda_verb alc882_3ST_ch4_init[] = {
6634 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6635 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6636 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6637 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6638 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6645 static struct hda_verb alc882_3ST_ch6_init[] = {
6646 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6647 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6648 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6649 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6650 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6651 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6655 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6656 { 2, alc882_3ST_ch2_init },
6657 { 4, alc882_3ST_ch4_init },
6658 { 6, alc882_3ST_ch6_init },
6661 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6666 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6667 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6668 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6669 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6670 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6671 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6678 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6679 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6680 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6681 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6682 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6683 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6684 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6691 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6692 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6693 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6694 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6695 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6696 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6697 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6698 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6702 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6703 { 2, alc883_3ST_ch2_clevo_init },
6704 { 4, alc883_3ST_ch4_clevo_init },
6705 { 6, alc883_3ST_ch6_clevo_init },
6712 static struct hda_verb alc882_sixstack_ch6_init[] = {
6713 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6714 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6715 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6716 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6723 static struct hda_verb alc882_sixstack_ch8_init[] = {
6724 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6725 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6726 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6727 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6731 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6732 { 6, alc882_sixstack_ch6_init },
6733 { 8, alc882_sixstack_ch8_init },
6737 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6743 static struct hda_verb alc885_mbp_ch2_init[] = {
6744 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6745 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6746 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6753 static struct hda_verb alc885_mbp_ch4_init[] = {
6754 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6755 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6756 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6757 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6758 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6762 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
6763 { 2, alc885_mbp_ch2_init },
6764 { 4, alc885_mbp_ch4_init },
6769 * Speakers/Woofer/HP = Front
6772 static struct hda_verb alc885_mb5_ch2_init[] = {
6773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6780 * Speakers/HP = Front
6784 static struct hda_verb alc885_mb5_ch6_init[] = {
6785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6787 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6791 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6792 { 2, alc885_mb5_ch2_init },
6793 { 6, alc885_mb5_ch6_init },
6800 static struct hda_verb alc883_4ST_ch2_init[] = {
6801 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6802 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6805 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6806 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6813 static struct hda_verb alc883_4ST_ch4_init[] = {
6814 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6815 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6816 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6817 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6818 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6819 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6820 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6827 static struct hda_verb alc883_4ST_ch6_init[] = {
6828 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6829 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6830 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6831 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6832 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6833 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6834 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6835 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6842 static struct hda_verb alc883_4ST_ch8_init[] = {
6843 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6844 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6845 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6846 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6847 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6848 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6851 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6855 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6856 { 2, alc883_4ST_ch2_init },
6857 { 4, alc883_4ST_ch4_init },
6858 { 6, alc883_4ST_ch6_init },
6859 { 8, alc883_4ST_ch8_init },
6866 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6867 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6868 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6869 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6870 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6877 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6878 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6879 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6882 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6889 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6890 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6891 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6892 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6893 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6894 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6895 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6899 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6900 { 2, alc883_3ST_ch2_intel_init },
6901 { 4, alc883_3ST_ch4_intel_init },
6902 { 6, alc883_3ST_ch6_intel_init },
6908 static struct hda_verb alc889_ch2_intel_init[] = {
6909 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6910 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6911 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6912 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6913 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6914 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6921 static struct hda_verb alc889_ch6_intel_init[] = {
6922 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6923 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6924 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6925 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6926 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6927 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6934 static struct hda_verb alc889_ch8_intel_init[] = {
6935 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6936 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6937 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6938 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6939 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
6940 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6941 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6945 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6946 { 2, alc889_ch2_intel_init },
6947 { 6, alc889_ch6_intel_init },
6948 { 8, alc889_ch8_intel_init },
6954 static struct hda_verb alc883_sixstack_ch6_init[] = {
6955 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6956 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6957 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6958 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6965 static struct hda_verb alc883_sixstack_ch8_init[] = {
6966 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6967 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6968 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6969 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6973 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6974 { 6, alc883_sixstack_ch6_init },
6975 { 8, alc883_sixstack_ch8_init },
6979 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6980 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6982 static struct snd_kcontrol_new alc882_base_mixer[] = {
6983 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6984 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6985 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6986 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6991 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6992 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6994 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6995 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6996 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6997 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6998 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6999 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7000 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7001 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7002 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7003 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7007 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7008 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7009 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7010 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7011 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7012 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7013 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7014 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7016 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7017 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7018 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7022 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7023 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7024 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7025 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7026 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7027 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7028 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7029 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7030 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
7031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7032 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7034 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7035 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7036 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7040 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7041 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7042 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7043 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7044 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7048 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7053 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7054 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7055 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7059 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7060 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7063 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7064 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7065 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7066 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7070 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7071 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7073 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7075 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7076 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7077 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7078 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7079 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7080 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7081 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7082 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7083 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7086 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7090 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7091 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7092 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7093 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7094 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7095 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7096 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7097 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7099 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7104 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7106 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7107 .name = "Channel Mode",
7108 .info = alc_ch_mode_info,
7109 .get = alc_ch_mode_get,
7110 .put = alc_ch_mode_put,
7115 static struct hda_verb alc882_base_init_verbs[] = {
7116 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7123 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7125 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7126 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7127 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7129 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7133 /* mute analog input loopbacks */
7134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7140 /* Front Pin: output 0 (0x0c) */
7141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7142 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7143 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7144 /* Rear Pin: output 1 (0x0d) */
7145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7146 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7147 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7148 /* CLFE Pin: output 2 (0x0e) */
7149 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7150 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7151 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7152 /* Side Pin: output 3 (0x0f) */
7153 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7154 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7155 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7156 /* Mic (rear) pin: input vref at 80% */
7157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7159 /* Front Mic pin: input vref at 80% */
7160 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7161 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7162 /* Line In pin: input */
7163 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7164 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7165 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7166 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7167 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7168 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7169 /* CD pin widget for input */
7170 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7172 /* FIXME: use matrix-type input source selection */
7173 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7176 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7177 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7178 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7182 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7184 /* ADC2: mute amp left and right */
7185 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7186 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7187 /* ADC3: mute amp left and right */
7188 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7189 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7194 static struct hda_verb alc882_adc1_init_verbs[] = {
7195 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7197 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7200 /* ADC1: mute amp left and right */
7201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7202 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7206 static struct hda_verb alc882_eapd_verbs[] = {
7207 /* change to EAPD mode */
7208 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7209 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7213 static struct hda_verb alc889_eapd_verbs[] = {
7214 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7215 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7219 static struct hda_verb alc_hp15_unsol_verbs[] = {
7220 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7225 static struct hda_verb alc885_init_verbs[] = {
7226 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7231 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7232 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7233 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7235 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7236 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7237 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7239 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7240 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7241 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7243 /* mute analog input loopbacks */
7244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7248 /* Front HP Pin: output 0 (0x0c) */
7249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7251 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7252 /* Front Pin: output 0 (0x0c) */
7253 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7254 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7255 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7256 /* Rear Pin: output 1 (0x0d) */
7257 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7258 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7259 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7260 /* CLFE Pin: output 2 (0x0e) */
7261 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7262 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7263 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7264 /* Side Pin: output 3 (0x0f) */
7265 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7267 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7268 /* Mic (rear) pin: input vref at 80% */
7269 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7270 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7271 /* Front Mic pin: input vref at 80% */
7272 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7273 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7274 /* Line In pin: input */
7275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7278 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7280 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7284 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7285 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7290 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7291 /* ADC2: mute amp left and right */
7292 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7293 /* ADC3: mute amp left and right */
7294 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7299 static struct hda_verb alc885_init_input_verbs[] = {
7300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7307 /* Unmute Selector 24h and set the default input to front mic */
7308 static struct hda_verb alc889_init_input_verbs[] = {
7309 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7310 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7315 #define alc883_init_verbs alc882_base_init_verbs
7318 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7319 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7320 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7321 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7322 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7323 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7324 /* FIXME: this looks suspicious...
7325 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7326 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7331 static struct hda_verb alc882_macpro_init_verbs[] = {
7332 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7336 /* Front Pin: output 0 (0x0c) */
7337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7340 /* Front Mic pin: input vref at 80% */
7341 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7343 /* Speaker: output */
7344 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7346 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7347 /* Headphone output (output 0 - 0x0c) */
7348 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7349 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7350 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7352 /* FIXME: use matrix-type input source selection */
7353 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7354 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7361 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7369 /* ADC1: mute amp left and right */
7370 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7372 /* ADC2: mute amp left and right */
7373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7374 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7375 /* ADC3: mute amp left and right */
7376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7377 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7383 static struct hda_verb alc885_mb5_init_verbs[] = {
7385 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7386 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7387 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7388 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7393 /* Surround mixer */
7394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7398 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7399 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7403 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7405 /* Front Pin (0x0c) */
7406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7408 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7409 /* LFE Pin (0x0e) */
7410 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7411 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7412 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7414 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7415 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7416 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7417 /* Front Mic pin: input vref at 80% */
7418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7419 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7421 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7431 /* Macbook Pro rev3 */
7432 static struct hda_verb alc885_mbp3_init_verbs[] = {
7433 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7438 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7442 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7445 /* Front Pin: output 0 (0x0c) */
7446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7448 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7449 /* HP Pin: output 0 (0x0e) */
7450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7453 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7454 /* Mic (rear) pin: input vref at 80% */
7455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7457 /* Front Mic pin: input vref at 80% */
7458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7460 /* Line In pin: use output 1 when in LineOut mode */
7461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7463 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7465 /* FIXME: use matrix-type input source selection */
7466 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7467 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7482 /* ADC1: mute amp left and right */
7483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7484 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7485 /* ADC2: mute amp left and right */
7486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7487 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7488 /* ADC3: mute amp left and right */
7489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7490 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7495 /* iMac 24 mixer. */
7496 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7497 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7498 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7502 /* iMac 24 init verbs. */
7503 static struct hda_verb alc885_imac24_init_verbs[] = {
7504 /* Internal speakers: output 0 (0x0c) */
7505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7506 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7507 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7508 /* Internal speakers: output 0 (0x0c) */
7509 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7511 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7512 /* Headphone: output 0 (0x0c) */
7513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7516 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7517 /* Front Mic: input vref at 80% */
7518 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7519 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7523 /* Toggle speaker-output according to the hp-jack state */
7524 static void alc885_imac24_setup(struct hda_codec *codec)
7526 struct alc_spec *spec = codec->spec;
7528 spec->autocfg.hp_pins[0] = 0x14;
7529 spec->autocfg.speaker_pins[0] = 0x18;
7530 spec->autocfg.speaker_pins[1] = 0x1a;
7533 static void alc885_mbp3_setup(struct hda_codec *codec)
7535 struct alc_spec *spec = codec->spec;
7537 spec->autocfg.hp_pins[0] = 0x15;
7538 spec->autocfg.speaker_pins[0] = 0x14;
7542 static struct hda_verb alc882_targa_verbs[] = {
7543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7547 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7549 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7550 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7551 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7557 /* toggle speaker-output according to the hp-jack state */
7558 static void alc882_targa_automute(struct hda_codec *codec)
7560 struct alc_spec *spec = codec->spec;
7561 alc_automute_amp(codec);
7562 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7563 spec->jack_present ? 1 : 3);
7566 static void alc882_targa_setup(struct hda_codec *codec)
7568 struct alc_spec *spec = codec->spec;
7570 spec->autocfg.hp_pins[0] = 0x14;
7571 spec->autocfg.speaker_pins[0] = 0x1b;
7574 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7576 if ((res >> 26) == ALC880_HP_EVENT)
7577 alc882_targa_automute(codec);
7580 static struct hda_verb alc882_asus_a7j_verbs[] = {
7581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7586 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7588 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7589 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7590 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7592 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7593 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7594 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7598 static struct hda_verb alc882_asus_a7m_verbs[] = {
7599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7603 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7604 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7606 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7607 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7608 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7610 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7611 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7612 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7616 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7618 unsigned int gpiostate, gpiomask, gpiodir;
7620 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7621 AC_VERB_GET_GPIO_DATA, 0);
7624 gpiostate |= (1 << pin);
7626 gpiostate &= ~(1 << pin);
7628 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7629 AC_VERB_GET_GPIO_MASK, 0);
7630 gpiomask |= (1 << pin);
7632 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7633 AC_VERB_GET_GPIO_DIRECTION, 0);
7634 gpiodir |= (1 << pin);
7637 snd_hda_codec_write(codec, codec->afg, 0,
7638 AC_VERB_SET_GPIO_MASK, gpiomask);
7639 snd_hda_codec_write(codec, codec->afg, 0,
7640 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7644 snd_hda_codec_write(codec, codec->afg, 0,
7645 AC_VERB_SET_GPIO_DATA, gpiostate);
7648 /* set up GPIO at initialization */
7649 static void alc885_macpro_init_hook(struct hda_codec *codec)
7651 alc882_gpio_mute(codec, 0, 0);
7652 alc882_gpio_mute(codec, 1, 0);
7655 /* set up GPIO and update auto-muting at initialization */
7656 static void alc885_imac24_init_hook(struct hda_codec *codec)
7658 alc885_macpro_init_hook(codec);
7659 alc_automute_amp(codec);
7663 * generic initialization of ADC, input mixers and output mixers
7665 static struct hda_verb alc883_auto_init_verbs[] = {
7667 * Unmute ADC0-2 and set the default input to mic-in
7669 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7671 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7672 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7674 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7676 * Note: PASD motherboards uses the Line In 2 as the input for
7677 * front panel mic (mic 2)
7679 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7680 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7687 * Set up output mixers (0x0c - 0x0f)
7689 /* set vol=0 to output mixers */
7690 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7691 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7692 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7693 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7694 /* set up input amps for analog loopback */
7695 /* Amp Indices: DAC = 0, mixer = 1 */
7696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7698 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7699 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7700 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7701 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7702 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7703 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7704 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7705 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7707 /* FIXME: use matrix-type input source selection */
7708 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7710 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7711 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7712 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7713 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7723 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7724 static struct hda_verb alc889A_mb31_ch2_init[] = {
7725 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7726 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7727 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7728 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7732 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7733 static struct hda_verb alc889A_mb31_ch4_init[] = {
7734 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7735 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7736 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7741 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7742 static struct hda_verb alc889A_mb31_ch5_init[] = {
7743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7744 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7745 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7750 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7751 static struct hda_verb alc889A_mb31_ch6_init[] = {
7752 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7754 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7755 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7759 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7760 { 2, alc889A_mb31_ch2_init },
7761 { 4, alc889A_mb31_ch4_init },
7762 { 5, alc889A_mb31_ch5_init },
7763 { 6, alc889A_mb31_ch6_init },
7766 static struct hda_verb alc883_medion_eapd_verbs[] = {
7767 /* eanable EAPD on medion laptop */
7768 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7769 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7773 #define alc883_base_mixer alc882_base_mixer
7775 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7777 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7778 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7779 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7780 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7781 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7787 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7788 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7792 static struct snd_kcontrol_new alc883_clevo_m720_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_2ch_fujitsu_pi2515_mixer[] = {
7807 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7808 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7809 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7810 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7812 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7813 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7814 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7816 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7820 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7821 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7822 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7823 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7829 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7830 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7831 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7832 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7833 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7837 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7838 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7841 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7842 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7843 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7844 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7845 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7847 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7848 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7849 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7850 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7854 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7855 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7856 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7860 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7861 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7862 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7863 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7864 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7865 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7867 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7868 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7869 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7870 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7871 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7872 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7873 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7874 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7875 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7876 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7878 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7879 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7880 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7884 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7885 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7886 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7887 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7888 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7889 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7891 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7892 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7893 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7894 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7895 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7896 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7897 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7898 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7900 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7902 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7903 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7904 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7908 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7909 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7910 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7911 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7912 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7913 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7914 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7915 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7916 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7918 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7919 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7921 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7922 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7925 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7926 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7927 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7931 static struct snd_kcontrol_new alc883_targa_mixer[] = {
7932 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7933 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7934 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7935 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7936 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7937 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7938 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7940 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7941 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7942 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7943 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7944 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7945 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7947 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7948 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7952 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
7953 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7954 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7956 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 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_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7961 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7962 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7963 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7964 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7968 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
7969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7971 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7973 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7977 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7980 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7981 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7982 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7989 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7990 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7991 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7993 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7994 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7997 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7998 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8002 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8005 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8015 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8016 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8017 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8018 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8019 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8020 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8022 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8023 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8027 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8028 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8029 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8030 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8031 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8032 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8033 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8042 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8045 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8046 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8047 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8048 0x0d, 1, 0x0, HDA_OUTPUT),
8049 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8050 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8051 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8052 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8053 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8054 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8055 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8057 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8059 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8060 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8062 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8063 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8067 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8069 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8070 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8072 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8073 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8075 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8076 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8077 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8078 /* Output switches */
8079 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8080 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8081 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8083 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8084 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8087 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8088 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8089 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8093 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8094 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8095 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8096 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8097 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8098 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8103 static struct hda_bind_ctls alc883_bind_cap_vol = {
8104 .ops = &snd_hda_bind_vol,
8106 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8107 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8112 static struct hda_bind_ctls alc883_bind_cap_switch = {
8113 .ops = &snd_hda_bind_sw,
8115 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8116 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8121 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8122 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8123 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8133 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8134 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8135 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8138 /* .name = "Capture Source", */
8139 .name = "Input Source",
8141 .info = alc_mux_enum_info,
8142 .get = alc_mux_enum_get,
8143 .put = alc_mux_enum_put,
8148 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8150 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8151 .name = "Channel Mode",
8152 .info = alc_ch_mode_info,
8153 .get = alc_ch_mode_get,
8154 .put = alc_ch_mode_put,
8159 /* toggle speaker-output according to the hp-jack state */
8160 static void alc883_mitac_setup(struct hda_codec *codec)
8162 struct alc_spec *spec = codec->spec;
8164 spec->autocfg.hp_pins[0] = 0x15;
8165 spec->autocfg.speaker_pins[0] = 0x14;
8166 spec->autocfg.speaker_pins[1] = 0x17;
8169 /* auto-toggle front mic */
8171 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8173 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8175 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8179 static struct hda_verb alc883_mitac_verbs[] = {
8181 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8185 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8187 /* enable unsolicited event */
8188 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8189 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8194 static struct hda_verb alc883_clevo_m540r_verbs[] = {
8196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8197 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8199 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8201 /* enable unsolicited event */
8203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8210 static struct hda_verb alc883_clevo_m720_verbs[] = {
8212 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8215 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8218 /* enable unsolicited event */
8219 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8220 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8225 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8227 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8230 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8233 /* enable unsolicited event */
8234 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8239 static struct hda_verb alc883_targa_verbs[] = {
8240 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8243 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8246 /* Connect Line-Out side jack (SPDIF) to Side */
8247 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8248 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8249 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8250 /* Connect Mic jack to CLFE */
8251 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8252 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8253 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8254 /* Connect Line-in jack to Surround */
8255 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8257 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8258 /* Connect HP out jack to Front */
8259 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8261 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8263 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8268 static struct hda_verb alc883_lenovo_101e_verbs[] = {
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_lenovo_nb0763_verbs[] = {
8276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8277 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8278 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8279 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8283 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8284 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8285 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8286 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8287 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8288 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8292 static struct hda_verb alc883_haier_w66_verbs[] = {
8293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8298 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8299 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8300 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8305 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8308 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8309 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8311 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8312 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8313 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8317 static struct hda_verb alc888_6st_dell_verbs[] = {
8318 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8322 static struct hda_verb alc883_vaiott_verbs[] = {
8324 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8327 /* enable unsolicited event */
8328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8333 static void alc888_3st_hp_setup(struct hda_codec *codec)
8335 struct alc_spec *spec = codec->spec;
8337 spec->autocfg.hp_pins[0] = 0x1b;
8338 spec->autocfg.speaker_pins[0] = 0x14;
8339 spec->autocfg.speaker_pins[1] = 0x16;
8340 spec->autocfg.speaker_pins[2] = 0x18;
8343 static struct hda_verb alc888_3st_hp_verbs[] = {
8344 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8345 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8346 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8347 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8354 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8355 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8356 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8357 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8358 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8365 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8366 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8367 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8368 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8369 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8370 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8377 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8378 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8379 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8380 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8381 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8382 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8383 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8387 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8388 { 2, alc888_3st_hp_2ch_init },
8389 { 4, alc888_3st_hp_4ch_init },
8390 { 6, alc888_3st_hp_6ch_init },
8393 /* toggle front-jack and RCA according to the hp-jack state */
8394 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8396 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
8398 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8399 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8400 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8401 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8404 /* toggle RCA according to the front-jack state */
8405 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8407 unsigned int present = snd_hda_jack_detect(codec, 0x14);
8409 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8410 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8413 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8416 if ((res >> 26) == ALC880_HP_EVENT)
8417 alc888_lenovo_ms7195_front_automute(codec);
8418 if ((res >> 26) == ALC880_FRONT_EVENT)
8419 alc888_lenovo_ms7195_rca_automute(codec);
8422 static struct hda_verb alc883_medion_md2_verbs[] = {
8423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8428 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8432 /* toggle speaker-output according to the hp-jack state */
8433 static void alc883_medion_md2_setup(struct hda_codec *codec)
8435 struct alc_spec *spec = codec->spec;
8437 spec->autocfg.hp_pins[0] = 0x14;
8438 spec->autocfg.speaker_pins[0] = 0x15;
8441 /* toggle speaker-output according to the hp-jack state */
8442 #define alc883_targa_init_hook alc882_targa_init_hook
8443 #define alc883_targa_unsol_event alc882_targa_unsol_event
8445 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8447 unsigned int present;
8449 present = snd_hda_jack_detect(codec, 0x18);
8450 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8451 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8454 static void alc883_clevo_m720_setup(struct hda_codec *codec)
8456 struct alc_spec *spec = codec->spec;
8458 spec->autocfg.hp_pins[0] = 0x15;
8459 spec->autocfg.speaker_pins[0] = 0x14;
8462 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8464 alc_automute_amp(codec);
8465 alc883_clevo_m720_mic_automute(codec);
8468 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8471 switch (res >> 26) {
8472 case ALC880_MIC_EVENT:
8473 alc883_clevo_m720_mic_automute(codec);
8476 alc_automute_amp_unsol_event(codec, res);
8481 /* toggle speaker-output according to the hp-jack state */
8482 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
8484 struct alc_spec *spec = codec->spec;
8486 spec->autocfg.hp_pins[0] = 0x14;
8487 spec->autocfg.speaker_pins[0] = 0x15;
8490 static void alc883_haier_w66_setup(struct hda_codec *codec)
8492 struct alc_spec *spec = codec->spec;
8494 spec->autocfg.hp_pins[0] = 0x1b;
8495 spec->autocfg.speaker_pins[0] = 0x14;
8498 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8500 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
8502 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8503 HDA_AMP_MUTE, bits);
8506 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8508 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
8510 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8511 HDA_AMP_MUTE, bits);
8512 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8513 HDA_AMP_MUTE, bits);
8516 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8519 if ((res >> 26) == ALC880_HP_EVENT)
8520 alc883_lenovo_101e_all_automute(codec);
8521 if ((res >> 26) == ALC880_FRONT_EVENT)
8522 alc883_lenovo_101e_ispeaker_automute(codec);
8525 /* toggle speaker-output according to the hp-jack state */
8526 static void alc883_acer_aspire_setup(struct hda_codec *codec)
8528 struct alc_spec *spec = codec->spec;
8530 spec->autocfg.hp_pins[0] = 0x14;
8531 spec->autocfg.speaker_pins[0] = 0x15;
8532 spec->autocfg.speaker_pins[1] = 0x16;
8535 static struct hda_verb alc883_acer_eapd_verbs[] = {
8536 /* HP Pin: output 0 (0x0c) */
8537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8539 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8540 /* Front Pin: output 0 (0x0c) */
8541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8542 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8544 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8545 /* eanable EAPD on medion laptop */
8546 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8547 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8548 /* enable unsolicited event */
8549 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8553 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8555 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8556 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8560 static void alc888_6st_dell_setup(struct hda_codec *codec)
8562 struct alc_spec *spec = codec->spec;
8564 spec->autocfg.hp_pins[0] = 0x1b;
8565 spec->autocfg.speaker_pins[0] = 0x14;
8566 spec->autocfg.speaker_pins[1] = 0x15;
8567 spec->autocfg.speaker_pins[2] = 0x16;
8568 spec->autocfg.speaker_pins[3] = 0x17;
8571 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
8573 struct alc_spec *spec = codec->spec;
8575 spec->autocfg.hp_pins[0] = 0x1b;
8576 spec->autocfg.speaker_pins[0] = 0x14;
8577 spec->autocfg.speaker_pins[1] = 0x15;
8578 spec->autocfg.speaker_pins[2] = 0x16;
8579 spec->autocfg.speaker_pins[3] = 0x17;
8580 spec->autocfg.speaker_pins[4] = 0x1a;
8583 static void alc883_vaiott_setup(struct hda_codec *codec)
8585 struct alc_spec *spec = codec->spec;
8587 spec->autocfg.hp_pins[0] = 0x15;
8588 spec->autocfg.speaker_pins[0] = 0x14;
8589 spec->autocfg.speaker_pins[1] = 0x17;
8592 static struct hda_verb alc888_asus_m90v_verbs[] = {
8593 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8596 /* enable unsolicited event */
8597 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8602 static void alc883_mode2_setup(struct hda_codec *codec)
8604 struct alc_spec *spec = codec->spec;
8606 spec->autocfg.hp_pins[0] = 0x1b;
8607 spec->autocfg.speaker_pins[0] = 0x14;
8608 spec->autocfg.speaker_pins[1] = 0x15;
8609 spec->autocfg.speaker_pins[2] = 0x16;
8610 spec->ext_mic.pin = 0x18;
8611 spec->int_mic.pin = 0x19;
8612 spec->ext_mic.mux_idx = 0;
8613 spec->int_mic.mux_idx = 1;
8617 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8622 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8623 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8624 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8625 /* enable unsolicited event */
8626 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8630 static void alc883_eee1601_inithook(struct hda_codec *codec)
8632 struct alc_spec *spec = codec->spec;
8634 spec->autocfg.hp_pins[0] = 0x14;
8635 spec->autocfg.speaker_pins[0] = 0x1b;
8636 alc_automute_pin(codec);
8639 static struct hda_verb alc889A_mb31_verbs[] = {
8640 /* Init rear pin (used as headphone output) */
8641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8643 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8644 /* Init line pin (used as output in 4ch and 6ch mode) */
8645 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8646 /* Init line 2 pin (used as headphone out by default) */
8647 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8648 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8652 /* Mute speakers according to the headphone jack state */
8653 static void alc889A_mb31_automute(struct hda_codec *codec)
8655 unsigned int present;
8657 /* Mute only in 2ch or 4ch mode */
8658 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8660 present = snd_hda_jack_detect(codec, 0x15);
8661 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8662 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8663 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8664 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8668 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8670 if ((res >> 26) == ALC880_HP_EVENT)
8671 alc889A_mb31_automute(codec);
8675 #ifdef CONFIG_SND_HDA_POWER_SAVE
8676 #define alc882_loopbacks alc880_loopbacks
8679 /* pcm configuration: identical with ALC880 */
8680 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
8681 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
8682 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
8683 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
8685 static hda_nid_t alc883_slave_dig_outs[] = {
8686 ALC1200_DIGOUT_NID, 0,
8689 static hda_nid_t alc1200_slave_dig_outs[] = {
8690 ALC883_DIGOUT_NID, 0,
8694 * configuration and preset
8696 static const char *alc882_models[ALC882_MODEL_LAST] = {
8697 [ALC882_3ST_DIG] = "3stack-dig",
8698 [ALC882_6ST_DIG] = "6stack-dig",
8699 [ALC882_ARIMA] = "arima",
8700 [ALC882_W2JC] = "w2jc",
8701 [ALC882_TARGA] = "targa",
8702 [ALC882_ASUS_A7J] = "asus-a7j",
8703 [ALC882_ASUS_A7M] = "asus-a7m",
8704 [ALC885_MACPRO] = "macpro",
8705 [ALC885_MB5] = "mb5",
8706 [ALC885_MBP3] = "mbp3",
8707 [ALC885_IMAC24] = "imac24",
8708 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
8709 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8710 [ALC883_3ST_6ch] = "3stack-6ch",
8711 [ALC883_6ST_DIG] = "alc883-6stack-dig",
8712 [ALC883_TARGA_DIG] = "targa-dig",
8713 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8714 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
8715 [ALC883_ACER] = "acer",
8716 [ALC883_ACER_ASPIRE] = "acer-aspire",
8717 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8718 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
8719 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8720 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
8721 [ALC883_MEDION] = "medion",
8722 [ALC883_MEDION_MD2] = "medion-md2",
8723 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8724 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8725 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8726 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8727 [ALC888_LENOVO_SKY] = "lenovo-sky",
8728 [ALC883_HAIER_W66] = "haier-w66",
8729 [ALC888_3ST_HP] = "3stack-hp",
8730 [ALC888_6ST_DELL] = "6stack-dell",
8731 [ALC883_MITAC] = "mitac",
8732 [ALC883_CLEVO_M540R] = "clevo-m540r",
8733 [ALC883_CLEVO_M720] = "clevo-m720",
8734 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8735 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8736 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8737 [ALC889A_INTEL] = "intel-alc889a",
8738 [ALC889_INTEL] = "intel-x58",
8739 [ALC1200_ASUS_P5Q] = "asus-p5q",
8740 [ALC889A_MB31] = "mb31",
8741 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
8742 [ALC882_AUTO] = "auto",
8745 static struct snd_pci_quirk alc882_cfg_tbl[] = {
8746 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8748 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8749 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8750 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8751 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8752 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8753 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8754 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8755 ALC888_ACER_ASPIRE_4930G),
8756 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8757 ALC888_ACER_ASPIRE_4930G),
8758 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8759 ALC888_ACER_ASPIRE_8930G),
8760 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8761 ALC888_ACER_ASPIRE_8930G),
8762 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8763 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
8764 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8765 ALC888_ACER_ASPIRE_6530G),
8766 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8767 ALC888_ACER_ASPIRE_6530G),
8768 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
8769 ALC888_ACER_ASPIRE_7730G),
8770 /* default Acer -- disabled as it causes more problems.
8771 * model=auto should work fine now
8773 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8775 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8777 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8778 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8779 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8780 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8781 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8782 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8784 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8785 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8786 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
8787 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8788 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8789 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8790 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
8791 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8792 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8793 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8794 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8796 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8797 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8798 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
8799 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8800 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8801 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8802 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8803 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8804 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8806 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8807 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8808 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8809 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
8810 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8811 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8812 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8813 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8814 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8815 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8816 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8817 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8818 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8819 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8820 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
8821 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8822 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8823 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8824 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8825 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8826 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8827 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8828 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8829 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8830 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8831 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8832 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
8833 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8834 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8836 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8837 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8838 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8839 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
8840 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8841 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8842 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
8843 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8844 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8845 ALC883_FUJITSU_PI2515),
8846 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8847 ALC888_FUJITSU_XA3530),
8848 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8849 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8850 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8851 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8852 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8853 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8854 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8855 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8856 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8858 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8859 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8860 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8861 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8862 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8863 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
8864 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8869 /* codec SSID table for Intel Mac */
8870 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8871 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8872 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8873 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8874 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8875 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8876 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8877 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8878 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8879 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8880 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8881 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8882 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
8883 * so apparently no perfect solution yet
8885 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8886 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
8890 static struct alc_config_preset alc882_presets[] = {
8891 [ALC882_3ST_DIG] = {
8892 .mixers = { alc882_base_mixer },
8893 .init_verbs = { alc882_base_init_verbs,
8894 alc882_adc1_init_verbs },
8895 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8896 .dac_nids = alc882_dac_nids,
8897 .dig_out_nid = ALC882_DIGOUT_NID,
8898 .dig_in_nid = ALC882_DIGIN_NID,
8899 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8900 .channel_mode = alc882_ch_modes,
8902 .input_mux = &alc882_capture_source,
8904 [ALC882_6ST_DIG] = {
8905 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8906 .init_verbs = { alc882_base_init_verbs,
8907 alc882_adc1_init_verbs },
8908 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8909 .dac_nids = alc882_dac_nids,
8910 .dig_out_nid = ALC882_DIGOUT_NID,
8911 .dig_in_nid = ALC882_DIGIN_NID,
8912 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8913 .channel_mode = alc882_sixstack_modes,
8914 .input_mux = &alc882_capture_source,
8917 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8918 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8919 alc882_eapd_verbs },
8920 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8921 .dac_nids = alc882_dac_nids,
8922 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8923 .channel_mode = alc882_sixstack_modes,
8924 .input_mux = &alc882_capture_source,
8927 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8928 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8929 alc882_eapd_verbs, alc880_gpio1_init_verbs },
8930 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8931 .dac_nids = alc882_dac_nids,
8932 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8933 .channel_mode = alc880_threestack_modes,
8935 .input_mux = &alc882_capture_source,
8936 .dig_out_nid = ALC882_DIGOUT_NID,
8939 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8940 .init_verbs = { alc885_mbp3_init_verbs,
8941 alc880_gpio1_init_verbs },
8943 .dac_nids = alc882_dac_nids,
8945 .channel_mode = alc885_mbp_4ch_modes,
8946 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
8947 .input_mux = &alc882_capture_source,
8948 .dig_out_nid = ALC882_DIGOUT_NID,
8949 .dig_in_nid = ALC882_DIGIN_NID,
8950 .unsol_event = alc_automute_amp_unsol_event,
8951 .setup = alc885_mbp3_setup,
8952 .init_hook = alc_automute_amp,
8955 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8956 .init_verbs = { alc885_mb5_init_verbs,
8957 alc880_gpio1_init_verbs },
8958 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8959 .dac_nids = alc882_dac_nids,
8960 .channel_mode = alc885_mb5_6ch_modes,
8961 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8962 .input_mux = &mb5_capture_source,
8963 .dig_out_nid = ALC882_DIGOUT_NID,
8964 .dig_in_nid = ALC882_DIGIN_NID,
8967 .mixers = { alc882_macpro_mixer },
8968 .init_verbs = { alc882_macpro_init_verbs },
8969 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8970 .dac_nids = alc882_dac_nids,
8971 .dig_out_nid = ALC882_DIGOUT_NID,
8972 .dig_in_nid = ALC882_DIGIN_NID,
8973 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8974 .channel_mode = alc882_ch_modes,
8975 .input_mux = &alc882_capture_source,
8976 .init_hook = alc885_macpro_init_hook,
8979 .mixers = { alc885_imac24_mixer },
8980 .init_verbs = { alc885_imac24_init_verbs },
8981 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8982 .dac_nids = alc882_dac_nids,
8983 .dig_out_nid = ALC882_DIGOUT_NID,
8984 .dig_in_nid = ALC882_DIGIN_NID,
8985 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8986 .channel_mode = alc882_ch_modes,
8987 .input_mux = &alc882_capture_source,
8988 .unsol_event = alc_automute_amp_unsol_event,
8989 .setup = alc885_imac24_setup,
8990 .init_hook = alc885_imac24_init_hook,
8993 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8994 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8995 alc880_gpio3_init_verbs, alc882_targa_verbs},
8996 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8997 .dac_nids = alc882_dac_nids,
8998 .dig_out_nid = ALC882_DIGOUT_NID,
8999 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9000 .adc_nids = alc882_adc_nids,
9001 .capsrc_nids = alc882_capsrc_nids,
9002 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9003 .channel_mode = alc882_3ST_6ch_modes,
9005 .input_mux = &alc882_capture_source,
9006 .unsol_event = alc882_targa_unsol_event,
9007 .setup = alc882_targa_setup,
9008 .init_hook = alc882_targa_automute,
9010 [ALC882_ASUS_A7J] = {
9011 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9012 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9013 alc882_asus_a7j_verbs},
9014 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9015 .dac_nids = alc882_dac_nids,
9016 .dig_out_nid = ALC882_DIGOUT_NID,
9017 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9018 .adc_nids = alc882_adc_nids,
9019 .capsrc_nids = alc882_capsrc_nids,
9020 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9021 .channel_mode = alc882_3ST_6ch_modes,
9023 .input_mux = &alc882_capture_source,
9025 [ALC882_ASUS_A7M] = {
9026 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9027 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9028 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9029 alc882_asus_a7m_verbs },
9030 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9031 .dac_nids = alc882_dac_nids,
9032 .dig_out_nid = ALC882_DIGOUT_NID,
9033 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9034 .channel_mode = alc880_threestack_modes,
9036 .input_mux = &alc882_capture_source,
9038 [ALC883_3ST_2ch_DIG] = {
9039 .mixers = { alc883_3ST_2ch_mixer },
9040 .init_verbs = { alc883_init_verbs },
9041 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9042 .dac_nids = alc883_dac_nids,
9043 .dig_out_nid = ALC883_DIGOUT_NID,
9044 .dig_in_nid = ALC883_DIGIN_NID,
9045 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9046 .channel_mode = alc883_3ST_2ch_modes,
9047 .input_mux = &alc883_capture_source,
9049 [ALC883_3ST_6ch_DIG] = {
9050 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9051 .init_verbs = { alc883_init_verbs },
9052 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9053 .dac_nids = alc883_dac_nids,
9054 .dig_out_nid = ALC883_DIGOUT_NID,
9055 .dig_in_nid = ALC883_DIGIN_NID,
9056 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9057 .channel_mode = alc883_3ST_6ch_modes,
9059 .input_mux = &alc883_capture_source,
9061 [ALC883_3ST_6ch] = {
9062 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9063 .init_verbs = { alc883_init_verbs },
9064 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9065 .dac_nids = alc883_dac_nids,
9066 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9067 .channel_mode = alc883_3ST_6ch_modes,
9069 .input_mux = &alc883_capture_source,
9071 [ALC883_3ST_6ch_INTEL] = {
9072 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9073 .init_verbs = { alc883_init_verbs },
9074 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9075 .dac_nids = alc883_dac_nids,
9076 .dig_out_nid = ALC883_DIGOUT_NID,
9077 .dig_in_nid = ALC883_DIGIN_NID,
9078 .slave_dig_outs = alc883_slave_dig_outs,
9079 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9080 .channel_mode = alc883_3ST_6ch_intel_modes,
9082 .input_mux = &alc883_3stack_6ch_intel,
9085 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9086 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9087 alc_hp15_unsol_verbs },
9088 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9089 .dac_nids = alc883_dac_nids,
9090 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9091 .adc_nids = alc889_adc_nids,
9092 .dig_out_nid = ALC883_DIGOUT_NID,
9093 .dig_in_nid = ALC883_DIGIN_NID,
9094 .slave_dig_outs = alc883_slave_dig_outs,
9095 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9096 .channel_mode = alc889_8ch_intel_modes,
9097 .capsrc_nids = alc889_capsrc_nids,
9098 .input_mux = &alc889_capture_source,
9099 .setup = alc889_automute_setup,
9100 .init_hook = alc_automute_amp,
9101 .unsol_event = alc_automute_amp_unsol_event,
9105 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9106 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9107 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9108 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9109 .dac_nids = alc883_dac_nids,
9110 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9111 .adc_nids = alc889_adc_nids,
9112 .dig_out_nid = ALC883_DIGOUT_NID,
9113 .dig_in_nid = ALC883_DIGIN_NID,
9114 .slave_dig_outs = alc883_slave_dig_outs,
9115 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9116 .channel_mode = alc889_8ch_intel_modes,
9117 .capsrc_nids = alc889_capsrc_nids,
9118 .input_mux = &alc889_capture_source,
9119 .setup = alc889_automute_setup,
9120 .init_hook = alc889_intel_init_hook,
9121 .unsol_event = alc_automute_amp_unsol_event,
9124 [ALC883_6ST_DIG] = {
9125 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9126 .init_verbs = { alc883_init_verbs },
9127 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9128 .dac_nids = alc883_dac_nids,
9129 .dig_out_nid = ALC883_DIGOUT_NID,
9130 .dig_in_nid = ALC883_DIGIN_NID,
9131 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9132 .channel_mode = alc883_sixstack_modes,
9133 .input_mux = &alc883_capture_source,
9135 [ALC883_TARGA_DIG] = {
9136 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9137 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9138 alc883_targa_verbs},
9139 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9140 .dac_nids = alc883_dac_nids,
9141 .dig_out_nid = ALC883_DIGOUT_NID,
9142 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9143 .channel_mode = alc883_3ST_6ch_modes,
9145 .input_mux = &alc883_capture_source,
9146 .unsol_event = alc883_targa_unsol_event,
9147 .setup = alc882_targa_setup,
9148 .init_hook = alc882_targa_automute,
9150 [ALC883_TARGA_2ch_DIG] = {
9151 .mixers = { alc883_targa_2ch_mixer},
9152 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9153 alc883_targa_verbs},
9154 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9155 .dac_nids = alc883_dac_nids,
9156 .adc_nids = alc883_adc_nids_alt,
9157 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9158 .dig_out_nid = ALC883_DIGOUT_NID,
9159 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9160 .channel_mode = alc883_3ST_2ch_modes,
9161 .input_mux = &alc883_capture_source,
9162 .unsol_event = alc883_targa_unsol_event,
9163 .setup = alc882_targa_setup,
9164 .init_hook = alc882_targa_automute,
9166 [ALC883_TARGA_8ch_DIG] = {
9167 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9168 alc883_chmode_mixer },
9169 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9170 alc883_targa_verbs },
9171 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9172 .dac_nids = alc883_dac_nids,
9173 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9174 .adc_nids = alc883_adc_nids_rev,
9175 .capsrc_nids = alc883_capsrc_nids_rev,
9176 .dig_out_nid = ALC883_DIGOUT_NID,
9177 .dig_in_nid = ALC883_DIGIN_NID,
9178 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9179 .channel_mode = alc883_4ST_8ch_modes,
9181 .input_mux = &alc883_capture_source,
9182 .unsol_event = alc883_targa_unsol_event,
9183 .setup = alc882_targa_setup,
9184 .init_hook = alc882_targa_automute,
9187 .mixers = { alc883_base_mixer },
9188 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9189 * and the headphone jack. Turn this on and rely on the
9190 * standard mute methods whenever the user wants to turn
9191 * these outputs off.
9193 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9194 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9195 .dac_nids = alc883_dac_nids,
9196 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9197 .channel_mode = alc883_3ST_2ch_modes,
9198 .input_mux = &alc883_capture_source,
9200 [ALC883_ACER_ASPIRE] = {
9201 .mixers = { alc883_acer_aspire_mixer },
9202 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9203 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9204 .dac_nids = alc883_dac_nids,
9205 .dig_out_nid = ALC883_DIGOUT_NID,
9206 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9207 .channel_mode = alc883_3ST_2ch_modes,
9208 .input_mux = &alc883_capture_source,
9209 .unsol_event = alc_automute_amp_unsol_event,
9210 .setup = alc883_acer_aspire_setup,
9211 .init_hook = alc_automute_amp,
9213 [ALC888_ACER_ASPIRE_4930G] = {
9214 .mixers = { alc888_base_mixer,
9215 alc883_chmode_mixer },
9216 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9217 alc888_acer_aspire_4930g_verbs },
9218 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9219 .dac_nids = alc883_dac_nids,
9220 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9221 .adc_nids = alc883_adc_nids_rev,
9222 .capsrc_nids = alc883_capsrc_nids_rev,
9223 .dig_out_nid = ALC883_DIGOUT_NID,
9224 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9225 .channel_mode = alc883_3ST_6ch_modes,
9228 ARRAY_SIZE(alc888_2_capture_sources),
9229 .input_mux = alc888_2_capture_sources,
9230 .unsol_event = alc_automute_amp_unsol_event,
9231 .setup = alc888_acer_aspire_4930g_setup,
9232 .init_hook = alc_automute_amp,
9234 [ALC888_ACER_ASPIRE_6530G] = {
9235 .mixers = { alc888_acer_aspire_6530_mixer },
9236 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9237 alc888_acer_aspire_6530g_verbs },
9238 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9239 .dac_nids = alc883_dac_nids,
9240 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9241 .adc_nids = alc883_adc_nids_rev,
9242 .capsrc_nids = alc883_capsrc_nids_rev,
9243 .dig_out_nid = ALC883_DIGOUT_NID,
9244 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9245 .channel_mode = alc883_3ST_2ch_modes,
9247 ARRAY_SIZE(alc888_2_capture_sources),
9248 .input_mux = alc888_acer_aspire_6530_sources,
9249 .unsol_event = alc_automute_amp_unsol_event,
9250 .setup = alc888_acer_aspire_6530g_setup,
9251 .init_hook = alc_automute_amp,
9253 [ALC888_ACER_ASPIRE_8930G] = {
9254 .mixers = { alc888_base_mixer,
9255 alc883_chmode_mixer },
9256 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9257 alc889_acer_aspire_8930g_verbs },
9258 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9259 .dac_nids = alc883_dac_nids,
9260 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9261 .adc_nids = alc889_adc_nids,
9262 .capsrc_nids = alc889_capsrc_nids,
9263 .dig_out_nid = ALC883_DIGOUT_NID,
9264 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9265 .channel_mode = alc883_3ST_6ch_modes,
9267 .const_channel_count = 6,
9269 ARRAY_SIZE(alc889_capture_sources),
9270 .input_mux = alc889_capture_sources,
9271 .unsol_event = alc_automute_amp_unsol_event,
9272 .setup = alc889_acer_aspire_8930g_setup,
9273 .init_hook = alc_automute_amp,
9275 [ALC888_ACER_ASPIRE_7730G] = {
9276 .mixers = { alc883_3ST_6ch_mixer,
9277 alc883_chmode_mixer },
9278 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9279 alc888_acer_aspire_7730G_verbs },
9280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9281 .dac_nids = alc883_dac_nids,
9282 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9283 .adc_nids = alc883_adc_nids_rev,
9284 .capsrc_nids = alc883_capsrc_nids_rev,
9285 .dig_out_nid = ALC883_DIGOUT_NID,
9286 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9287 .channel_mode = alc883_3ST_6ch_modes,
9289 .const_channel_count = 6,
9290 .input_mux = &alc883_capture_source,
9291 .unsol_event = alc_automute_amp_unsol_event,
9292 .setup = alc888_acer_aspire_6530g_setup,
9293 .init_hook = alc_automute_amp,
9296 .mixers = { alc883_fivestack_mixer,
9297 alc883_chmode_mixer },
9298 .init_verbs = { alc883_init_verbs,
9299 alc883_medion_eapd_verbs },
9300 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9301 .dac_nids = alc883_dac_nids,
9302 .adc_nids = alc883_adc_nids_alt,
9303 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9304 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9305 .channel_mode = alc883_sixstack_modes,
9306 .input_mux = &alc883_capture_source,
9308 [ALC883_MEDION_MD2] = {
9309 .mixers = { alc883_medion_md2_mixer},
9310 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9311 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9312 .dac_nids = alc883_dac_nids,
9313 .dig_out_nid = ALC883_DIGOUT_NID,
9314 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9315 .channel_mode = alc883_3ST_2ch_modes,
9316 .input_mux = &alc883_capture_source,
9317 .unsol_event = alc_automute_amp_unsol_event,
9318 .setup = alc883_medion_md2_setup,
9319 .init_hook = alc_automute_amp,
9321 [ALC883_LAPTOP_EAPD] = {
9322 .mixers = { alc883_base_mixer },
9323 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9324 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9325 .dac_nids = alc883_dac_nids,
9326 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9327 .channel_mode = alc883_3ST_2ch_modes,
9328 .input_mux = &alc883_capture_source,
9330 [ALC883_CLEVO_M540R] = {
9331 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9332 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9333 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9334 .dac_nids = alc883_dac_nids,
9335 .dig_out_nid = ALC883_DIGOUT_NID,
9336 .dig_in_nid = ALC883_DIGIN_NID,
9337 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9338 .channel_mode = alc883_3ST_6ch_clevo_modes,
9340 .input_mux = &alc883_capture_source,
9341 /* This machine has the hardware HP auto-muting, thus
9342 * we need no software mute via unsol event
9345 [ALC883_CLEVO_M720] = {
9346 .mixers = { alc883_clevo_m720_mixer },
9347 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9348 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9349 .dac_nids = alc883_dac_nids,
9350 .dig_out_nid = ALC883_DIGOUT_NID,
9351 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9352 .channel_mode = alc883_3ST_2ch_modes,
9353 .input_mux = &alc883_capture_source,
9354 .unsol_event = alc883_clevo_m720_unsol_event,
9355 .setup = alc883_clevo_m720_setup,
9356 .init_hook = alc883_clevo_m720_init_hook,
9358 [ALC883_LENOVO_101E_2ch] = {
9359 .mixers = { alc883_lenovo_101e_2ch_mixer},
9360 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9361 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9362 .dac_nids = alc883_dac_nids,
9363 .adc_nids = alc883_adc_nids_alt,
9364 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9365 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9366 .channel_mode = alc883_3ST_2ch_modes,
9367 .input_mux = &alc883_lenovo_101e_capture_source,
9368 .unsol_event = alc883_lenovo_101e_unsol_event,
9369 .init_hook = alc883_lenovo_101e_all_automute,
9371 [ALC883_LENOVO_NB0763] = {
9372 .mixers = { alc883_lenovo_nb0763_mixer },
9373 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9374 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9375 .dac_nids = alc883_dac_nids,
9376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9377 .channel_mode = alc883_3ST_2ch_modes,
9379 .input_mux = &alc883_lenovo_nb0763_capture_source,
9380 .unsol_event = alc_automute_amp_unsol_event,
9381 .setup = alc883_medion_md2_setup,
9382 .init_hook = alc_automute_amp,
9384 [ALC888_LENOVO_MS7195_DIG] = {
9385 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9386 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9387 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9388 .dac_nids = alc883_dac_nids,
9389 .dig_out_nid = ALC883_DIGOUT_NID,
9390 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9391 .channel_mode = alc883_3ST_6ch_modes,
9393 .input_mux = &alc883_capture_source,
9394 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9395 .init_hook = alc888_lenovo_ms7195_front_automute,
9397 [ALC883_HAIER_W66] = {
9398 .mixers = { alc883_targa_2ch_mixer},
9399 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9400 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9401 .dac_nids = alc883_dac_nids,
9402 .dig_out_nid = ALC883_DIGOUT_NID,
9403 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9404 .channel_mode = alc883_3ST_2ch_modes,
9405 .input_mux = &alc883_capture_source,
9406 .unsol_event = alc_automute_amp_unsol_event,
9407 .setup = alc883_haier_w66_setup,
9408 .init_hook = alc_automute_amp,
9411 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9412 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9413 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9414 .dac_nids = alc883_dac_nids,
9415 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9416 .channel_mode = alc888_3st_hp_modes,
9418 .input_mux = &alc883_capture_source,
9419 .unsol_event = alc_automute_amp_unsol_event,
9420 .setup = alc888_3st_hp_setup,
9421 .init_hook = alc_automute_amp,
9423 [ALC888_6ST_DELL] = {
9424 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9425 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9426 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9427 .dac_nids = alc883_dac_nids,
9428 .dig_out_nid = ALC883_DIGOUT_NID,
9429 .dig_in_nid = ALC883_DIGIN_NID,
9430 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9431 .channel_mode = alc883_sixstack_modes,
9432 .input_mux = &alc883_capture_source,
9433 .unsol_event = alc_automute_amp_unsol_event,
9434 .setup = alc888_6st_dell_setup,
9435 .init_hook = alc_automute_amp,
9438 .mixers = { alc883_mitac_mixer },
9439 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9440 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9441 .dac_nids = alc883_dac_nids,
9442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9443 .channel_mode = alc883_3ST_2ch_modes,
9444 .input_mux = &alc883_capture_source,
9445 .unsol_event = alc_automute_amp_unsol_event,
9446 .setup = alc883_mitac_setup,
9447 .init_hook = alc_automute_amp,
9449 [ALC883_FUJITSU_PI2515] = {
9450 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9451 .init_verbs = { alc883_init_verbs,
9452 alc883_2ch_fujitsu_pi2515_verbs},
9453 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9454 .dac_nids = alc883_dac_nids,
9455 .dig_out_nid = ALC883_DIGOUT_NID,
9456 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9457 .channel_mode = alc883_3ST_2ch_modes,
9458 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9459 .unsol_event = alc_automute_amp_unsol_event,
9460 .setup = alc883_2ch_fujitsu_pi2515_setup,
9461 .init_hook = alc_automute_amp,
9463 [ALC888_FUJITSU_XA3530] = {
9464 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9465 .init_verbs = { alc883_init_verbs,
9466 alc888_fujitsu_xa3530_verbs },
9467 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9468 .dac_nids = alc883_dac_nids,
9469 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9470 .adc_nids = alc883_adc_nids_rev,
9471 .capsrc_nids = alc883_capsrc_nids_rev,
9472 .dig_out_nid = ALC883_DIGOUT_NID,
9473 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9474 .channel_mode = alc888_4ST_8ch_intel_modes,
9476 ARRAY_SIZE(alc888_2_capture_sources),
9477 .input_mux = alc888_2_capture_sources,
9478 .unsol_event = alc_automute_amp_unsol_event,
9479 .setup = alc888_fujitsu_xa3530_setup,
9480 .init_hook = alc_automute_amp,
9482 [ALC888_LENOVO_SKY] = {
9483 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9484 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9485 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9486 .dac_nids = alc883_dac_nids,
9487 .dig_out_nid = ALC883_DIGOUT_NID,
9488 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9489 .channel_mode = alc883_sixstack_modes,
9491 .input_mux = &alc883_lenovo_sky_capture_source,
9492 .unsol_event = alc_automute_amp_unsol_event,
9493 .setup = alc888_lenovo_sky_setup,
9494 .init_hook = alc_automute_amp,
9496 [ALC888_ASUS_M90V] = {
9497 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9498 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9499 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9500 .dac_nids = alc883_dac_nids,
9501 .dig_out_nid = ALC883_DIGOUT_NID,
9502 .dig_in_nid = ALC883_DIGIN_NID,
9503 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9504 .channel_mode = alc883_3ST_6ch_modes,
9506 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9507 .unsol_event = alc_sku_unsol_event,
9508 .setup = alc883_mode2_setup,
9509 .init_hook = alc_inithook,
9511 [ALC888_ASUS_EEE1601] = {
9512 .mixers = { alc883_asus_eee1601_mixer },
9513 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9514 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9515 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9516 .dac_nids = alc883_dac_nids,
9517 .dig_out_nid = ALC883_DIGOUT_NID,
9518 .dig_in_nid = ALC883_DIGIN_NID,
9519 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9520 .channel_mode = alc883_3ST_2ch_modes,
9522 .input_mux = &alc883_asus_eee1601_capture_source,
9523 .unsol_event = alc_sku_unsol_event,
9524 .init_hook = alc883_eee1601_inithook,
9526 [ALC1200_ASUS_P5Q] = {
9527 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9528 .init_verbs = { alc883_init_verbs },
9529 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9530 .dac_nids = alc883_dac_nids,
9531 .dig_out_nid = ALC1200_DIGOUT_NID,
9532 .dig_in_nid = ALC883_DIGIN_NID,
9533 .slave_dig_outs = alc1200_slave_dig_outs,
9534 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9535 .channel_mode = alc883_sixstack_modes,
9536 .input_mux = &alc883_capture_source,
9539 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9540 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9541 alc880_gpio1_init_verbs },
9542 .adc_nids = alc883_adc_nids,
9543 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9544 .dac_nids = alc883_dac_nids,
9545 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9546 .channel_mode = alc889A_mb31_6ch_modes,
9547 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9548 .input_mux = &alc889A_mb31_capture_source,
9549 .dig_out_nid = ALC883_DIGOUT_NID,
9550 .unsol_event = alc889A_mb31_unsol_event,
9551 .init_hook = alc889A_mb31_automute,
9553 [ALC883_SONY_VAIO_TT] = {
9554 .mixers = { alc883_vaiott_mixer },
9555 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9556 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9557 .dac_nids = alc883_dac_nids,
9558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9559 .channel_mode = alc883_3ST_2ch_modes,
9560 .input_mux = &alc883_capture_source,
9561 .unsol_event = alc_automute_amp_unsol_event,
9562 .setup = alc883_vaiott_setup,
9563 .init_hook = alc_automute_amp,
9572 PINFIX_ABIT_AW9D_MAX
9575 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9576 { 0x15, 0x01080104 }, /* side */
9577 { 0x16, 0x01011012 }, /* rear */
9578 { 0x17, 0x01016011 }, /* clfe */
9582 static const struct alc_fixup alc882_fixups[] = {
9583 [PINFIX_ABIT_AW9D_MAX] = {
9584 .pins = alc882_abit_aw9d_pinfix
9588 static struct snd_pci_quirk alc882_fixup_tbl[] = {
9589 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9594 * BIOS auto configuration
9596 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9597 const struct auto_pin_cfg *cfg)
9599 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9602 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9603 hda_nid_t nid, int pin_type,
9607 struct alc_spec *spec = codec->spec;
9610 alc_set_pin_output(codec, nid, pin_type);
9611 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9614 idx = spec->multiout.dac_nids[dac_idx] - 2;
9615 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9619 static void alc882_auto_init_multi_out(struct hda_codec *codec)
9621 struct alc_spec *spec = codec->spec;
9624 for (i = 0; i <= HDA_SIDE; i++) {
9625 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9626 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9628 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9633 static void alc882_auto_init_hp_out(struct hda_codec *codec)
9635 struct alc_spec *spec = codec->spec;
9638 pin = spec->autocfg.hp_pins[0];
9639 if (pin) /* connect to front */
9641 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9642 pin = spec->autocfg.speaker_pins[0];
9644 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9647 static void alc882_auto_init_analog_input(struct hda_codec *codec)
9649 struct alc_spec *spec = codec->spec;
9652 for (i = 0; i < AUTO_PIN_LAST; i++) {
9653 hda_nid_t nid = spec->autocfg.input_pins[i];
9656 alc_set_input_pin(codec, nid, i);
9657 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9658 snd_hda_codec_write(codec, nid, 0,
9659 AC_VERB_SET_AMP_GAIN_MUTE,
9664 static void alc882_auto_init_input_src(struct hda_codec *codec)
9666 struct alc_spec *spec = codec->spec;
9669 for (c = 0; c < spec->num_adc_nids; c++) {
9670 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9671 hda_nid_t nid = spec->capsrc_nids[c];
9672 unsigned int mux_idx;
9673 const struct hda_input_mux *imux;
9674 int conns, mute, idx, item;
9676 conns = snd_hda_get_connections(codec, nid, conn_list,
9677 ARRAY_SIZE(conn_list));
9680 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9681 imux = &spec->input_mux[mux_idx];
9682 for (idx = 0; idx < conns; idx++) {
9683 /* if the current connection is the selected one,
9684 * unmute it as default - otherwise mute it
9686 mute = AMP_IN_MUTE(idx);
9687 for (item = 0; item < imux->num_items; item++) {
9688 if (imux->items[item].index == idx) {
9689 if (spec->cur_mux[c] == item)
9690 mute = AMP_IN_UNMUTE(idx);
9694 /* check if we have a selector or mixer
9695 * we could check for the widget type instead, but
9696 * just check for Amp-In presence (in case of mixer
9697 * without amp-in there is something wrong, this
9698 * function shouldn't be used or capsrc nid is wrong)
9700 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9701 snd_hda_codec_write(codec, nid, 0,
9702 AC_VERB_SET_AMP_GAIN_MUTE,
9704 else if (mute != AMP_IN_MUTE(idx))
9705 snd_hda_codec_write(codec, nid, 0,
9706 AC_VERB_SET_CONNECT_SEL,
9712 /* add mic boosts if needed */
9713 static int alc_auto_add_mic_boost(struct hda_codec *codec)
9715 struct alc_spec *spec = codec->spec;
9719 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9720 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9721 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9723 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9727 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9728 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9729 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9731 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9738 /* almost identical with ALC880 parser... */
9739 static int alc882_parse_auto_config(struct hda_codec *codec)
9741 struct alc_spec *spec = codec->spec;
9742 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
9745 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9749 if (!spec->autocfg.line_outs)
9750 return 0; /* can't find valid BIOS pin config */
9752 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9755 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
9758 err = alc880_auto_create_extra_out(spec,
9759 spec->autocfg.speaker_pins[0],
9763 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
9767 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
9771 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9773 /* check multiple SPDIF-out (for recent codecs) */
9774 for (i = 0; i < spec->autocfg.dig_outs; i++) {
9776 err = snd_hda_get_connections(codec,
9777 spec->autocfg.dig_out_pins[i],
9782 spec->multiout.dig_out_nid = dig_nid;
9784 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9785 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
9787 spec->slave_dig_outs[i - 1] = dig_nid;
9790 if (spec->autocfg.dig_in_pin)
9791 spec->dig_in_nid = ALC880_DIGIN_NID;
9793 if (spec->kctls.list)
9794 add_mixer(spec, spec->kctls.list);
9796 add_verb(spec, alc883_auto_init_verbs);
9797 /* if ADC 0x07 is available, initialize it, too */
9798 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
9799 add_verb(spec, alc882_adc1_init_verbs);
9801 spec->num_mux_defs = 1;
9802 spec->input_mux = &spec->private_imux[0];
9804 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
9806 err = alc_auto_add_mic_boost(codec);
9810 return 1; /* config found */
9813 /* additional initialization for auto-configuration model */
9814 static void alc882_auto_init(struct hda_codec *codec)
9816 struct alc_spec *spec = codec->spec;
9817 alc882_auto_init_multi_out(codec);
9818 alc882_auto_init_hp_out(codec);
9819 alc882_auto_init_analog_input(codec);
9820 alc882_auto_init_input_src(codec);
9821 if (spec->unsol_event)
9822 alc_inithook(codec);
9825 static int patch_alc882(struct hda_codec *codec)
9827 struct alc_spec *spec;
9828 int err, board_config;
9830 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9836 switch (codec->vendor_id) {
9841 /* ALC883 and variants */
9842 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9846 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9850 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9851 board_config = snd_hda_check_board_codec_sid_config(codec,
9852 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9854 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9855 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
9857 board_config = ALC882_AUTO;
9860 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
9862 if (board_config == ALC882_AUTO) {
9863 /* automatic parse from the BIOS config */
9864 err = alc882_parse_auto_config(codec);
9870 "hda_codec: Cannot set up configuration "
9871 "from BIOS. Using base mode...\n");
9872 board_config = ALC882_3ST_DIG;
9876 err = snd_hda_attach_beep_device(codec, 0x1);
9882 if (board_config != ALC882_AUTO)
9883 setup_preset(codec, &alc882_presets[board_config]);
9885 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9886 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9887 /* FIXME: setup DAC5 */
9888 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9889 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9891 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9892 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9894 if (codec->vendor_id == 0x10ec0888)
9895 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9897 if (!spec->adc_nids && spec->input_mux) {
9899 spec->num_adc_nids = 0;
9900 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9902 hda_nid_t nid = alc882_adc_nids[i];
9903 unsigned int wcap = get_wcaps(codec, nid);
9905 wcap = get_wcaps_type(wcap);
9906 if (wcap != AC_WID_AUD_IN)
9908 spec->private_adc_nids[spec->num_adc_nids] = nid;
9909 err = snd_hda_get_connections(codec, nid, &cap, 1);
9912 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9913 spec->num_adc_nids++;
9915 spec->adc_nids = spec->private_adc_nids;
9916 spec->capsrc_nids = spec->private_capsrc_nids;
9919 set_capture_mixer(codec);
9920 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9922 spec->vmaster_nid = 0x0c;
9924 codec->patch_ops = alc_patch_ops;
9925 if (board_config == ALC882_AUTO)
9926 spec->init_hook = alc882_auto_init;
9927 #ifdef CONFIG_SND_HDA_POWER_SAVE
9928 if (!spec->loopback.amplist)
9929 spec->loopback.amplist = alc882_loopbacks;
9931 codec->proc_widget_hook = print_realtek_coef;
9941 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9942 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9944 #define alc262_dac_nids alc260_dac_nids
9945 #define alc262_adc_nids alc882_adc_nids
9946 #define alc262_adc_nids_alt alc882_adc_nids_alt
9947 #define alc262_capsrc_nids alc882_capsrc_nids
9948 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9950 #define alc262_modes alc260_modes
9951 #define alc262_capture_source alc882_capture_source
9953 static hda_nid_t alc262_dmic_adc_nids[1] = {
9958 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9960 static struct snd_kcontrol_new alc262_base_mixer[] = {
9961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9962 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9963 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9964 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9965 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9966 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9967 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9968 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9969 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9970 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9971 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9972 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9973 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9974 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9975 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9976 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9980 /* update HP, line and mono-out pins according to the master switch */
9981 static void alc262_hp_master_update(struct hda_codec *codec)
9983 struct alc_spec *spec = codec->spec;
9984 int val = spec->master_sw;
9987 snd_hda_codec_write_cache(codec, 0x1b, 0,
9988 AC_VERB_SET_PIN_WIDGET_CONTROL,
9990 snd_hda_codec_write_cache(codec, 0x15, 0,
9991 AC_VERB_SET_PIN_WIDGET_CONTROL,
9993 /* mono (speaker) depending on the HP jack sense */
9994 val = val && !spec->jack_present;
9995 snd_hda_codec_write_cache(codec, 0x16, 0,
9996 AC_VERB_SET_PIN_WIDGET_CONTROL,
10000 static void alc262_hp_bpc_automute(struct hda_codec *codec)
10002 struct alc_spec *spec = codec->spec;
10004 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10005 alc262_hp_master_update(codec);
10008 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10010 if ((res >> 26) != ALC880_HP_EVENT)
10012 alc262_hp_bpc_automute(codec);
10015 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10017 struct alc_spec *spec = codec->spec;
10019 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10020 alc262_hp_master_update(codec);
10023 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10026 if ((res >> 26) != ALC880_HP_EVENT)
10028 alc262_hp_wildwest_automute(codec);
10031 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
10033 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10034 struct snd_ctl_elem_value *ucontrol)
10036 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10037 struct alc_spec *spec = codec->spec;
10038 int val = !!*ucontrol->value.integer.value;
10040 if (val == spec->master_sw)
10042 spec->master_sw = val;
10043 alc262_hp_master_update(codec);
10047 #define ALC262_HP_MASTER_SWITCH \
10049 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10050 .name = "Master Playback Switch", \
10051 .info = snd_ctl_boolean_mono_info, \
10052 .get = alc262_hp_master_sw_get, \
10053 .put = alc262_hp_master_sw_put, \
10056 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10057 ALC262_HP_MASTER_SWITCH,
10058 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10059 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10061 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10063 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10067 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10068 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10070 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10071 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10072 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10073 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10074 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10075 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10076 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10080 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10081 ALC262_HP_MASTER_SWITCH,
10082 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10083 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10084 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10086 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10088 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10090 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10091 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10092 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10093 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10094 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10095 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10096 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10100 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10101 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10102 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10103 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10107 /* mute/unmute internal speaker according to the hp jack and mute state */
10108 static void alc262_hp_t5735_setup(struct hda_codec *codec)
10110 struct alc_spec *spec = codec->spec;
10112 spec->autocfg.hp_pins[0] = 0x15;
10113 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
10116 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10117 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10118 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10119 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10122 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10123 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10127 static struct hda_verb alc262_hp_t5735_verbs[] = {
10128 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10129 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10135 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10136 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10138 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10139 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10145 static struct hda_verb alc262_hp_rp5700_verbs[] = {
10146 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10147 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10151 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10159 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10166 /* bind hp and internal speaker mute (with plug check) as master switch */
10167 static void alc262_hippo_master_update(struct hda_codec *codec)
10169 struct alc_spec *spec = codec->spec;
10170 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10171 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10172 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10176 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10177 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10178 HDA_AMP_MUTE, mute);
10179 /* mute internal speaker per jack sense */
10180 if (spec->jack_present)
10181 mute = HDA_AMP_MUTE;
10183 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10184 HDA_AMP_MUTE, mute);
10185 if (speaker_nid && speaker_nid != line_nid)
10186 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10187 HDA_AMP_MUTE, mute);
10190 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10192 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10193 struct snd_ctl_elem_value *ucontrol)
10195 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10196 struct alc_spec *spec = codec->spec;
10197 int val = !!*ucontrol->value.integer.value;
10199 if (val == spec->master_sw)
10201 spec->master_sw = val;
10202 alc262_hippo_master_update(codec);
10206 #define ALC262_HIPPO_MASTER_SWITCH \
10208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10209 .name = "Master Playback Switch", \
10210 .info = snd_ctl_boolean_mono_info, \
10211 .get = alc262_hippo_master_sw_get, \
10212 .put = alc262_hippo_master_sw_put, \
10215 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10216 ALC262_HIPPO_MASTER_SWITCH,
10217 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10218 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10219 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10220 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10221 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10222 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10223 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10224 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10225 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10226 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10227 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10228 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10232 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10233 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10234 ALC262_HIPPO_MASTER_SWITCH,
10235 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10236 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10237 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10238 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10241 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10242 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10243 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10244 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10248 /* mute/unmute internal speaker according to the hp jack and mute state */
10249 static void alc262_hippo_automute(struct hda_codec *codec)
10251 struct alc_spec *spec = codec->spec;
10252 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10254 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
10255 alc262_hippo_master_update(codec);
10258 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10260 if ((res >> 26) != ALC880_HP_EVENT)
10262 alc262_hippo_automute(codec);
10265 static void alc262_hippo_setup(struct hda_codec *codec)
10267 struct alc_spec *spec = codec->spec;
10269 spec->autocfg.hp_pins[0] = 0x15;
10270 spec->autocfg.speaker_pins[0] = 0x14;
10273 static void alc262_hippo1_setup(struct hda_codec *codec)
10275 struct alc_spec *spec = codec->spec;
10277 spec->autocfg.hp_pins[0] = 0x1b;
10278 spec->autocfg.speaker_pins[0] = 0x14;
10282 static struct snd_kcontrol_new alc262_sony_mixer[] = {
10283 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10284 ALC262_HIPPO_MASTER_SWITCH,
10285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10287 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10288 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10292 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10293 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10294 ALC262_HIPPO_MASTER_SWITCH,
10295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10298 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10299 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10303 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10304 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10305 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10306 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10307 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10308 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10309 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10311 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10312 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10313 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10314 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10315 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10319 static struct hda_verb alc262_tyan_verbs[] = {
10320 /* Headphone automute */
10321 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10322 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10323 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10325 /* P11 AUX_IN, white 4-pin connector */
10326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10327 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10328 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10329 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10334 /* unsolicited event for HP jack sensing */
10335 static void alc262_tyan_setup(struct hda_codec *codec)
10337 struct alc_spec *spec = codec->spec;
10339 spec->autocfg.hp_pins[0] = 0x1b;
10340 spec->autocfg.speaker_pins[0] = 0x15;
10344 #define alc262_capture_mixer alc882_capture_mixer
10345 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
10348 * generic initialization of ADC, input mixers and output mixers
10350 static struct hda_verb alc262_init_verbs[] = {
10352 * Unmute ADC0-2 and set the default input to mic-in
10354 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10355 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10356 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10357 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10358 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10359 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10361 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10363 * Note: PASD motherboards uses the Line In 2 as the input for
10364 * front panel mic (mic 2)
10366 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10367 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10374 * Set up output mixers (0x0c - 0x0e)
10376 /* set vol=0 to output mixers */
10377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10378 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10380 /* set up input amps for analog loopback */
10381 /* Amp Indices: DAC = 0, mixer = 1 */
10382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10384 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10386 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10392 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10393 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10394 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10396 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10398 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10400 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10402 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10403 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10405 /* FIXME: use matrix-type input source selection */
10406 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10407 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10411 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10420 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10426 static struct hda_verb alc262_eapd_verbs[] = {
10427 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10428 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10432 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10434 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10435 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10437 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10442 static struct hda_verb alc262_sony_unsol_verbs[] = {
10443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10444 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10445 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10447 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10448 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10452 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10453 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10454 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10461 static struct hda_verb alc262_toshiba_s06_verbs[] = {
10462 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10463 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10465 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10466 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10468 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10469 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10473 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
10475 struct alc_spec *spec = codec->spec;
10477 spec->autocfg.hp_pins[0] = 0x15;
10478 spec->autocfg.speaker_pins[0] = 0x14;
10479 spec->ext_mic.pin = 0x18;
10480 spec->ext_mic.mux_idx = 0;
10481 spec->int_mic.pin = 0x12;
10482 spec->int_mic.mux_idx = 9;
10483 spec->auto_mic = 1;
10489 * 0x16 = internal speaker
10490 * 0x18 = external mic
10493 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10494 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10495 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10499 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10501 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10506 static struct hda_verb alc262_nec_verbs[] = {
10507 /* Unmute Speaker */
10508 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10511 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10514 /* External mic to headphone */
10515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10516 /* External mic to speaker */
10517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10523 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10524 * 0x1b = port replicator headphone out
10527 #define ALC_HP_EVENT 0x37
10529 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10530 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10532 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10533 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10537 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10538 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10543 static struct hda_input_mux alc262_fujitsu_capture_source = {
10547 { "Int Mic", 0x1 },
10552 static struct hda_input_mux alc262_HP_capture_source = {
10556 { "Front Mic", 0x1 },
10563 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10567 { "Front Mic", 0x2 },
10573 /* mute/unmute internal speaker according to the hp jacks and mute state */
10574 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10576 struct alc_spec *spec = codec->spec;
10579 if (force || !spec->sense_updated) {
10580 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
10581 snd_hda_jack_detect(codec, 0x1b);
10582 spec->sense_updated = 1;
10584 /* unmute internal speaker only if both HPs are unplugged and
10585 * master switch is on
10587 if (spec->jack_present)
10588 mute = HDA_AMP_MUTE;
10590 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10591 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10592 HDA_AMP_MUTE, mute);
10595 /* unsolicited event for HP jack sensing */
10596 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10599 if ((res >> 26) != ALC_HP_EVENT)
10601 alc262_fujitsu_automute(codec, 1);
10604 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10606 alc262_fujitsu_automute(codec, 1);
10609 /* bind volumes of both NID 0x0c and 0x0d */
10610 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10611 .ops = &snd_hda_bind_vol,
10613 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10614 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10619 /* mute/unmute internal speaker according to the hp jack and mute state */
10620 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10622 struct alc_spec *spec = codec->spec;
10625 if (force || !spec->sense_updated) {
10626 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10627 spec->sense_updated = 1;
10629 if (spec->jack_present) {
10630 /* mute internal speaker */
10631 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10632 HDA_AMP_MUTE, HDA_AMP_MUTE);
10633 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10634 HDA_AMP_MUTE, HDA_AMP_MUTE);
10636 /* unmute internal speaker if necessary */
10637 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10638 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10639 HDA_AMP_MUTE, mute);
10640 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10641 HDA_AMP_MUTE, mute);
10645 /* unsolicited event for HP jack sensing */
10646 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10649 if ((res >> 26) != ALC_HP_EVENT)
10651 alc262_lenovo_3000_automute(codec, 1);
10654 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
10655 int dir, int idx, long *valp)
10659 for (i = 0; i < 2; i++, valp++)
10660 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
10662 *valp ? 0 : HDA_AMP_MUTE);
10666 /* bind hp and internal speaker mute (with plug check) */
10667 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10668 struct snd_ctl_elem_value *ucontrol)
10670 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10671 long *valp = ucontrol->value.integer.value;
10674 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
10675 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10677 alc262_fujitsu_automute(codec, 0);
10681 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10682 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10685 .name = "Master Playback Switch",
10686 .info = snd_hda_mixer_amp_switch_info,
10687 .get = snd_hda_mixer_amp_switch_get,
10688 .put = alc262_fujitsu_master_sw_put,
10689 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10691 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10692 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10693 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10694 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10695 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10697 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10698 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10702 /* bind hp and internal speaker mute (with plug check) */
10703 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10704 struct snd_ctl_elem_value *ucontrol)
10706 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10707 long *valp = ucontrol->value.integer.value;
10710 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10712 alc262_lenovo_3000_automute(codec, 0);
10716 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10717 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10719 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10720 .name = "Master Playback Switch",
10721 .info = snd_hda_mixer_amp_switch_info,
10722 .get = snd_hda_mixer_amp_switch_get,
10723 .put = alc262_lenovo_3000_master_sw_put,
10724 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10726 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10727 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10728 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10731 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10732 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10733 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10737 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10738 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10739 ALC262_HIPPO_MASTER_SWITCH,
10740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10742 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10743 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10744 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10745 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10749 /* additional init verbs for Benq laptops */
10750 static struct hda_verb alc262_EAPD_verbs[] = {
10751 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10752 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10756 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10758 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10760 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10761 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10765 /* Samsung Q1 Ultra Vista model setup */
10766 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10767 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10768 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10771 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10772 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10776 static struct hda_verb alc262_ultra_verbs[] = {
10778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10779 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10782 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10784 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10785 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10787 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10788 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10789 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10790 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10795 /* ADC, choose mic */
10796 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10797 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10798 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10799 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10800 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10801 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10802 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10803 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10809 /* mute/unmute internal speaker according to the hp jack and mute state */
10810 static void alc262_ultra_automute(struct hda_codec *codec)
10812 struct alc_spec *spec = codec->spec;
10816 /* auto-mute only when HP is used as HP */
10817 if (!spec->cur_mux[0]) {
10818 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10819 if (spec->jack_present)
10820 mute = HDA_AMP_MUTE;
10822 /* mute/unmute internal speaker */
10823 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10824 HDA_AMP_MUTE, mute);
10825 /* mute/unmute HP */
10826 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10827 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10830 /* unsolicited event for HP jack sensing */
10831 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10834 if ((res >> 26) != ALC880_HP_EVENT)
10836 alc262_ultra_automute(codec);
10839 static struct hda_input_mux alc262_ultra_capture_source = {
10843 { "Headphone", 0x7 },
10847 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10848 struct snd_ctl_elem_value *ucontrol)
10850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10851 struct alc_spec *spec = codec->spec;
10854 ret = alc_mux_enum_put(kcontrol, ucontrol);
10857 /* reprogram the HP pin as mic or HP according to the input source */
10858 snd_hda_codec_write_cache(codec, 0x15, 0,
10859 AC_VERB_SET_PIN_WIDGET_CONTROL,
10860 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10861 alc262_ultra_automute(codec); /* mute/unmute HP */
10865 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10866 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10867 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10870 .name = "Capture Source",
10871 .info = alc_mux_enum_info,
10872 .get = alc_mux_enum_get,
10873 .put = alc262_ultra_mux_enum_put,
10878 /* We use two mixers depending on the output pin; 0x16 is a mono output
10879 * and thus it's bound with a different mixer.
10880 * This function returns which mixer amp should be used.
10882 static int alc262_check_volbit(hda_nid_t nid)
10886 else if (nid == 0x16)
10892 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10893 const char *pfx, int *vbits)
10898 vbit = alc262_check_volbit(nid);
10901 if (*vbits & vbit) /* a volume control for this mixer already there */
10905 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
10907 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
10908 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
10911 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
10919 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
10921 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
10922 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
10925 /* add playback controls from the parsed DAC table */
10926 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10927 const struct auto_pin_cfg *cfg)
10933 spec->multiout.num_dacs = 1; /* only use one dac */
10934 spec->multiout.dac_nids = spec->private_dac_nids;
10935 spec->multiout.dac_nids[0] = 2;
10937 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
10939 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10943 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
10946 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
10949 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
10953 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
10954 alc262_check_volbit(cfg->speaker_pins[0]) |
10955 alc262_check_volbit(cfg->hp_pins[0]);
10956 if (vbits == 1 || vbits == 2)
10957 pfx = "Master"; /* only one mixer is used */
10958 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10963 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
10966 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
10970 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
10977 #define alc262_auto_create_input_ctls \
10978 alc880_auto_create_input_ctls
10981 * generic initialization of ADC, input mixers and output mixers
10983 static struct hda_verb alc262_volume_init_verbs[] = {
10985 * Unmute ADC0-2 and set the default input to mic-in
10987 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10988 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10989 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10990 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10991 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10994 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10996 * Note: PASD motherboards uses the Line In 2 as the input for
10997 * front panel mic (mic 2)
10999 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11000 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11001 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11002 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11003 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11007 * Set up output mixers (0x0c - 0x0f)
11009 /* set vol=0 to output mixers */
11010 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11011 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11012 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11014 /* set up input amps for analog loopback */
11015 /* Amp Indices: DAC = 0, mixer = 1 */
11016 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11020 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11023 /* FIXME: use matrix-type input source selection */
11024 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11025 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11031 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11032 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11033 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11034 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11044 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11046 * Unmute ADC0-2 and set the default input to mic-in
11048 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11050 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11051 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11052 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11053 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11055 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11057 * Note: PASD motherboards uses the Line In 2 as the input for
11058 * front panel mic (mic 2)
11060 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11070 * Set up output mixers (0x0c - 0x0e)
11072 /* set vol=0 to output mixers */
11073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11074 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11075 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11077 /* set up input amps for analog loopback */
11078 /* Amp Indices: DAC = 0, mixer = 1 */
11079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11081 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11083 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11084 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11086 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11090 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11093 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11094 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11096 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11097 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11098 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11099 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11100 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11102 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11103 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11104 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11105 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11106 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11107 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11110 /* FIXME: use matrix-type input source selection */
11111 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11112 /* Input mixer1: only unmute Mic */
11113 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11114 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11119 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11125 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11129 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11130 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11131 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11134 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11135 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11136 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11137 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11138 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11143 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11148 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11150 * Unmute ADC0-2 and set the default input to mic-in
11152 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11154 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11156 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11159 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11161 * Note: PASD motherboards uses the Line In 2 as the input for front
11162 * panel mic (mic 2)
11164 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11165 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11166 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11168 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11174 * Set up output mixers (0x0c - 0x0e)
11176 /* set vol=0 to output mixers */
11177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11181 /* set up input amps for analog loopback */
11182 /* Amp Indices: DAC = 0, mixer = 1 */
11183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11186 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11187 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11188 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11191 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11192 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11193 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11195 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11197 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11199 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11202 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11205 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11206 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11207 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11208 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11209 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11210 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11212 /* FIXME: use matrix-type input source selection */
11213 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11214 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11215 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11216 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11220 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11223 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11224 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11225 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11226 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11227 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11228 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11229 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11231 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11232 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11233 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11234 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11235 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11236 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11239 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11244 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11246 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11247 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11248 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11250 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11251 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11252 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11253 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11257 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11262 #ifdef CONFIG_SND_HDA_POWER_SAVE
11263 #define alc262_loopbacks alc880_loopbacks
11266 /* pcm configuration: identical with ALC880 */
11267 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
11268 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
11269 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
11270 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
11273 * BIOS auto configuration
11275 static int alc262_parse_auto_config(struct hda_codec *codec)
11277 struct alc_spec *spec = codec->spec;
11279 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11281 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11285 if (!spec->autocfg.line_outs) {
11286 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11287 spec->multiout.max_channels = 2;
11288 spec->no_analog = 1;
11291 return 0; /* can't find valid BIOS pin config */
11293 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11296 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11300 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11303 if (spec->autocfg.dig_outs) {
11304 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11305 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11307 if (spec->autocfg.dig_in_pin)
11308 spec->dig_in_nid = ALC262_DIGIN_NID;
11310 if (spec->kctls.list)
11311 add_mixer(spec, spec->kctls.list);
11313 add_verb(spec, alc262_volume_init_verbs);
11314 spec->num_mux_defs = 1;
11315 spec->input_mux = &spec->private_imux[0];
11317 err = alc_auto_add_mic_boost(codec);
11321 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11326 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
11327 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
11328 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
11329 #define alc262_auto_init_input_src alc882_auto_init_input_src
11332 /* init callback for auto-configuration model -- overriding the default init */
11333 static void alc262_auto_init(struct hda_codec *codec)
11335 struct alc_spec *spec = codec->spec;
11336 alc262_auto_init_multi_out(codec);
11337 alc262_auto_init_hp_out(codec);
11338 alc262_auto_init_analog_input(codec);
11339 alc262_auto_init_input_src(codec);
11340 if (spec->unsol_event)
11341 alc_inithook(codec);
11345 * configuration and preset
11347 static const char *alc262_models[ALC262_MODEL_LAST] = {
11348 [ALC262_BASIC] = "basic",
11349 [ALC262_HIPPO] = "hippo",
11350 [ALC262_HIPPO_1] = "hippo_1",
11351 [ALC262_FUJITSU] = "fujitsu",
11352 [ALC262_HP_BPC] = "hp-bpc",
11353 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11354 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
11355 [ALC262_HP_RP5700] = "hp-rp5700",
11356 [ALC262_BENQ_ED8] = "benq",
11357 [ALC262_BENQ_T31] = "benq-t31",
11358 [ALC262_SONY_ASSAMD] = "sony-assamd",
11359 [ALC262_TOSHIBA_S06] = "toshiba-s06",
11360 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
11361 [ALC262_ULTRA] = "ultra",
11362 [ALC262_LENOVO_3000] = "lenovo-3000",
11363 [ALC262_NEC] = "nec",
11364 [ALC262_TYAN] = "tyan",
11365 [ALC262_AUTO] = "auto",
11368 static struct snd_pci_quirk alc262_cfg_tbl[] = {
11369 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11370 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11371 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11373 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11375 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11377 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11378 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11379 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11380 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11381 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11382 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11383 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11384 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11385 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11386 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11387 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11388 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11389 ALC262_HP_TC_T5735),
11390 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11391 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11392 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11393 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11394 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11395 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11396 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11397 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
11398 #if 0 /* disable the quirk since model=auto works better in recent versions */
11399 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11400 ALC262_SONY_ASSAMD),
11402 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11403 ALC262_TOSHIBA_RX1),
11404 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11405 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11406 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11407 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11408 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11410 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11411 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11412 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11413 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11414 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11418 static struct alc_config_preset alc262_presets[] = {
11420 .mixers = { alc262_base_mixer },
11421 .init_verbs = { alc262_init_verbs },
11422 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11423 .dac_nids = alc262_dac_nids,
11425 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11426 .channel_mode = alc262_modes,
11427 .input_mux = &alc262_capture_source,
11430 .mixers = { alc262_hippo_mixer },
11431 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11432 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11433 .dac_nids = alc262_dac_nids,
11435 .dig_out_nid = ALC262_DIGOUT_NID,
11436 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11437 .channel_mode = alc262_modes,
11438 .input_mux = &alc262_capture_source,
11439 .unsol_event = alc262_hippo_unsol_event,
11440 .setup = alc262_hippo_setup,
11441 .init_hook = alc262_hippo_automute,
11443 [ALC262_HIPPO_1] = {
11444 .mixers = { alc262_hippo1_mixer },
11445 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11446 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11447 .dac_nids = alc262_dac_nids,
11449 .dig_out_nid = ALC262_DIGOUT_NID,
11450 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11451 .channel_mode = alc262_modes,
11452 .input_mux = &alc262_capture_source,
11453 .unsol_event = alc262_hippo_unsol_event,
11454 .setup = alc262_hippo1_setup,
11455 .init_hook = alc262_hippo_automute,
11457 [ALC262_FUJITSU] = {
11458 .mixers = { alc262_fujitsu_mixer },
11459 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11460 alc262_fujitsu_unsol_verbs },
11461 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11462 .dac_nids = alc262_dac_nids,
11464 .dig_out_nid = ALC262_DIGOUT_NID,
11465 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11466 .channel_mode = alc262_modes,
11467 .input_mux = &alc262_fujitsu_capture_source,
11468 .unsol_event = alc262_fujitsu_unsol_event,
11469 .init_hook = alc262_fujitsu_init_hook,
11471 [ALC262_HP_BPC] = {
11472 .mixers = { alc262_HP_BPC_mixer },
11473 .init_verbs = { alc262_HP_BPC_init_verbs },
11474 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11475 .dac_nids = alc262_dac_nids,
11477 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11478 .channel_mode = alc262_modes,
11479 .input_mux = &alc262_HP_capture_source,
11480 .unsol_event = alc262_hp_bpc_unsol_event,
11481 .init_hook = alc262_hp_bpc_automute,
11483 [ALC262_HP_BPC_D7000_WF] = {
11484 .mixers = { alc262_HP_BPC_WildWest_mixer },
11485 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11486 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11487 .dac_nids = alc262_dac_nids,
11489 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11490 .channel_mode = alc262_modes,
11491 .input_mux = &alc262_HP_D7000_capture_source,
11492 .unsol_event = alc262_hp_wildwest_unsol_event,
11493 .init_hook = alc262_hp_wildwest_automute,
11495 [ALC262_HP_BPC_D7000_WL] = {
11496 .mixers = { alc262_HP_BPC_WildWest_mixer,
11497 alc262_HP_BPC_WildWest_option_mixer },
11498 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11499 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11500 .dac_nids = alc262_dac_nids,
11502 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11503 .channel_mode = alc262_modes,
11504 .input_mux = &alc262_HP_D7000_capture_source,
11505 .unsol_event = alc262_hp_wildwest_unsol_event,
11506 .init_hook = alc262_hp_wildwest_automute,
11508 [ALC262_HP_TC_T5735] = {
11509 .mixers = { alc262_hp_t5735_mixer },
11510 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11511 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11512 .dac_nids = alc262_dac_nids,
11514 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11515 .channel_mode = alc262_modes,
11516 .input_mux = &alc262_capture_source,
11517 .unsol_event = alc_automute_amp_unsol_event,
11518 .setup = alc262_hp_t5735_setup,
11519 .init_hook = alc_automute_amp,
11521 [ALC262_HP_RP5700] = {
11522 .mixers = { alc262_hp_rp5700_mixer },
11523 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11524 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11525 .dac_nids = alc262_dac_nids,
11526 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11527 .channel_mode = alc262_modes,
11528 .input_mux = &alc262_hp_rp5700_capture_source,
11530 [ALC262_BENQ_ED8] = {
11531 .mixers = { alc262_base_mixer },
11532 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11533 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11534 .dac_nids = alc262_dac_nids,
11536 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11537 .channel_mode = alc262_modes,
11538 .input_mux = &alc262_capture_source,
11540 [ALC262_SONY_ASSAMD] = {
11541 .mixers = { alc262_sony_mixer },
11542 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11543 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11544 .dac_nids = alc262_dac_nids,
11546 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11547 .channel_mode = alc262_modes,
11548 .input_mux = &alc262_capture_source,
11549 .unsol_event = alc262_hippo_unsol_event,
11550 .setup = alc262_hippo_setup,
11551 .init_hook = alc262_hippo_automute,
11553 [ALC262_BENQ_T31] = {
11554 .mixers = { alc262_benq_t31_mixer },
11555 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11556 alc_hp15_unsol_verbs },
11557 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11558 .dac_nids = alc262_dac_nids,
11560 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11561 .channel_mode = alc262_modes,
11562 .input_mux = &alc262_capture_source,
11563 .unsol_event = alc262_hippo_unsol_event,
11564 .setup = alc262_hippo_setup,
11565 .init_hook = alc262_hippo_automute,
11568 .mixers = { alc262_ultra_mixer },
11569 .cap_mixer = alc262_ultra_capture_mixer,
11570 .init_verbs = { alc262_ultra_verbs },
11571 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11572 .dac_nids = alc262_dac_nids,
11573 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11574 .channel_mode = alc262_modes,
11575 .input_mux = &alc262_ultra_capture_source,
11576 .adc_nids = alc262_adc_nids, /* ADC0 */
11577 .capsrc_nids = alc262_capsrc_nids,
11578 .num_adc_nids = 1, /* single ADC */
11579 .unsol_event = alc262_ultra_unsol_event,
11580 .init_hook = alc262_ultra_automute,
11582 [ALC262_LENOVO_3000] = {
11583 .mixers = { alc262_lenovo_3000_mixer },
11584 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11585 alc262_lenovo_3000_unsol_verbs },
11586 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11587 .dac_nids = alc262_dac_nids,
11589 .dig_out_nid = ALC262_DIGOUT_NID,
11590 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11591 .channel_mode = alc262_modes,
11592 .input_mux = &alc262_fujitsu_capture_source,
11593 .unsol_event = alc262_lenovo_3000_unsol_event,
11596 .mixers = { alc262_nec_mixer },
11597 .init_verbs = { alc262_nec_verbs },
11598 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11599 .dac_nids = alc262_dac_nids,
11601 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11602 .channel_mode = alc262_modes,
11603 .input_mux = &alc262_capture_source,
11605 [ALC262_TOSHIBA_S06] = {
11606 .mixers = { alc262_toshiba_s06_mixer },
11607 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11608 alc262_eapd_verbs },
11609 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11610 .capsrc_nids = alc262_dmic_capsrc_nids,
11611 .dac_nids = alc262_dac_nids,
11612 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11613 .num_adc_nids = 1, /* single ADC */
11614 .dig_out_nid = ALC262_DIGOUT_NID,
11615 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11616 .channel_mode = alc262_modes,
11617 .unsol_event = alc_sku_unsol_event,
11618 .setup = alc262_toshiba_s06_setup,
11619 .init_hook = alc_inithook,
11621 [ALC262_TOSHIBA_RX1] = {
11622 .mixers = { alc262_toshiba_rx1_mixer },
11623 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11624 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11625 .dac_nids = alc262_dac_nids,
11627 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11628 .channel_mode = alc262_modes,
11629 .input_mux = &alc262_capture_source,
11630 .unsol_event = alc262_hippo_unsol_event,
11631 .setup = alc262_hippo_setup,
11632 .init_hook = alc262_hippo_automute,
11635 .mixers = { alc262_tyan_mixer },
11636 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11637 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11638 .dac_nids = alc262_dac_nids,
11640 .dig_out_nid = ALC262_DIGOUT_NID,
11641 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11642 .channel_mode = alc262_modes,
11643 .input_mux = &alc262_capture_source,
11644 .unsol_event = alc_automute_amp_unsol_event,
11645 .setup = alc262_tyan_setup,
11646 .init_hook = alc_automute_amp,
11650 static int patch_alc262(struct hda_codec *codec)
11652 struct alc_spec *spec;
11656 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11660 codec->spec = spec;
11662 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11667 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11668 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11669 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11670 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11674 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11676 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11680 if (board_config < 0) {
11681 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11683 board_config = ALC262_AUTO;
11686 if (board_config == ALC262_AUTO) {
11687 /* automatic parse from the BIOS config */
11688 err = alc262_parse_auto_config(codec);
11694 "hda_codec: Cannot set up configuration "
11695 "from BIOS. Using base mode...\n");
11696 board_config = ALC262_BASIC;
11700 if (!spec->no_analog) {
11701 err = snd_hda_attach_beep_device(codec, 0x1);
11708 if (board_config != ALC262_AUTO)
11709 setup_preset(codec, &alc262_presets[board_config]);
11711 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11712 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11714 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11715 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11717 if (!spec->adc_nids && spec->input_mux) {
11719 /* check whether the digital-mic has to be supported */
11720 for (i = 0; i < spec->input_mux->num_items; i++) {
11721 if (spec->input_mux->items[i].index >= 9)
11724 if (i < spec->input_mux->num_items) {
11725 /* use only ADC0 */
11726 spec->adc_nids = alc262_dmic_adc_nids;
11727 spec->num_adc_nids = 1;
11728 spec->capsrc_nids = alc262_dmic_capsrc_nids;
11730 /* all analog inputs */
11731 /* check whether NID 0x07 is valid */
11732 unsigned int wcap = get_wcaps(codec, 0x07);
11735 wcap = get_wcaps_type(wcap);
11736 if (wcap != AC_WID_AUD_IN) {
11737 spec->adc_nids = alc262_adc_nids_alt;
11738 spec->num_adc_nids =
11739 ARRAY_SIZE(alc262_adc_nids_alt);
11740 spec->capsrc_nids = alc262_capsrc_nids_alt;
11742 spec->adc_nids = alc262_adc_nids;
11743 spec->num_adc_nids =
11744 ARRAY_SIZE(alc262_adc_nids);
11745 spec->capsrc_nids = alc262_capsrc_nids;
11749 if (!spec->cap_mixer && !spec->no_analog)
11750 set_capture_mixer(codec);
11751 if (!spec->no_analog)
11752 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11754 spec->vmaster_nid = 0x0c;
11756 codec->patch_ops = alc_patch_ops;
11757 if (board_config == ALC262_AUTO)
11758 spec->init_hook = alc262_auto_init;
11759 #ifdef CONFIG_SND_HDA_POWER_SAVE
11760 if (!spec->loopback.amplist)
11761 spec->loopback.amplist = alc262_loopbacks;
11763 codec->proc_widget_hook = print_realtek_coef;
11769 * ALC268 channel source setting (2 channel)
11771 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11772 #define alc268_modes alc260_modes
11774 static hda_nid_t alc268_dac_nids[2] = {
11779 static hda_nid_t alc268_adc_nids[2] = {
11784 static hda_nid_t alc268_adc_nids_alt[1] = {
11789 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11791 static struct snd_kcontrol_new alc268_base_mixer[] = {
11792 /* output mixer control */
11793 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11794 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11795 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11796 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11797 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11798 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11799 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11803 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11804 /* output mixer control */
11805 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11806 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11807 ALC262_HIPPO_MASTER_SWITCH,
11808 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11809 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11810 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11814 /* bind Beep switches of both NID 0x0f and 0x10 */
11815 static struct hda_bind_ctls alc268_bind_beep_sw = {
11816 .ops = &snd_hda_bind_sw,
11818 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11819 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11824 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11825 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11826 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11830 static struct hda_verb alc268_eapd_verbs[] = {
11831 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11832 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11836 /* Toshiba specific */
11837 static struct hda_verb alc268_toshiba_verbs[] = {
11838 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11842 /* Acer specific */
11843 /* bind volumes of both NID 0x02 and 0x03 */
11844 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11845 .ops = &snd_hda_bind_vol,
11847 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11848 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11853 /* mute/unmute internal speaker according to the hp jack and mute state */
11854 static void alc268_acer_automute(struct hda_codec *codec, int force)
11856 struct alc_spec *spec = codec->spec;
11859 if (force || !spec->sense_updated) {
11860 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
11861 spec->sense_updated = 1;
11863 if (spec->jack_present)
11864 mute = HDA_AMP_MUTE; /* mute internal speaker */
11865 else /* unmute internal speaker if necessary */
11866 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11867 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11868 HDA_AMP_MUTE, mute);
11872 /* bind hp and internal speaker mute (with plug check) */
11873 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11874 struct snd_ctl_elem_value *ucontrol)
11876 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11877 long *valp = ucontrol->value.integer.value;
11880 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11882 alc268_acer_automute(codec, 0);
11886 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11887 /* output mixer control */
11888 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11890 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11891 .name = "Master Playback Switch",
11892 .info = snd_hda_mixer_amp_switch_info,
11893 .get = snd_hda_mixer_amp_switch_get,
11894 .put = alc268_acer_master_sw_put,
11895 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11897 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11901 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11902 /* output mixer control */
11903 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11906 .name = "Master Playback Switch",
11907 .info = snd_hda_mixer_amp_switch_info,
11908 .get = snd_hda_mixer_amp_switch_get,
11909 .put = alc268_acer_master_sw_put,
11910 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11912 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11913 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11914 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11918 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11919 /* output mixer control */
11920 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11923 .name = "Master Playback Switch",
11924 .info = snd_hda_mixer_amp_switch_info,
11925 .get = snd_hda_mixer_amp_switch_get,
11926 .put = alc268_acer_master_sw_put,
11927 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11929 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11930 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11934 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11935 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11937 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11938 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11939 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11940 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11944 static struct hda_verb alc268_acer_verbs[] = {
11945 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11946 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11949 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11950 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11951 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11955 /* unsolicited event for HP jack sensing */
11956 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11957 #define alc268_toshiba_setup alc262_hippo_setup
11958 #define alc268_toshiba_automute alc262_hippo_automute
11960 static void alc268_acer_unsol_event(struct hda_codec *codec,
11963 if ((res >> 26) != ALC880_HP_EVENT)
11965 alc268_acer_automute(codec, 1);
11968 static void alc268_acer_init_hook(struct hda_codec *codec)
11970 alc268_acer_automute(codec, 1);
11973 /* toggle speaker-output according to the hp-jack state */
11974 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11976 unsigned int present;
11977 unsigned char bits;
11979 present = snd_hda_jack_detect(codec, 0x15);
11980 bits = present ? AMP_IN_MUTE(0) : 0;
11981 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11982 AMP_IN_MUTE(0), bits);
11983 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11984 AMP_IN_MUTE(0), bits);
11987 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11990 switch (res >> 26) {
11991 case ALC880_HP_EVENT:
11992 alc268_aspire_one_speaker_automute(codec);
11994 case ALC880_MIC_EVENT:
11995 alc_mic_automute(codec);
12000 static void alc268_acer_lc_setup(struct hda_codec *codec)
12002 struct alc_spec *spec = codec->spec;
12003 spec->ext_mic.pin = 0x18;
12004 spec->ext_mic.mux_idx = 0;
12005 spec->int_mic.pin = 0x12;
12006 spec->int_mic.mux_idx = 6;
12007 spec->auto_mic = 1;
12010 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12012 alc268_aspire_one_speaker_automute(codec);
12013 alc_mic_automute(codec);
12016 static struct snd_kcontrol_new alc268_dell_mixer[] = {
12017 /* output mixer control */
12018 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12019 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12020 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12021 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12022 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12023 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12027 static struct hda_verb alc268_dell_verbs[] = {
12028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12030 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12031 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12035 /* mute/unmute internal speaker according to the hp jack and mute state */
12036 static void alc268_dell_setup(struct hda_codec *codec)
12038 struct alc_spec *spec = codec->spec;
12040 spec->autocfg.hp_pins[0] = 0x15;
12041 spec->autocfg.speaker_pins[0] = 0x14;
12042 spec->ext_mic.pin = 0x18;
12043 spec->ext_mic.mux_idx = 0;
12044 spec->int_mic.pin = 0x19;
12045 spec->int_mic.mux_idx = 1;
12046 spec->auto_mic = 1;
12049 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12050 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12051 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12052 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12053 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12054 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12055 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12056 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12057 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12061 static struct hda_verb alc267_quanta_il1_verbs[] = {
12062 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12063 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12067 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12069 struct alc_spec *spec = codec->spec;
12070 spec->autocfg.hp_pins[0] = 0x15;
12071 spec->autocfg.speaker_pins[0] = 0x14;
12072 spec->ext_mic.pin = 0x18;
12073 spec->ext_mic.mux_idx = 0;
12074 spec->int_mic.pin = 0x19;
12075 spec->int_mic.mux_idx = 1;
12076 spec->auto_mic = 1;
12080 * generic initialization of ADC, input mixers and output mixers
12082 static struct hda_verb alc268_base_init_verbs[] = {
12083 /* Unmute DAC0-1 and set vol = 0 */
12084 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12085 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12088 * Set up output mixers (0x0c - 0x0e)
12090 /* set vol=0 to output mixers */
12091 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12092 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12094 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12095 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12098 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12099 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12100 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12102 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12103 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12104 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12107 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12108 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12110 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12112 /* set PCBEEP vol = 0, mute connections */
12113 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12115 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12117 /* Unmute Selector 23h,24h and set the default input to mic-in */
12119 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12121 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12128 * generic initialization of ADC, input mixers and output mixers
12130 static struct hda_verb alc268_volume_init_verbs[] = {
12131 /* set output DAC */
12132 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12133 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12135 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12136 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12137 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12138 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12139 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12143 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12145 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12146 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12148 /* set PCBEEP vol = 0, mute connections */
12149 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12150 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12151 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12156 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12157 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12158 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12162 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12163 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12164 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12169 static struct snd_kcontrol_new alc268_capture_mixer[] = {
12170 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12171 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12172 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12173 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12178 static struct hda_input_mux alc268_capture_source = {
12182 { "Front Mic", 0x1 },
12188 static struct hda_input_mux alc268_acer_capture_source = {
12192 { "Internal Mic", 0x1 },
12197 static struct hda_input_mux alc268_acer_dmic_capture_source = {
12201 { "Internal Mic", 0x6 },
12206 #ifdef CONFIG_SND_DEBUG
12207 static struct snd_kcontrol_new alc268_test_mixer[] = {
12208 /* Volume widgets */
12209 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12210 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12211 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12212 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12213 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12214 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12215 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12216 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12217 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12218 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12219 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12220 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12221 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12222 /* The below appears problematic on some hardwares */
12223 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12224 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12225 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12226 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12227 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12229 /* Modes for retasking pin widgets */
12230 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12231 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12232 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12233 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12235 /* Controls for GPIO pins, assuming they are configured as outputs */
12236 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12237 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12238 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12239 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12241 /* Switches to allow the digital SPDIF output pin to be enabled.
12242 * The ALC268 does not have an SPDIF input.
12244 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12246 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12247 * this output to turn on an external amplifier.
12249 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12250 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12256 /* create input playback/capture controls for the given pin */
12257 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12258 const char *ctlname, int idx)
12274 if (spec->multiout.dac_nids[0] != dac &&
12275 spec->multiout.dac_nids[1] != dac) {
12276 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
12277 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12281 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12285 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12286 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12288 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12289 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12295 /* add playback controls from the parsed DAC table */
12296 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12297 const struct auto_pin_cfg *cfg)
12302 spec->multiout.dac_nids = spec->private_dac_nids;
12304 nid = cfg->line_out_pins[0];
12307 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12311 err = alc268_new_analog_output(spec, nid, name, 0);
12316 nid = cfg->speaker_pins[0];
12318 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
12319 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12323 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12327 nid = cfg->hp_pins[0];
12329 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12334 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12336 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
12337 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12344 /* create playback/capture controls for input pins */
12345 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12346 const struct auto_pin_cfg *cfg)
12348 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12351 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12352 hda_nid_t nid, int pin_type)
12356 alc_set_pin_output(codec, nid, pin_type);
12357 if (nid == 0x14 || nid == 0x16)
12361 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12364 static void alc268_auto_init_multi_out(struct hda_codec *codec)
12366 struct alc_spec *spec = codec->spec;
12367 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12369 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12370 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12374 static void alc268_auto_init_hp_out(struct hda_codec *codec)
12376 struct alc_spec *spec = codec->spec;
12379 pin = spec->autocfg.hp_pins[0];
12381 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12382 pin = spec->autocfg.speaker_pins[0];
12384 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12387 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12389 struct alc_spec *spec = codec->spec;
12390 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12391 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12392 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12393 unsigned int dac_vol1, dac_vol2;
12395 if (line_nid == 0x1d || speaker_nid == 0x1d) {
12396 snd_hda_codec_write(codec, speaker_nid, 0,
12397 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12398 /* mute mixer inputs from 0x1d */
12399 snd_hda_codec_write(codec, 0x0f, 0,
12400 AC_VERB_SET_AMP_GAIN_MUTE,
12402 snd_hda_codec_write(codec, 0x10, 0,
12403 AC_VERB_SET_AMP_GAIN_MUTE,
12406 /* unmute mixer inputs from 0x1d */
12407 snd_hda_codec_write(codec, 0x0f, 0,
12408 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12409 snd_hda_codec_write(codec, 0x10, 0,
12410 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12413 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
12414 if (line_nid == 0x14)
12415 dac_vol2 = AMP_OUT_ZERO;
12416 else if (line_nid == 0x15)
12417 dac_vol1 = AMP_OUT_ZERO;
12418 if (hp_nid == 0x14)
12419 dac_vol2 = AMP_OUT_ZERO;
12420 else if (hp_nid == 0x15)
12421 dac_vol1 = AMP_OUT_ZERO;
12422 if (line_nid != 0x16 || hp_nid != 0x16 ||
12423 spec->autocfg.line_out_pins[1] != 0x16 ||
12424 spec->autocfg.line_out_pins[2] != 0x16)
12425 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12427 snd_hda_codec_write(codec, 0x02, 0,
12428 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12429 snd_hda_codec_write(codec, 0x03, 0,
12430 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12433 /* pcm configuration: identical with ALC880 */
12434 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12435 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12436 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12437 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12440 * BIOS auto configuration
12442 static int alc268_parse_auto_config(struct hda_codec *codec)
12444 struct alc_spec *spec = codec->spec;
12446 static hda_nid_t alc268_ignore[] = { 0 };
12448 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12452 if (!spec->autocfg.line_outs) {
12453 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12454 spec->multiout.max_channels = 2;
12455 spec->no_analog = 1;
12458 return 0; /* can't find valid BIOS pin config */
12460 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12463 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
12467 spec->multiout.max_channels = 2;
12470 /* digital only support output */
12471 if (spec->autocfg.dig_outs) {
12472 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12473 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12475 if (spec->kctls.list)
12476 add_mixer(spec, spec->kctls.list);
12478 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12479 add_mixer(spec, alc268_beep_mixer);
12481 add_verb(spec, alc268_volume_init_verbs);
12482 spec->num_mux_defs = 2;
12483 spec->input_mux = &spec->private_imux[0];
12485 err = alc_auto_add_mic_boost(codec);
12489 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12494 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12496 /* init callback for auto-configuration model -- overriding the default init */
12497 static void alc268_auto_init(struct hda_codec *codec)
12499 struct alc_spec *spec = codec->spec;
12500 alc268_auto_init_multi_out(codec);
12501 alc268_auto_init_hp_out(codec);
12502 alc268_auto_init_mono_speaker_out(codec);
12503 alc268_auto_init_analog_input(codec);
12504 if (spec->unsol_event)
12505 alc_inithook(codec);
12509 * configuration and preset
12511 static const char *alc268_models[ALC268_MODEL_LAST] = {
12512 [ALC267_QUANTA_IL1] = "quanta-il1",
12513 [ALC268_3ST] = "3stack",
12514 [ALC268_TOSHIBA] = "toshiba",
12515 [ALC268_ACER] = "acer",
12516 [ALC268_ACER_DMIC] = "acer-dmic",
12517 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12518 [ALC268_DELL] = "dell",
12519 [ALC268_ZEPTO] = "zepto",
12520 #ifdef CONFIG_SND_DEBUG
12521 [ALC268_TEST] = "test",
12523 [ALC268_AUTO] = "auto",
12526 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12527 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12528 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12529 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12530 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12531 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12532 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12533 ALC268_ACER_ASPIRE_ONE),
12534 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12535 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
12536 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
12537 /* almost compatible with toshiba but with optional digital outs;
12538 * auto-probing seems working fine
12540 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12542 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12543 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12544 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12545 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12546 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12547 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12551 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
12552 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12553 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
12554 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
12555 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12560 static struct alc_config_preset alc268_presets[] = {
12561 [ALC267_QUANTA_IL1] = {
12562 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12563 alc268_capture_nosrc_mixer },
12564 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12565 alc267_quanta_il1_verbs },
12566 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12567 .dac_nids = alc268_dac_nids,
12568 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12569 .adc_nids = alc268_adc_nids_alt,
12571 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12572 .channel_mode = alc268_modes,
12573 .unsol_event = alc_sku_unsol_event,
12574 .setup = alc267_quanta_il1_setup,
12575 .init_hook = alc_inithook,
12578 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12579 alc268_beep_mixer },
12580 .init_verbs = { alc268_base_init_verbs },
12581 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12582 .dac_nids = alc268_dac_nids,
12583 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12584 .adc_nids = alc268_adc_nids_alt,
12585 .capsrc_nids = alc268_capsrc_nids,
12587 .dig_out_nid = ALC268_DIGOUT_NID,
12588 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12589 .channel_mode = alc268_modes,
12590 .input_mux = &alc268_capture_source,
12592 [ALC268_TOSHIBA] = {
12593 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12594 alc268_beep_mixer },
12595 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12596 alc268_toshiba_verbs },
12597 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12598 .dac_nids = alc268_dac_nids,
12599 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12600 .adc_nids = alc268_adc_nids_alt,
12601 .capsrc_nids = alc268_capsrc_nids,
12603 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12604 .channel_mode = alc268_modes,
12605 .input_mux = &alc268_capture_source,
12606 .unsol_event = alc268_toshiba_unsol_event,
12607 .setup = alc268_toshiba_setup,
12608 .init_hook = alc268_toshiba_automute,
12611 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12612 alc268_beep_mixer },
12613 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12614 alc268_acer_verbs },
12615 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12616 .dac_nids = alc268_dac_nids,
12617 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12618 .adc_nids = alc268_adc_nids_alt,
12619 .capsrc_nids = alc268_capsrc_nids,
12621 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12622 .channel_mode = alc268_modes,
12623 .input_mux = &alc268_acer_capture_source,
12624 .unsol_event = alc268_acer_unsol_event,
12625 .init_hook = alc268_acer_init_hook,
12627 [ALC268_ACER_DMIC] = {
12628 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12629 alc268_beep_mixer },
12630 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12631 alc268_acer_verbs },
12632 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12633 .dac_nids = alc268_dac_nids,
12634 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12635 .adc_nids = alc268_adc_nids_alt,
12636 .capsrc_nids = alc268_capsrc_nids,
12638 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12639 .channel_mode = alc268_modes,
12640 .input_mux = &alc268_acer_dmic_capture_source,
12641 .unsol_event = alc268_acer_unsol_event,
12642 .init_hook = alc268_acer_init_hook,
12644 [ALC268_ACER_ASPIRE_ONE] = {
12645 .mixers = { alc268_acer_aspire_one_mixer,
12647 alc268_capture_nosrc_mixer },
12648 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12649 alc268_acer_aspire_one_verbs },
12650 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12651 .dac_nids = alc268_dac_nids,
12652 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12653 .adc_nids = alc268_adc_nids_alt,
12654 .capsrc_nids = alc268_capsrc_nids,
12656 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12657 .channel_mode = alc268_modes,
12658 .unsol_event = alc268_acer_lc_unsol_event,
12659 .setup = alc268_acer_lc_setup,
12660 .init_hook = alc268_acer_lc_init_hook,
12663 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12664 alc268_capture_nosrc_mixer },
12665 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12666 alc268_dell_verbs },
12667 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12668 .dac_nids = alc268_dac_nids,
12669 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12670 .adc_nids = alc268_adc_nids_alt,
12671 .capsrc_nids = alc268_capsrc_nids,
12673 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12674 .channel_mode = alc268_modes,
12675 .unsol_event = alc_sku_unsol_event,
12676 .setup = alc268_dell_setup,
12677 .init_hook = alc_inithook,
12680 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12681 alc268_beep_mixer },
12682 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12683 alc268_toshiba_verbs },
12684 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12685 .dac_nids = alc268_dac_nids,
12686 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12687 .adc_nids = alc268_adc_nids_alt,
12688 .capsrc_nids = alc268_capsrc_nids,
12690 .dig_out_nid = ALC268_DIGOUT_NID,
12691 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12692 .channel_mode = alc268_modes,
12693 .input_mux = &alc268_capture_source,
12694 .setup = alc268_toshiba_setup,
12695 .init_hook = alc268_toshiba_automute,
12697 #ifdef CONFIG_SND_DEBUG
12699 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12700 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12701 alc268_volume_init_verbs },
12702 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12703 .dac_nids = alc268_dac_nids,
12704 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12705 .adc_nids = alc268_adc_nids_alt,
12706 .capsrc_nids = alc268_capsrc_nids,
12708 .dig_out_nid = ALC268_DIGOUT_NID,
12709 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12710 .channel_mode = alc268_modes,
12711 .input_mux = &alc268_capture_source,
12716 static int patch_alc268(struct hda_codec *codec)
12718 struct alc_spec *spec;
12720 int i, has_beep, err;
12722 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12726 codec->spec = spec;
12728 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12732 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
12733 board_config = snd_hda_check_board_codec_sid_config(codec,
12734 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12736 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12737 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12739 board_config = ALC268_AUTO;
12742 if (board_config == ALC268_AUTO) {
12743 /* automatic parse from the BIOS config */
12744 err = alc268_parse_auto_config(codec);
12750 "hda_codec: Cannot set up configuration "
12751 "from BIOS. Using base mode...\n");
12752 board_config = ALC268_3ST;
12756 if (board_config != ALC268_AUTO)
12757 setup_preset(codec, &alc268_presets[board_config]);
12759 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12760 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12761 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12763 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12766 for (i = 0; i < spec->num_mixers; i++) {
12767 if (spec->mixers[i] == alc268_beep_mixer) {
12774 err = snd_hda_attach_beep_device(codec, 0x1);
12779 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12780 /* override the amp caps for beep generator */
12781 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12782 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12783 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12784 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12785 (0 << AC_AMPCAP_MUTE_SHIFT));
12788 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12789 /* check whether NID 0x07 is valid */
12790 unsigned int wcap = get_wcaps(codec, 0x07);
12793 spec->capsrc_nids = alc268_capsrc_nids;
12795 wcap = get_wcaps_type(wcap);
12796 if (spec->auto_mic ||
12797 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12798 spec->adc_nids = alc268_adc_nids_alt;
12799 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12800 if (spec->auto_mic)
12801 fixup_automic_adc(codec);
12802 if (spec->auto_mic || spec->input_mux->num_items == 1)
12803 add_mixer(spec, alc268_capture_nosrc_mixer);
12805 add_mixer(spec, alc268_capture_alt_mixer);
12807 spec->adc_nids = alc268_adc_nids;
12808 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12809 add_mixer(spec, alc268_capture_mixer);
12811 /* set default input source */
12812 for (i = 0; i < spec->num_adc_nids; i++)
12813 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12814 0, AC_VERB_SET_CONNECT_SEL,
12815 i < spec->num_mux_defs ?
12816 spec->input_mux[i].items[0].index :
12817 spec->input_mux->items[0].index);
12820 spec->vmaster_nid = 0x02;
12822 codec->patch_ops = alc_patch_ops;
12823 if (board_config == ALC268_AUTO)
12824 spec->init_hook = alc268_auto_init;
12826 codec->proc_widget_hook = print_realtek_coef;
12832 * ALC269 channel source setting (2 channel)
12834 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12836 #define alc269_dac_nids alc260_dac_nids
12838 static hda_nid_t alc269_adc_nids[1] = {
12843 static hda_nid_t alc269_capsrc_nids[1] = {
12847 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12851 #define alc269_modes alc260_modes
12852 #define alc269_capture_source alc880_lg_lw_capture_source
12854 static struct snd_kcontrol_new alc269_base_mixer[] = {
12855 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12856 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12857 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12858 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12862 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12863 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12864 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12865 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12866 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12870 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12871 /* output mixer control */
12872 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12875 .name = "Master Playback Switch",
12876 .info = snd_hda_mixer_amp_switch_info,
12877 .get = snd_hda_mixer_amp_switch_get,
12878 .put = alc268_acer_master_sw_put,
12879 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12881 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12882 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12883 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12884 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12885 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12886 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12890 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12891 /* output mixer control */
12892 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12894 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12895 .name = "Master Playback Switch",
12896 .info = snd_hda_mixer_amp_switch_info,
12897 .get = snd_hda_mixer_amp_switch_get,
12898 .put = alc268_acer_master_sw_put,
12899 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12903 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12904 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12905 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12906 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12907 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12908 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12909 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12913 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12914 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12916 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12921 /* capture mixer elements */
12922 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12923 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12924 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12925 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12930 #define alc269_fujitsu_mixer alc269_eeepc_mixer
12932 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12933 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12934 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12936 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12937 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12938 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12942 static struct hda_verb alc269_lifebook_verbs[] = {
12943 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12944 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12945 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12947 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12948 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12949 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12950 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12951 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12952 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12956 /* toggle speaker-output according to the hp-jack state */
12957 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12959 unsigned int present;
12960 unsigned char bits;
12962 present = snd_hda_jack_detect(codec, 0x15);
12963 bits = present ? AMP_IN_MUTE(0) : 0;
12964 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12965 AMP_IN_MUTE(0), bits);
12966 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12967 AMP_IN_MUTE(0), bits);
12969 snd_hda_codec_write(codec, 0x20, 0,
12970 AC_VERB_SET_COEF_INDEX, 0x0c);
12971 snd_hda_codec_write(codec, 0x20, 0,
12972 AC_VERB_SET_PROC_COEF, 0x680);
12974 snd_hda_codec_write(codec, 0x20, 0,
12975 AC_VERB_SET_COEF_INDEX, 0x0c);
12976 snd_hda_codec_write(codec, 0x20, 0,
12977 AC_VERB_SET_PROC_COEF, 0x480);
12980 /* toggle speaker-output according to the hp-jacks state */
12981 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12983 unsigned int present;
12984 unsigned char bits;
12986 /* Check laptop headphone socket */
12987 present = snd_hda_jack_detect(codec, 0x15);
12989 /* Check port replicator headphone socket */
12990 present |= snd_hda_jack_detect(codec, 0x1a);
12992 bits = present ? AMP_IN_MUTE(0) : 0;
12993 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12994 AMP_IN_MUTE(0), bits);
12995 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12996 AMP_IN_MUTE(0), bits);
12998 snd_hda_codec_write(codec, 0x20, 0,
12999 AC_VERB_SET_COEF_INDEX, 0x0c);
13000 snd_hda_codec_write(codec, 0x20, 0,
13001 AC_VERB_SET_PROC_COEF, 0x680);
13003 snd_hda_codec_write(codec, 0x20, 0,
13004 AC_VERB_SET_COEF_INDEX, 0x0c);
13005 snd_hda_codec_write(codec, 0x20, 0,
13006 AC_VERB_SET_PROC_COEF, 0x480);
13009 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13011 unsigned int present_laptop;
13012 unsigned int present_dock;
13014 present_laptop = snd_hda_jack_detect(codec, 0x18);
13015 present_dock = snd_hda_jack_detect(codec, 0x1b);
13017 /* Laptop mic port overrides dock mic port, design decision */
13019 snd_hda_codec_write(codec, 0x23, 0,
13020 AC_VERB_SET_CONNECT_SEL, 0x3);
13021 if (present_laptop)
13022 snd_hda_codec_write(codec, 0x23, 0,
13023 AC_VERB_SET_CONNECT_SEL, 0x0);
13024 if (!present_dock && !present_laptop)
13025 snd_hda_codec_write(codec, 0x23, 0,
13026 AC_VERB_SET_CONNECT_SEL, 0x1);
13029 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13032 switch (res >> 26) {
13033 case ALC880_HP_EVENT:
13034 alc269_quanta_fl1_speaker_automute(codec);
13036 case ALC880_MIC_EVENT:
13037 alc_mic_automute(codec);
13042 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13045 if ((res >> 26) == ALC880_HP_EVENT)
13046 alc269_lifebook_speaker_automute(codec);
13047 if ((res >> 26) == ALC880_MIC_EVENT)
13048 alc269_lifebook_mic_autoswitch(codec);
13051 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13053 struct alc_spec *spec = codec->spec;
13054 spec->ext_mic.pin = 0x18;
13055 spec->ext_mic.mux_idx = 0;
13056 spec->int_mic.pin = 0x19;
13057 spec->int_mic.mux_idx = 1;
13058 spec->auto_mic = 1;
13061 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13063 alc269_quanta_fl1_speaker_automute(codec);
13064 alc_mic_automute(codec);
13067 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13069 alc269_lifebook_speaker_automute(codec);
13070 alc269_lifebook_mic_autoswitch(codec);
13073 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13074 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13075 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13076 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13077 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13078 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13079 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13084 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13085 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13086 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13087 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13090 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13094 /* toggle speaker-output according to the hp-jack state */
13095 static void alc269_speaker_automute(struct hda_codec *codec)
13097 unsigned int present;
13098 unsigned char bits;
13100 present = snd_hda_jack_detect(codec, 0x15);
13101 bits = present ? AMP_IN_MUTE(0) : 0;
13102 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13103 AMP_IN_MUTE(0), bits);
13104 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13105 AMP_IN_MUTE(0), bits);
13108 /* unsolicited event for HP jack sensing */
13109 static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13112 switch (res >> 26) {
13113 case ALC880_HP_EVENT:
13114 alc269_speaker_automute(codec);
13116 case ALC880_MIC_EVENT:
13117 alc_mic_automute(codec);
13122 static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13124 struct alc_spec *spec = codec->spec;
13125 spec->ext_mic.pin = 0x18;
13126 spec->ext_mic.mux_idx = 0;
13127 spec->int_mic.pin = 0x12;
13128 spec->int_mic.mux_idx = 5;
13129 spec->auto_mic = 1;
13132 static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13134 struct alc_spec *spec = codec->spec;
13135 spec->ext_mic.pin = 0x18;
13136 spec->ext_mic.mux_idx = 0;
13137 spec->int_mic.pin = 0x19;
13138 spec->int_mic.mux_idx = 1;
13139 spec->auto_mic = 1;
13142 static void alc269_eeepc_inithook(struct hda_codec *codec)
13144 alc269_speaker_automute(codec);
13145 alc_mic_automute(codec);
13149 * generic initialization of ADC, input mixers and output mixers
13151 static struct hda_verb alc269_init_verbs[] = {
13153 * Unmute ADC0 and set the default input to mic-in
13155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13157 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13158 * analog-loopback mixer widget
13159 * Note: PASD motherboards uses the Line In 2 as the input for
13160 * front panel mic (mic 2)
13162 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13163 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13164 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13165 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13166 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13170 * Set up output mixers (0x0c - 0x0e)
13172 /* set vol=0 to output mixers */
13173 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13174 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13176 /* set up input amps for analog loopback */
13177 /* Amp Indices: DAC = 0, mixer = 1 */
13178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13181 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13182 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13183 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13187 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13188 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13189 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13190 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13191 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13193 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13194 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13196 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13197 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13198 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13199 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13201 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13202 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13204 /* FIXME: use matrix-type input source selection */
13205 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13206 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13213 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13214 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13218 #define alc269_auto_create_multi_out_ctls \
13219 alc268_auto_create_multi_out_ctls
13220 #define alc269_auto_create_input_ctls \
13221 alc268_auto_create_input_ctls
13223 #ifdef CONFIG_SND_HDA_POWER_SAVE
13224 #define alc269_loopbacks alc880_loopbacks
13227 /* pcm configuration: identical with ALC880 */
13228 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
13229 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
13230 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
13231 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
13233 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13237 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13238 /* NID is set in alc_build_pcms */
13240 .open = alc880_playback_pcm_open,
13241 .prepare = alc880_playback_pcm_prepare,
13242 .cleanup = alc880_playback_pcm_cleanup
13246 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13250 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13251 /* NID is set in alc_build_pcms */
13255 * BIOS auto configuration
13257 static int alc269_parse_auto_config(struct hda_codec *codec)
13259 struct alc_spec *spec = codec->spec;
13261 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13263 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13268 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13271 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
13275 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13277 if (spec->autocfg.dig_outs)
13278 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13280 if (spec->kctls.list)
13281 add_mixer(spec, spec->kctls.list);
13283 add_verb(spec, alc269_init_verbs);
13284 spec->num_mux_defs = 1;
13285 spec->input_mux = &spec->private_imux[0];
13286 /* set default input source */
13287 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13288 0, AC_VERB_SET_CONNECT_SEL,
13289 spec->input_mux->items[0].index);
13291 err = alc_auto_add_mic_boost(codec);
13295 if (!spec->cap_mixer && !spec->no_analog)
13296 set_capture_mixer(codec);
13298 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13303 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
13304 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
13305 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13308 /* init callback for auto-configuration model -- overriding the default init */
13309 static void alc269_auto_init(struct hda_codec *codec)
13311 struct alc_spec *spec = codec->spec;
13312 alc269_auto_init_multi_out(codec);
13313 alc269_auto_init_hp_out(codec);
13314 alc269_auto_init_analog_input(codec);
13315 if (spec->unsol_event)
13316 alc_inithook(codec);
13320 * configuration and preset
13322 static const char *alc269_models[ALC269_MODEL_LAST] = {
13323 [ALC269_BASIC] = "basic",
13324 [ALC269_QUANTA_FL1] = "quanta",
13325 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13326 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13327 [ALC269_FUJITSU] = "fujitsu",
13328 [ALC269_LIFEBOOK] = "lifebook",
13329 [ALC269_AUTO] = "auto",
13332 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13333 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13334 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13335 ALC269_ASUS_EEEPC_P703),
13336 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13337 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13338 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13339 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13340 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13341 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13342 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13343 ALC269_ASUS_EEEPC_P901),
13344 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13345 ALC269_ASUS_EEEPC_P901),
13346 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13347 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13348 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13352 static struct alc_config_preset alc269_presets[] = {
13354 .mixers = { alc269_base_mixer },
13355 .init_verbs = { alc269_init_verbs },
13356 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13357 .dac_nids = alc269_dac_nids,
13359 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13360 .channel_mode = alc269_modes,
13361 .input_mux = &alc269_capture_source,
13363 [ALC269_QUANTA_FL1] = {
13364 .mixers = { alc269_quanta_fl1_mixer },
13365 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13366 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13367 .dac_nids = alc269_dac_nids,
13369 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13370 .channel_mode = alc269_modes,
13371 .input_mux = &alc269_capture_source,
13372 .unsol_event = alc269_quanta_fl1_unsol_event,
13373 .setup = alc269_quanta_fl1_setup,
13374 .init_hook = alc269_quanta_fl1_init_hook,
13376 [ALC269_ASUS_EEEPC_P703] = {
13377 .mixers = { alc269_eeepc_mixer },
13378 .cap_mixer = alc269_epc_capture_mixer,
13379 .init_verbs = { alc269_init_verbs,
13380 alc269_eeepc_amic_init_verbs },
13381 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13382 .dac_nids = alc269_dac_nids,
13384 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13385 .channel_mode = alc269_modes,
13386 .unsol_event = alc269_eeepc_unsol_event,
13387 .setup = alc269_eeepc_amic_setup,
13388 .init_hook = alc269_eeepc_inithook,
13390 [ALC269_ASUS_EEEPC_P901] = {
13391 .mixers = { alc269_eeepc_mixer },
13392 .cap_mixer = alc269_epc_capture_mixer,
13393 .init_verbs = { alc269_init_verbs,
13394 alc269_eeepc_dmic_init_verbs },
13395 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13396 .dac_nids = alc269_dac_nids,
13398 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13399 .channel_mode = alc269_modes,
13400 .unsol_event = alc269_eeepc_unsol_event,
13401 .setup = alc269_eeepc_dmic_setup,
13402 .init_hook = alc269_eeepc_inithook,
13404 [ALC269_FUJITSU] = {
13405 .mixers = { alc269_fujitsu_mixer },
13406 .cap_mixer = alc269_epc_capture_mixer,
13407 .init_verbs = { alc269_init_verbs,
13408 alc269_eeepc_dmic_init_verbs },
13409 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13410 .dac_nids = alc269_dac_nids,
13412 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13413 .channel_mode = alc269_modes,
13414 .unsol_event = alc269_eeepc_unsol_event,
13415 .setup = alc269_eeepc_dmic_setup,
13416 .init_hook = alc269_eeepc_inithook,
13418 [ALC269_LIFEBOOK] = {
13419 .mixers = { alc269_lifebook_mixer },
13420 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13421 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13422 .dac_nids = alc269_dac_nids,
13424 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13425 .channel_mode = alc269_modes,
13426 .input_mux = &alc269_capture_source,
13427 .unsol_event = alc269_lifebook_unsol_event,
13428 .init_hook = alc269_lifebook_init_hook,
13432 static int patch_alc269(struct hda_codec *codec)
13434 struct alc_spec *spec;
13438 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13442 codec->spec = spec;
13444 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13446 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13450 if (board_config < 0) {
13451 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13453 board_config = ALC269_AUTO;
13456 if (board_config == ALC269_AUTO) {
13457 /* automatic parse from the BIOS config */
13458 err = alc269_parse_auto_config(codec);
13464 "hda_codec: Cannot set up configuration "
13465 "from BIOS. Using base mode...\n");
13466 board_config = ALC269_BASIC;
13470 err = snd_hda_attach_beep_device(codec, 0x1);
13476 if (board_config != ALC269_AUTO)
13477 setup_preset(codec, &alc269_presets[board_config]);
13479 if (codec->subsystem_id == 0x17aa3bf8) {
13480 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13481 * fix the sample rate of analog I/O to 44.1kHz
13483 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13484 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13486 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13487 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13489 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13490 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13492 spec->adc_nids = alc269_adc_nids;
13493 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13494 spec->capsrc_nids = alc269_capsrc_nids;
13495 if (!spec->cap_mixer)
13496 set_capture_mixer(codec);
13497 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13499 spec->vmaster_nid = 0x02;
13501 codec->patch_ops = alc_patch_ops;
13502 if (board_config == ALC269_AUTO)
13503 spec->init_hook = alc269_auto_init;
13504 #ifdef CONFIG_SND_HDA_POWER_SAVE
13505 if (!spec->loopback.amplist)
13506 spec->loopback.amplist = alc269_loopbacks;
13508 codec->proc_widget_hook = print_realtek_coef;
13514 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13518 * set the path ways for 2 channel output
13519 * need to set the codec line out and mic 1 pin widgets to inputs
13521 static struct hda_verb alc861_threestack_ch2_init[] = {
13522 /* set pin widget 1Ah (line in) for input */
13523 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13524 /* set pin widget 18h (mic1/2) for input, for mic also enable
13527 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13529 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13531 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13532 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13538 * need to set the codec line out and mic 1 pin widgets to outputs
13540 static struct hda_verb alc861_threestack_ch6_init[] = {
13541 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13542 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13543 /* set pin widget 18h (mic1) for output (CLFE)*/
13544 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13546 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13547 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13549 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13551 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13552 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13557 static struct hda_channel_mode alc861_threestack_modes[2] = {
13558 { 2, alc861_threestack_ch2_init },
13559 { 6, alc861_threestack_ch6_init },
13561 /* Set mic1 as input and unmute the mixer */
13562 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13563 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13564 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13567 /* Set mic1 as output and mute mixer */
13568 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13569 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13570 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13574 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13575 { 2, alc861_uniwill_m31_ch2_init },
13576 { 4, alc861_uniwill_m31_ch4_init },
13579 /* Set mic1 and line-in as input and unmute the mixer */
13580 static struct hda_verb alc861_asus_ch2_init[] = {
13581 /* set pin widget 1Ah (line in) for input */
13582 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13583 /* set pin widget 18h (mic1/2) for input, for mic also enable
13586 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13588 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13590 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13591 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13595 /* Set mic1 nad line-in as output and mute mixer */
13596 static struct hda_verb alc861_asus_ch6_init[] = {
13597 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13598 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13599 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13600 /* set pin widget 18h (mic1) for output (CLFE)*/
13601 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13602 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13603 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13604 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13606 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13608 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13609 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13614 static struct hda_channel_mode alc861_asus_modes[2] = {
13615 { 2, alc861_asus_ch2_init },
13616 { 6, alc861_asus_ch6_init },
13621 static struct snd_kcontrol_new alc861_base_mixer[] = {
13622 /* output mixer control */
13623 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13624 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13625 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13626 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13627 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13629 /*Input mixer control */
13630 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13631 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13632 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13633 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13634 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13635 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13637 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13638 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13644 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13645 /* output mixer control */
13646 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13647 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13648 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13649 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13650 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13652 /* Input mixer control */
13653 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13654 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13655 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13656 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13657 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13658 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13660 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13661 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13662 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13666 .name = "Channel Mode",
13667 .info = alc_ch_mode_info,
13668 .get = alc_ch_mode_get,
13669 .put = alc_ch_mode_put,
13670 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13675 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13676 /* output mixer control */
13677 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13679 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13684 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13685 /* output mixer control */
13686 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13687 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13688 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13689 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13690 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13692 /* Input mixer control */
13693 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13694 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13695 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13696 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13697 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13698 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13699 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13700 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13701 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13706 .name = "Channel Mode",
13707 .info = alc_ch_mode_info,
13708 .get = alc_ch_mode_get,
13709 .put = alc_ch_mode_put,
13710 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13715 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13716 /* output mixer control */
13717 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13718 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13719 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13720 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13721 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13723 /* Input mixer control */
13724 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13725 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13726 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13727 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13728 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13729 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13731 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13732 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13733 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13737 .name = "Channel Mode",
13738 .info = alc_ch_mode_info,
13739 .get = alc_ch_mode_get,
13740 .put = alc_ch_mode_put,
13741 .private_value = ARRAY_SIZE(alc861_asus_modes),
13746 /* additional mixer */
13747 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13748 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13749 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13754 * generic initialization of ADC, input mixers and output mixers
13756 static struct hda_verb alc861_base_init_verbs[] = {
13758 * Unmute ADC0 and set the default input to mic-in
13760 /* port-A for surround (rear panel) */
13761 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13762 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13763 /* port-B for mic-in (rear panel) with vref */
13764 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13765 /* port-C for line-in (rear panel) */
13766 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13767 /* port-D for Front */
13768 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13769 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13770 /* port-E for HP out (front panel) */
13771 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13772 /* route front PCM to HP */
13773 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13774 /* port-F for mic-in (front panel) with vref */
13775 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13776 /* port-G for CLFE (rear panel) */
13777 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13778 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13779 /* port-H for side (rear panel) */
13780 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13781 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13783 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13784 /* route front mic to ADC1*/
13785 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13788 /* Unmute DAC0~3 & spdif out*/
13789 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13790 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13791 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13792 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13795 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13796 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13797 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13798 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13799 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13801 /* Unmute Stereo Mixer 15 */
13802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13803 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13808 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13809 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13810 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13811 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13813 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13815 /* hp used DAC 3 (Front) */
13816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13817 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13822 static struct hda_verb alc861_threestack_init_verbs[] = {
13824 * Unmute ADC0 and set the default input to mic-in
13826 /* port-A for surround (rear panel) */
13827 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13828 /* port-B for mic-in (rear panel) with vref */
13829 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13830 /* port-C for line-in (rear panel) */
13831 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13832 /* port-D for Front */
13833 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13834 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13835 /* port-E for HP out (front panel) */
13836 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13837 /* route front PCM to HP */
13838 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13839 /* port-F for mic-in (front panel) with vref */
13840 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13841 /* port-G for CLFE (rear panel) */
13842 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13843 /* port-H for side (rear panel) */
13844 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13846 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13847 /* route front mic to ADC1*/
13848 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13849 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13850 /* Unmute DAC0~3 & spdif out*/
13851 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13852 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13853 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13854 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13855 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13857 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13858 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13859 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13860 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13861 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13863 /* Unmute Stereo Mixer 15 */
13864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13869 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13870 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13871 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13872 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13874 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13875 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13876 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13877 /* hp used DAC 3 (Front) */
13878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13883 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13885 * Unmute ADC0 and set the default input to mic-in
13887 /* port-A for surround (rear panel) */
13888 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13889 /* port-B for mic-in (rear panel) with vref */
13890 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13891 /* port-C for line-in (rear panel) */
13892 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13893 /* port-D for Front */
13894 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13895 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13896 /* port-E for HP out (front panel) */
13897 /* this has to be set to VREF80 */
13898 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13899 /* route front PCM to HP */
13900 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13901 /* port-F for mic-in (front panel) with vref */
13902 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13903 /* port-G for CLFE (rear panel) */
13904 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13905 /* port-H for side (rear panel) */
13906 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13908 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13909 /* route front mic to ADC1*/
13910 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13911 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13912 /* Unmute DAC0~3 & spdif out*/
13913 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13914 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13915 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13916 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13919 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13920 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13921 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13922 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13923 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13925 /* Unmute Stereo Mixer 15 */
13926 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13927 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13929 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13931 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13932 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13933 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13934 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13935 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13936 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13937 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13938 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13939 /* hp used DAC 3 (Front) */
13940 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13945 static struct hda_verb alc861_asus_init_verbs[] = {
13947 * Unmute ADC0 and set the default input to mic-in
13949 /* port-A for surround (rear panel)
13950 * according to codec#0 this is the HP jack
13952 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13953 /* route front PCM to HP */
13954 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13955 /* port-B for mic-in (rear panel) with vref */
13956 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13957 /* port-C for line-in (rear panel) */
13958 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13959 /* port-D for Front */
13960 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13961 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13962 /* port-E for HP out (front panel) */
13963 /* this has to be set to VREF80 */
13964 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13965 /* route front PCM to HP */
13966 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13967 /* port-F for mic-in (front panel) with vref */
13968 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13969 /* port-G for CLFE (rear panel) */
13970 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13971 /* port-H for side (rear panel) */
13972 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13974 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13975 /* route front mic to ADC1*/
13976 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13977 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13978 /* Unmute DAC0~3 & spdif out*/
13979 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13980 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13981 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13982 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13983 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13984 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13985 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13986 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13987 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13988 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13990 /* Unmute Stereo Mixer 15 */
13991 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13992 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13993 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13996 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13997 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13998 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13999 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14000 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14002 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14003 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14004 /* hp used DAC 3 (Front) */
14005 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14006 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14010 /* additional init verbs for ASUS laptops */
14011 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14012 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14013 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14018 * generic initialization of ADC, input mixers and output mixers
14020 static struct hda_verb alc861_auto_init_verbs[] = {
14022 * Unmute ADC0 and set the default input to mic-in
14024 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14025 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14027 /* Unmute DAC0~3 & spdif out*/
14028 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14029 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14030 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14031 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14032 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14034 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14035 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14036 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14037 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14038 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14040 /* Unmute Stereo Mixer 15 */
14041 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14042 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14043 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14046 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14047 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14048 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14049 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14050 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14051 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14052 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14053 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14055 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14057 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14058 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14059 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14060 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14061 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14064 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14069 static struct hda_verb alc861_toshiba_init_verbs[] = {
14070 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14075 /* toggle speaker-output according to the hp-jack state */
14076 static void alc861_toshiba_automute(struct hda_codec *codec)
14078 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
14080 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14081 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14082 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14083 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14086 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14089 if ((res >> 26) == ALC880_HP_EVENT)
14090 alc861_toshiba_automute(codec);
14093 /* pcm configuration: identical with ALC880 */
14094 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
14095 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
14096 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
14097 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
14100 #define ALC861_DIGOUT_NID 0x07
14102 static struct hda_channel_mode alc861_8ch_modes[1] = {
14106 static hda_nid_t alc861_dac_nids[4] = {
14107 /* front, surround, clfe, side */
14108 0x03, 0x06, 0x05, 0x04
14111 static hda_nid_t alc660_dac_nids[3] = {
14112 /* front, clfe, surround */
14116 static hda_nid_t alc861_adc_nids[1] = {
14121 static struct hda_input_mux alc861_capture_source = {
14125 { "Front Mic", 0x3 },
14132 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14134 struct alc_spec *spec = codec->spec;
14135 hda_nid_t mix, srcs[5];
14138 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14140 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14143 for (i = 0; i < num; i++) {
14145 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14146 if (type != AC_WID_AUD_OUT)
14148 for (j = 0; j < spec->multiout.num_dacs; j++)
14149 if (spec->multiout.dac_nids[j] == srcs[i])
14151 if (j >= spec->multiout.num_dacs)
14157 /* fill in the dac_nids table from the parsed pin configuration */
14158 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14159 const struct auto_pin_cfg *cfg)
14161 struct alc_spec *spec = codec->spec;
14163 hda_nid_t nid, dac;
14165 spec->multiout.dac_nids = spec->private_dac_nids;
14166 for (i = 0; i < cfg->line_outs; i++) {
14167 nid = cfg->line_out_pins[i];
14168 dac = alc861_look_for_dac(codec, nid);
14171 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14176 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14177 hda_nid_t nid, unsigned int chs)
14179 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
14180 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14183 /* add playback controls from the parsed DAC table */
14184 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14185 const struct auto_pin_cfg *cfg)
14187 struct alc_spec *spec = codec->spec;
14188 static const char *chname[4] = {
14189 "Front", "Surround", NULL /*CLFE*/, "Side"
14194 if (cfg->line_outs == 1) {
14195 const char *pfx = NULL;
14198 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14201 nid = spec->multiout.dac_nids[0];
14202 return alc861_create_out_sw(codec, pfx, nid, 3);
14206 for (i = 0; i < cfg->line_outs; i++) {
14207 nid = spec->multiout.dac_nids[i];
14212 err = alc861_create_out_sw(codec, "Center", nid, 1);
14215 err = alc861_create_out_sw(codec, "LFE", nid, 2);
14219 err = alc861_create_out_sw(codec, chname[i], nid, 3);
14227 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14229 struct alc_spec *spec = codec->spec;
14236 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14237 nid = alc861_look_for_dac(codec, pin);
14239 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14242 spec->multiout.hp_nid = nid;
14248 /* create playback/capture controls for input pins */
14249 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
14250 const struct auto_pin_cfg *cfg)
14252 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
14255 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14257 int pin_type, hda_nid_t dac)
14259 hda_nid_t mix, srcs[5];
14262 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14264 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14266 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14268 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14271 for (i = 0; i < num; i++) {
14273 if (srcs[i] == dac || srcs[i] == 0x15)
14274 mute = AMP_IN_UNMUTE(i);
14276 mute = AMP_IN_MUTE(i);
14277 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14282 static void alc861_auto_init_multi_out(struct hda_codec *codec)
14284 struct alc_spec *spec = codec->spec;
14287 for (i = 0; i < spec->autocfg.line_outs; i++) {
14288 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14289 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14291 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14292 spec->multiout.dac_nids[i]);
14296 static void alc861_auto_init_hp_out(struct hda_codec *codec)
14298 struct alc_spec *spec = codec->spec;
14300 if (spec->autocfg.hp_outs)
14301 alc861_auto_set_output_and_unmute(codec,
14302 spec->autocfg.hp_pins[0],
14304 spec->multiout.hp_nid);
14305 if (spec->autocfg.speaker_outs)
14306 alc861_auto_set_output_and_unmute(codec,
14307 spec->autocfg.speaker_pins[0],
14309 spec->multiout.dac_nids[0]);
14312 static void alc861_auto_init_analog_input(struct hda_codec *codec)
14314 struct alc_spec *spec = codec->spec;
14317 for (i = 0; i < AUTO_PIN_LAST; i++) {
14318 hda_nid_t nid = spec->autocfg.input_pins[i];
14319 if (nid >= 0x0c && nid <= 0x11)
14320 alc_set_input_pin(codec, nid, i);
14324 /* parse the BIOS configuration and set up the alc_spec */
14325 /* return 1 if successful, 0 if the proper config is not found,
14326 * or a negative error code
14328 static int alc861_parse_auto_config(struct hda_codec *codec)
14330 struct alc_spec *spec = codec->spec;
14332 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14334 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14338 if (!spec->autocfg.line_outs)
14339 return 0; /* can't find valid BIOS pin config */
14341 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14344 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14347 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14350 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
14354 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14356 if (spec->autocfg.dig_outs)
14357 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14359 if (spec->kctls.list)
14360 add_mixer(spec, spec->kctls.list);
14362 add_verb(spec, alc861_auto_init_verbs);
14364 spec->num_mux_defs = 1;
14365 spec->input_mux = &spec->private_imux[0];
14367 spec->adc_nids = alc861_adc_nids;
14368 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14369 set_capture_mixer(codec);
14371 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14376 /* additional initialization for auto-configuration model */
14377 static void alc861_auto_init(struct hda_codec *codec)
14379 struct alc_spec *spec = codec->spec;
14380 alc861_auto_init_multi_out(codec);
14381 alc861_auto_init_hp_out(codec);
14382 alc861_auto_init_analog_input(codec);
14383 if (spec->unsol_event)
14384 alc_inithook(codec);
14387 #ifdef CONFIG_SND_HDA_POWER_SAVE
14388 static struct hda_amp_list alc861_loopbacks[] = {
14389 { 0x15, HDA_INPUT, 0 },
14390 { 0x15, HDA_INPUT, 1 },
14391 { 0x15, HDA_INPUT, 2 },
14392 { 0x15, HDA_INPUT, 3 },
14399 * configuration and preset
14401 static const char *alc861_models[ALC861_MODEL_LAST] = {
14402 [ALC861_3ST] = "3stack",
14403 [ALC660_3ST] = "3stack-660",
14404 [ALC861_3ST_DIG] = "3stack-dig",
14405 [ALC861_6ST_DIG] = "6stack-dig",
14406 [ALC861_UNIWILL_M31] = "uniwill-m31",
14407 [ALC861_TOSHIBA] = "toshiba",
14408 [ALC861_ASUS] = "asus",
14409 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14410 [ALC861_AUTO] = "auto",
14413 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14414 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14415 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14416 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14417 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14418 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14419 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14420 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14421 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14422 * Any other models that need this preset?
14424 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14425 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14426 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14427 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14428 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14429 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14430 /* FIXME: the below seems conflict */
14431 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14432 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14433 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14437 static struct alc_config_preset alc861_presets[] = {
14439 .mixers = { alc861_3ST_mixer },
14440 .init_verbs = { alc861_threestack_init_verbs },
14441 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14442 .dac_nids = alc861_dac_nids,
14443 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14444 .channel_mode = alc861_threestack_modes,
14446 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14447 .adc_nids = alc861_adc_nids,
14448 .input_mux = &alc861_capture_source,
14450 [ALC861_3ST_DIG] = {
14451 .mixers = { alc861_base_mixer },
14452 .init_verbs = { alc861_threestack_init_verbs },
14453 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14454 .dac_nids = alc861_dac_nids,
14455 .dig_out_nid = ALC861_DIGOUT_NID,
14456 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14457 .channel_mode = alc861_threestack_modes,
14459 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14460 .adc_nids = alc861_adc_nids,
14461 .input_mux = &alc861_capture_source,
14463 [ALC861_6ST_DIG] = {
14464 .mixers = { alc861_base_mixer },
14465 .init_verbs = { alc861_base_init_verbs },
14466 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14467 .dac_nids = alc861_dac_nids,
14468 .dig_out_nid = ALC861_DIGOUT_NID,
14469 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14470 .channel_mode = alc861_8ch_modes,
14471 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14472 .adc_nids = alc861_adc_nids,
14473 .input_mux = &alc861_capture_source,
14476 .mixers = { alc861_3ST_mixer },
14477 .init_verbs = { alc861_threestack_init_verbs },
14478 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14479 .dac_nids = alc660_dac_nids,
14480 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14481 .channel_mode = alc861_threestack_modes,
14483 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14484 .adc_nids = alc861_adc_nids,
14485 .input_mux = &alc861_capture_source,
14487 [ALC861_UNIWILL_M31] = {
14488 .mixers = { alc861_uniwill_m31_mixer },
14489 .init_verbs = { alc861_uniwill_m31_init_verbs },
14490 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14491 .dac_nids = alc861_dac_nids,
14492 .dig_out_nid = ALC861_DIGOUT_NID,
14493 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14494 .channel_mode = alc861_uniwill_m31_modes,
14496 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14497 .adc_nids = alc861_adc_nids,
14498 .input_mux = &alc861_capture_source,
14500 [ALC861_TOSHIBA] = {
14501 .mixers = { alc861_toshiba_mixer },
14502 .init_verbs = { alc861_base_init_verbs,
14503 alc861_toshiba_init_verbs },
14504 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14505 .dac_nids = alc861_dac_nids,
14506 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14507 .channel_mode = alc883_3ST_2ch_modes,
14508 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14509 .adc_nids = alc861_adc_nids,
14510 .input_mux = &alc861_capture_source,
14511 .unsol_event = alc861_toshiba_unsol_event,
14512 .init_hook = alc861_toshiba_automute,
14515 .mixers = { alc861_asus_mixer },
14516 .init_verbs = { alc861_asus_init_verbs },
14517 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14518 .dac_nids = alc861_dac_nids,
14519 .dig_out_nid = ALC861_DIGOUT_NID,
14520 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14521 .channel_mode = alc861_asus_modes,
14524 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14525 .adc_nids = alc861_adc_nids,
14526 .input_mux = &alc861_capture_source,
14528 [ALC861_ASUS_LAPTOP] = {
14529 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14530 .init_verbs = { alc861_asus_init_verbs,
14531 alc861_asus_laptop_init_verbs },
14532 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14533 .dac_nids = alc861_dac_nids,
14534 .dig_out_nid = ALC861_DIGOUT_NID,
14535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14536 .channel_mode = alc883_3ST_2ch_modes,
14538 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14539 .adc_nids = alc861_adc_nids,
14540 .input_mux = &alc861_capture_source,
14545 static int patch_alc861(struct hda_codec *codec)
14547 struct alc_spec *spec;
14551 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14555 codec->spec = spec;
14557 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14561 if (board_config < 0) {
14562 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14564 board_config = ALC861_AUTO;
14567 if (board_config == ALC861_AUTO) {
14568 /* automatic parse from the BIOS config */
14569 err = alc861_parse_auto_config(codec);
14575 "hda_codec: Cannot set up configuration "
14576 "from BIOS. Using base mode...\n");
14577 board_config = ALC861_3ST_DIG;
14581 err = snd_hda_attach_beep_device(codec, 0x23);
14587 if (board_config != ALC861_AUTO)
14588 setup_preset(codec, &alc861_presets[board_config]);
14590 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14591 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14593 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14594 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14596 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14598 spec->vmaster_nid = 0x03;
14600 codec->patch_ops = alc_patch_ops;
14601 if (board_config == ALC861_AUTO)
14602 spec->init_hook = alc861_auto_init;
14603 #ifdef CONFIG_SND_HDA_POWER_SAVE
14604 if (!spec->loopback.amplist)
14605 spec->loopback.amplist = alc861_loopbacks;
14607 codec->proc_widget_hook = print_realtek_coef;
14613 * ALC861-VD support
14617 * In addition, an independent DAC
14619 #define ALC861VD_DIGOUT_NID 0x06
14621 static hda_nid_t alc861vd_dac_nids[4] = {
14622 /* front, surr, clfe, side surr */
14623 0x02, 0x03, 0x04, 0x05
14626 /* dac_nids for ALC660vd are in a different order - according to
14627 * Realtek's driver.
14628 * This should probably result in a different mixer for 6stack models
14629 * of ALC660vd codecs, but for now there is only 3stack mixer
14630 * - and it is the same as in 861vd.
14631 * adc_nids in ALC660vd are (is) the same as in 861vd
14633 static hda_nid_t alc660vd_dac_nids[3] = {
14634 /* front, rear, clfe, rear_surr */
14638 static hda_nid_t alc861vd_adc_nids[1] = {
14643 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14646 /* FIXME: should be a matrix-type input source selection */
14647 static struct hda_input_mux alc861vd_capture_source = {
14651 { "Front Mic", 0x1 },
14657 static struct hda_input_mux alc861vd_dallas_capture_source = {
14660 { "Ext Mic", 0x0 },
14661 { "Int Mic", 0x1 },
14665 static struct hda_input_mux alc861vd_hp_capture_source = {
14668 { "Front Mic", 0x0 },
14669 { "ATAPI Mic", 0x1 },
14676 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14683 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14684 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14685 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14686 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14687 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14694 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14695 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14697 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14698 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14702 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14703 { 6, alc861vd_6stack_ch6_init },
14704 { 8, alc861vd_6stack_ch8_init },
14707 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14710 .name = "Channel Mode",
14711 .info = alc_ch_mode_info,
14712 .get = alc_ch_mode_get,
14713 .put = alc_ch_mode_put,
14718 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14719 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14721 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14722 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14723 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14725 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14726 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14728 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14730 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14732 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14733 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14735 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14736 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14738 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14740 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14744 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14745 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14746 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14748 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14749 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14751 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14752 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14757 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14758 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14759 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14761 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14767 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14768 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14769 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14771 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14772 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14774 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14775 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14780 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14781 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14782 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14783 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14787 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14788 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14789 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14791 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14792 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14793 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14795 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14796 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14801 /* Pin assignment: Speaker=0x14, HP = 0x15,
14802 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14804 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14805 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14806 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14807 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14808 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14809 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14810 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14811 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14812 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14813 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14814 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14818 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14819 * Front Mic=0x18, ATAPI Mic = 0x19,
14821 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14822 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14823 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14824 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14825 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14827 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14828 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14829 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14835 * generic initialization of ADC, input mixers and output mixers
14837 static struct hda_verb alc861vd_volume_init_verbs[] = {
14839 * Unmute ADC0 and set the default input to mic-in
14841 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14842 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14844 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14845 * the analog-loopback mixer widget
14847 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14854 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14855 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14856 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14861 * Set up output mixers (0x02 - 0x05)
14863 /* set vol=0 to output mixers */
14864 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14865 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14866 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14867 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14869 /* set up input amps for analog loopback */
14870 /* Amp Indices: DAC = 0, mixer = 1 */
14871 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14873 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14874 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14875 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14876 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14877 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14878 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14884 * 3-stack pin configuration:
14885 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14887 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14889 * Set pin mode and muting
14891 /* set front pin widgets 0x14 for output */
14892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14894 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14896 /* Mic (rear) pin: input vref at 80% */
14897 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14898 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14899 /* Front Mic pin: input vref at 80% */
14900 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14901 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14902 /* Line In pin: input */
14903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14904 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14905 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14908 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14909 /* CD pin widget for input */
14910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14916 * 6-stack pin configuration:
14918 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14920 * Set pin mode and muting
14922 /* set front pin widgets 0x14 for output */
14923 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14924 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14925 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14927 /* Rear Pin: output 1 (0x0d) */
14928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14929 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14930 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14931 /* CLFE Pin: output 2 (0x0e) */
14932 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14933 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14934 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14935 /* Side Pin: output 3 (0x0f) */
14936 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14937 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14938 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14940 /* Mic (rear) pin: input vref at 80% */
14941 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14942 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14943 /* Front Mic pin: input vref at 80% */
14944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14946 /* Line In pin: input */
14947 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14948 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14949 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14950 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14951 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14952 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14953 /* CD pin widget for input */
14954 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14959 static struct hda_verb alc861vd_eapd_verbs[] = {
14960 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14964 static struct hda_verb alc660vd_eapd_verbs[] = {
14965 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14966 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14970 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14974 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14975 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14979 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14981 unsigned int present;
14982 unsigned char bits;
14984 present = snd_hda_jack_detect(codec, 0x18);
14985 bits = present ? HDA_AMP_MUTE : 0;
14987 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14988 HDA_AMP_MUTE, bits);
14991 static void alc861vd_lenovo_setup(struct hda_codec *codec)
14993 struct alc_spec *spec = codec->spec;
14994 spec->autocfg.hp_pins[0] = 0x1b;
14995 spec->autocfg.speaker_pins[0] = 0x14;
14998 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15000 alc_automute_amp(codec);
15001 alc861vd_lenovo_mic_automute(codec);
15004 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15007 switch (res >> 26) {
15008 case ALC880_MIC_EVENT:
15009 alc861vd_lenovo_mic_automute(codec);
15012 alc_automute_amp_unsol_event(codec, res);
15017 static struct hda_verb alc861vd_dallas_verbs[] = {
15018 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15019 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15020 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15021 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15025 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15027 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15029 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15030 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15033 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15036 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15037 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15038 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15039 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15041 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15042 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15043 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15044 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15045 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15046 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15047 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15048 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15055 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15056 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15057 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15062 /* toggle speaker-output according to the hp-jack state */
15063 static void alc861vd_dallas_setup(struct hda_codec *codec)
15065 struct alc_spec *spec = codec->spec;
15067 spec->autocfg.hp_pins[0] = 0x15;
15068 spec->autocfg.speaker_pins[0] = 0x14;
15071 #ifdef CONFIG_SND_HDA_POWER_SAVE
15072 #define alc861vd_loopbacks alc880_loopbacks
15075 /* pcm configuration: identical with ALC880 */
15076 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15077 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15078 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15079 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15082 * configuration and preset
15084 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15085 [ALC660VD_3ST] = "3stack-660",
15086 [ALC660VD_3ST_DIG] = "3stack-660-digout",
15087 [ALC660VD_ASUS_V1S] = "asus-v1s",
15088 [ALC861VD_3ST] = "3stack",
15089 [ALC861VD_3ST_DIG] = "3stack-digout",
15090 [ALC861VD_6ST_DIG] = "6stack-digout",
15091 [ALC861VD_LENOVO] = "lenovo",
15092 [ALC861VD_DALLAS] = "dallas",
15093 [ALC861VD_HP] = "hp",
15094 [ALC861VD_AUTO] = "auto",
15097 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15098 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15099 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15100 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15101 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15102 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15103 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15104 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
15105 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
15106 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
15107 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
15108 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
15109 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
15110 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
15111 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
15112 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
15116 static struct alc_config_preset alc861vd_presets[] = {
15118 .mixers = { alc861vd_3st_mixer },
15119 .init_verbs = { alc861vd_volume_init_verbs,
15120 alc861vd_3stack_init_verbs },
15121 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15122 .dac_nids = alc660vd_dac_nids,
15123 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15124 .channel_mode = alc861vd_3stack_2ch_modes,
15125 .input_mux = &alc861vd_capture_source,
15127 [ALC660VD_3ST_DIG] = {
15128 .mixers = { alc861vd_3st_mixer },
15129 .init_verbs = { alc861vd_volume_init_verbs,
15130 alc861vd_3stack_init_verbs },
15131 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15132 .dac_nids = alc660vd_dac_nids,
15133 .dig_out_nid = ALC861VD_DIGOUT_NID,
15134 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15135 .channel_mode = alc861vd_3stack_2ch_modes,
15136 .input_mux = &alc861vd_capture_source,
15139 .mixers = { alc861vd_3st_mixer },
15140 .init_verbs = { alc861vd_volume_init_verbs,
15141 alc861vd_3stack_init_verbs },
15142 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15143 .dac_nids = alc861vd_dac_nids,
15144 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15145 .channel_mode = alc861vd_3stack_2ch_modes,
15146 .input_mux = &alc861vd_capture_source,
15148 [ALC861VD_3ST_DIG] = {
15149 .mixers = { alc861vd_3st_mixer },
15150 .init_verbs = { alc861vd_volume_init_verbs,
15151 alc861vd_3stack_init_verbs },
15152 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15153 .dac_nids = alc861vd_dac_nids,
15154 .dig_out_nid = ALC861VD_DIGOUT_NID,
15155 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15156 .channel_mode = alc861vd_3stack_2ch_modes,
15157 .input_mux = &alc861vd_capture_source,
15159 [ALC861VD_6ST_DIG] = {
15160 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15161 .init_verbs = { alc861vd_volume_init_verbs,
15162 alc861vd_6stack_init_verbs },
15163 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15164 .dac_nids = alc861vd_dac_nids,
15165 .dig_out_nid = ALC861VD_DIGOUT_NID,
15166 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15167 .channel_mode = alc861vd_6stack_modes,
15168 .input_mux = &alc861vd_capture_source,
15170 [ALC861VD_LENOVO] = {
15171 .mixers = { alc861vd_lenovo_mixer },
15172 .init_verbs = { alc861vd_volume_init_verbs,
15173 alc861vd_3stack_init_verbs,
15174 alc861vd_eapd_verbs,
15175 alc861vd_lenovo_unsol_verbs },
15176 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15177 .dac_nids = alc660vd_dac_nids,
15178 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15179 .channel_mode = alc861vd_3stack_2ch_modes,
15180 .input_mux = &alc861vd_capture_source,
15181 .unsol_event = alc861vd_lenovo_unsol_event,
15182 .setup = alc861vd_lenovo_setup,
15183 .init_hook = alc861vd_lenovo_init_hook,
15185 [ALC861VD_DALLAS] = {
15186 .mixers = { alc861vd_dallas_mixer },
15187 .init_verbs = { alc861vd_dallas_verbs },
15188 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15189 .dac_nids = alc861vd_dac_nids,
15190 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15191 .channel_mode = alc861vd_3stack_2ch_modes,
15192 .input_mux = &alc861vd_dallas_capture_source,
15193 .unsol_event = alc_automute_amp_unsol_event,
15194 .setup = alc861vd_dallas_setup,
15195 .init_hook = alc_automute_amp,
15198 .mixers = { alc861vd_hp_mixer },
15199 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15200 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15201 .dac_nids = alc861vd_dac_nids,
15202 .dig_out_nid = ALC861VD_DIGOUT_NID,
15203 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15204 .channel_mode = alc861vd_3stack_2ch_modes,
15205 .input_mux = &alc861vd_hp_capture_source,
15206 .unsol_event = alc_automute_amp_unsol_event,
15207 .setup = alc861vd_dallas_setup,
15208 .init_hook = alc_automute_amp,
15210 [ALC660VD_ASUS_V1S] = {
15211 .mixers = { alc861vd_lenovo_mixer },
15212 .init_verbs = { alc861vd_volume_init_verbs,
15213 alc861vd_3stack_init_verbs,
15214 alc861vd_eapd_verbs,
15215 alc861vd_lenovo_unsol_verbs },
15216 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15217 .dac_nids = alc660vd_dac_nids,
15218 .dig_out_nid = ALC861VD_DIGOUT_NID,
15219 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15220 .channel_mode = alc861vd_3stack_2ch_modes,
15221 .input_mux = &alc861vd_capture_source,
15222 .unsol_event = alc861vd_lenovo_unsol_event,
15223 .setup = alc861vd_lenovo_setup,
15224 .init_hook = alc861vd_lenovo_init_hook,
15229 * BIOS auto configuration
15231 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15232 const struct auto_pin_cfg *cfg)
15234 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15238 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15239 hda_nid_t nid, int pin_type, int dac_idx)
15241 alc_set_pin_output(codec, nid, pin_type);
15244 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15246 struct alc_spec *spec = codec->spec;
15249 for (i = 0; i <= HDA_SIDE; i++) {
15250 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15251 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15253 alc861vd_auto_set_output_and_unmute(codec, nid,
15259 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15261 struct alc_spec *spec = codec->spec;
15264 pin = spec->autocfg.hp_pins[0];
15265 if (pin) /* connect to front and use dac 0 */
15266 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15267 pin = spec->autocfg.speaker_pins[0];
15269 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15272 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15274 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15276 struct alc_spec *spec = codec->spec;
15279 for (i = 0; i < AUTO_PIN_LAST; i++) {
15280 hda_nid_t nid = spec->autocfg.input_pins[i];
15281 if (alc_is_input_pin(codec, nid)) {
15282 alc_set_input_pin(codec, nid, i);
15283 if (nid != ALC861VD_PIN_CD_NID &&
15284 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15285 snd_hda_codec_write(codec, nid, 0,
15286 AC_VERB_SET_AMP_GAIN_MUTE,
15292 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
15294 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15295 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15297 /* add playback controls from the parsed DAC table */
15298 /* Based on ALC880 version. But ALC861VD has separate,
15299 * different NIDs for mute/unmute switch and volume control */
15300 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15301 const struct auto_pin_cfg *cfg)
15303 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15304 hda_nid_t nid_v, nid_s;
15307 for (i = 0; i < cfg->line_outs; i++) {
15308 if (!spec->multiout.dac_nids[i])
15310 nid_v = alc861vd_idx_to_mixer_vol(
15312 spec->multiout.dac_nids[i]));
15313 nid_s = alc861vd_idx_to_mixer_switch(
15315 spec->multiout.dac_nids[i]));
15319 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15321 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15325 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15327 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15331 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15333 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15337 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15339 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15345 if (cfg->line_outs == 1 &&
15346 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15353 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15354 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15358 if (cfg->line_outs == 1 &&
15359 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15361 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15362 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15371 /* add playback controls for speaker and HP outputs */
15372 /* Based on ALC880 version. But ALC861VD has separate,
15373 * different NIDs for mute/unmute switch and volume control */
15374 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15375 hda_nid_t pin, const char *pfx)
15377 hda_nid_t nid_v, nid_s;
15383 if (alc880_is_fixed_pin(pin)) {
15384 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15385 /* specify the DAC as the extra output */
15386 if (!spec->multiout.hp_nid)
15387 spec->multiout.hp_nid = nid_v;
15389 spec->multiout.extra_out_nid[0] = nid_v;
15390 /* control HP volume/switch on the output mixer amp */
15391 nid_v = alc861vd_idx_to_mixer_vol(
15392 alc880_fixed_pin_idx(pin));
15393 nid_s = alc861vd_idx_to_mixer_switch(
15394 alc880_fixed_pin_idx(pin));
15396 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15397 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15400 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15401 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15404 } else if (alc880_is_multi_pin(pin)) {
15405 /* set manual connection */
15406 /* we have only a switch on HP-out PIN */
15407 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
15408 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15415 /* parse the BIOS configuration and set up the alc_spec
15416 * return 1 if successful, 0 if the proper config is not found,
15417 * or a negative error code
15418 * Based on ALC880 version - had to change it to override
15419 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15420 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15422 struct alc_spec *spec = codec->spec;
15424 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15426 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15430 if (!spec->autocfg.line_outs)
15431 return 0; /* can't find valid BIOS pin config */
15433 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15436 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15439 err = alc861vd_auto_create_extra_out(spec,
15440 spec->autocfg.speaker_pins[0],
15444 err = alc861vd_auto_create_extra_out(spec,
15445 spec->autocfg.hp_pins[0],
15449 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
15453 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15455 if (spec->autocfg.dig_outs)
15456 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15458 if (spec->kctls.list)
15459 add_mixer(spec, spec->kctls.list);
15461 add_verb(spec, alc861vd_volume_init_verbs);
15463 spec->num_mux_defs = 1;
15464 spec->input_mux = &spec->private_imux[0];
15466 err = alc_auto_add_mic_boost(codec);
15470 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15475 /* additional initialization for auto-configuration model */
15476 static void alc861vd_auto_init(struct hda_codec *codec)
15478 struct alc_spec *spec = codec->spec;
15479 alc861vd_auto_init_multi_out(codec);
15480 alc861vd_auto_init_hp_out(codec);
15481 alc861vd_auto_init_analog_input(codec);
15482 alc861vd_auto_init_input_src(codec);
15483 if (spec->unsol_event)
15484 alc_inithook(codec);
15488 ALC660VD_FIX_ASUS_GPIO1
15492 static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15493 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15494 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15495 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15499 static const struct alc_fixup alc861vd_fixups[] = {
15500 [ALC660VD_FIX_ASUS_GPIO1] = {
15501 .verbs = alc660vd_fix_asus_gpio1_verbs,
15505 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15506 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15510 static int patch_alc861vd(struct hda_codec *codec)
15512 struct alc_spec *spec;
15513 int err, board_config;
15515 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15519 codec->spec = spec;
15521 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15525 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15526 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15528 board_config = ALC861VD_AUTO;
15531 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15533 if (board_config == ALC861VD_AUTO) {
15534 /* automatic parse from the BIOS config */
15535 err = alc861vd_parse_auto_config(codec);
15541 "hda_codec: Cannot set up configuration "
15542 "from BIOS. Using base mode...\n");
15543 board_config = ALC861VD_3ST;
15547 err = snd_hda_attach_beep_device(codec, 0x23);
15553 if (board_config != ALC861VD_AUTO)
15554 setup_preset(codec, &alc861vd_presets[board_config]);
15556 if (codec->vendor_id == 0x10ec0660) {
15557 /* always turn on EAPD */
15558 add_verb(spec, alc660vd_eapd_verbs);
15561 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15562 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15564 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15565 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15567 if (!spec->adc_nids) {
15568 spec->adc_nids = alc861vd_adc_nids;
15569 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15571 if (!spec->capsrc_nids)
15572 spec->capsrc_nids = alc861vd_capsrc_nids;
15574 set_capture_mixer(codec);
15575 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15577 spec->vmaster_nid = 0x02;
15579 codec->patch_ops = alc_patch_ops;
15581 if (board_config == ALC861VD_AUTO)
15582 spec->init_hook = alc861vd_auto_init;
15583 #ifdef CONFIG_SND_HDA_POWER_SAVE
15584 if (!spec->loopback.amplist)
15585 spec->loopback.amplist = alc861vd_loopbacks;
15587 codec->proc_widget_hook = print_realtek_coef;
15595 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15596 * configuration. Each pin widget can choose any input DACs and a mixer.
15597 * Each ADC is connected from a mixer of all inputs. This makes possible
15598 * 6-channel independent captures.
15600 * In addition, an independent DAC for the multi-playback (not used in this
15603 #define ALC662_DIGOUT_NID 0x06
15604 #define ALC662_DIGIN_NID 0x0a
15606 static hda_nid_t alc662_dac_nids[4] = {
15607 /* front, rear, clfe, rear_surr */
15611 static hda_nid_t alc272_dac_nids[2] = {
15615 static hda_nid_t alc662_adc_nids[2] = {
15620 static hda_nid_t alc272_adc_nids[1] = {
15625 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
15626 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15630 /* FIXME: should be a matrix-type input source selection */
15631 static struct hda_input_mux alc662_capture_source = {
15635 { "Front Mic", 0x1 },
15641 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15649 static struct hda_input_mux alc663_capture_source = {
15653 { "Front Mic", 0x1 },
15658 #if 0 /* set to 1 for testing other input sources below */
15659 static struct hda_input_mux alc272_nc10_capture_source = {
15662 { "Autoselect Mic", 0x0 },
15663 { "Internal Mic", 0x1 },
15664 { "In-0x02", 0x2 },
15665 { "In-0x03", 0x3 },
15666 { "In-0x04", 0x4 },
15667 { "In-0x05", 0x5 },
15668 { "In-0x06", 0x6 },
15669 { "In-0x07", 0x7 },
15670 { "In-0x08", 0x8 },
15671 { "In-0x09", 0x9 },
15672 { "In-0x0a", 0x0a },
15673 { "In-0x0b", 0x0b },
15674 { "In-0x0c", 0x0c },
15675 { "In-0x0d", 0x0d },
15676 { "In-0x0e", 0x0e },
15677 { "In-0x0f", 0x0f },
15685 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15692 static struct hda_verb alc662_3ST_ch2_init[] = {
15693 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15694 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15695 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15696 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15703 static struct hda_verb alc662_3ST_ch6_init[] = {
15704 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15705 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15706 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15707 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15708 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15709 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15713 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15714 { 2, alc662_3ST_ch2_init },
15715 { 6, alc662_3ST_ch6_init },
15721 static struct hda_verb alc662_sixstack_ch6_init[] = {
15722 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15723 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15724 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15731 static struct hda_verb alc662_sixstack_ch8_init[] = {
15732 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15733 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15734 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15738 static struct hda_channel_mode alc662_5stack_modes[2] = {
15739 { 2, alc662_sixstack_ch6_init },
15740 { 6, alc662_sixstack_ch8_init },
15743 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15744 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15747 static struct snd_kcontrol_new alc662_base_mixer[] = {
15748 /* output mixer control */
15749 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15750 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15751 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15752 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15753 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15754 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15755 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15756 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15759 /*Input mixer control */
15760 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15761 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15762 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15763 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15764 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15765 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15766 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15767 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15771 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15772 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15773 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15774 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15775 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15776 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15777 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15778 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15781 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15782 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15786 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15787 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15788 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15789 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15790 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15791 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15792 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15793 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15794 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15795 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15796 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15797 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15801 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15802 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15803 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15807 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15808 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15809 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15810 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15811 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15812 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15813 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15814 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15815 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15820 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15821 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15822 ALC262_HIPPO_MASTER_SWITCH,
15824 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15825 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15826 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15828 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15829 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15830 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15834 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15835 ALC262_HIPPO_MASTER_SWITCH,
15836 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15837 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15838 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15839 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15840 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15841 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15842 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15848 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15849 .ops = &snd_hda_bind_vol,
15851 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15852 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15857 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15858 .ops = &snd_hda_bind_sw,
15860 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15861 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15866 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15867 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15868 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15874 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15875 .ops = &snd_hda_bind_sw,
15877 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15878 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15879 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15884 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15885 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15886 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15887 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15888 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15889 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15890 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15895 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15896 .ops = &snd_hda_bind_sw,
15898 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15899 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15900 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15905 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15906 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15907 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15908 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15910 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15911 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15915 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15916 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15917 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15921 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15922 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15926 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15927 .ops = &snd_hda_bind_vol,
15929 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15930 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15935 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15936 .ops = &snd_hda_bind_sw,
15938 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15939 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15944 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15945 HDA_BIND_VOL("Master Playback Volume",
15946 &alc663_asus_two_bind_master_vol),
15947 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15948 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15949 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15950 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15955 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15956 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15957 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15959 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15960 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15961 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15965 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15966 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15967 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15968 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15969 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15970 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15974 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15975 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15979 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15980 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15981 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15982 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15986 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15987 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15988 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15989 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15993 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15996 .name = "Channel Mode",
15997 .info = alc_ch_mode_info,
15998 .get = alc_ch_mode_get,
15999 .put = alc_ch_mode_put,
16004 static struct hda_verb alc662_init_verbs[] = {
16005 /* ADC: mute amp left and right */
16006 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16007 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16008 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16016 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16020 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16023 /* Front Pin: output 0 (0x0c) */
16024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16025 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16027 /* Rear Pin: output 1 (0x0d) */
16028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16029 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16031 /* CLFE Pin: output 2 (0x0e) */
16032 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16033 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16035 /* Mic (rear) pin: input vref at 80% */
16036 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16038 /* Front Mic pin: input vref at 80% */
16039 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16040 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16041 /* Line In pin: input */
16042 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16043 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16044 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16045 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16046 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16047 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16048 /* CD pin widget for input */
16049 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16051 /* FIXME: use matrix-type input source selection */
16052 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16057 /* always trun on EAPD */
16058 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16059 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16064 static struct hda_verb alc662_sue_init_verbs[] = {
16065 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16066 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16070 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16071 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16076 /* Set Unsolicited Event*/
16077 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16078 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16079 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16084 * generic initialization of ADC, input mixers and output mixers
16086 static struct hda_verb alc662_auto_init_verbs[] = {
16088 * Unmute ADC and set the default input to mic-in
16090 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16093 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16095 * Note: PASD motherboards uses the Line In 2 as the input for front
16096 * panel mic (mic 2)
16098 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16106 * Set up output mixers (0x0c - 0x0f)
16108 /* set vol=0 to output mixers */
16109 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16110 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16111 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16113 /* set up input amps for analog loopback */
16114 /* Amp Indices: DAC = 0, mixer = 1 */
16115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16123 /* FIXME: use matrix-type input source selection */
16124 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16131 /* additional verbs for ALC663 */
16132 static struct hda_verb alc663_auto_init_verbs[] = {
16133 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16134 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16138 static struct hda_verb alc663_m51va_init_verbs[] = {
16139 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16140 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16141 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16143 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16146 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16147 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16151 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16152 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16153 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16154 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16162 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16163 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16164 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16165 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16166 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16169 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16170 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16174 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16176 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16178 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16180 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16181 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16185 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16186 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16187 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16188 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16189 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16190 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16192 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16193 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16194 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16195 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16196 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16197 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16201 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16202 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16203 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16204 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16205 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16206 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16208 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16209 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16210 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16211 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16212 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16213 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16217 static struct hda_verb alc663_g71v_init_verbs[] = {
16218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16219 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16220 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16222 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16223 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16224 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16226 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16227 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16228 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16232 static struct hda_verb alc663_g50v_init_verbs[] = {
16233 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16234 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16235 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16237 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16238 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16242 static struct hda_verb alc662_ecs_init_verbs[] = {
16243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16244 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16245 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16246 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16250 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16251 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16252 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16253 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16254 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16255 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16256 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16257 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16260 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16261 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16265 static struct hda_verb alc272_dell_init_verbs[] = {
16266 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16267 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16269 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16270 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16271 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16272 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16273 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16274 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16275 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16276 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16280 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16281 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16282 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16286 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16287 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16288 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16292 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16294 unsigned int present;
16295 unsigned char bits;
16297 present = snd_hda_jack_detect(codec, 0x14);
16298 bits = present ? HDA_AMP_MUTE : 0;
16300 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16301 HDA_AMP_MUTE, bits);
16304 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16306 unsigned int present;
16307 unsigned char bits;
16309 present = snd_hda_jack_detect(codec, 0x1b);
16310 bits = present ? HDA_AMP_MUTE : 0;
16312 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16313 HDA_AMP_MUTE, bits);
16314 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16315 HDA_AMP_MUTE, bits);
16318 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16321 if ((res >> 26) == ALC880_HP_EVENT)
16322 alc662_lenovo_101e_all_automute(codec);
16323 if ((res >> 26) == ALC880_FRONT_EVENT)
16324 alc662_lenovo_101e_ispeaker_automute(codec);
16327 /* unsolicited event for HP jack sensing */
16328 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16331 if ((res >> 26) == ALC880_MIC_EVENT)
16332 alc_mic_automute(codec);
16334 alc262_hippo_unsol_event(codec, res);
16337 static void alc662_eeepc_setup(struct hda_codec *codec)
16339 struct alc_spec *spec = codec->spec;
16341 alc262_hippo1_setup(codec);
16342 spec->ext_mic.pin = 0x18;
16343 spec->ext_mic.mux_idx = 0;
16344 spec->int_mic.pin = 0x19;
16345 spec->int_mic.mux_idx = 1;
16346 spec->auto_mic = 1;
16349 static void alc662_eeepc_inithook(struct hda_codec *codec)
16351 alc262_hippo_automute(codec);
16352 alc_mic_automute(codec);
16355 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
16357 struct alc_spec *spec = codec->spec;
16359 spec->autocfg.hp_pins[0] = 0x14;
16360 spec->autocfg.speaker_pins[0] = 0x1b;
16363 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
16365 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16367 unsigned int present;
16368 unsigned char bits;
16370 present = snd_hda_jack_detect(codec, 0x21);
16371 bits = present ? HDA_AMP_MUTE : 0;
16372 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16373 AMP_IN_MUTE(0), bits);
16374 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16375 AMP_IN_MUTE(0), bits);
16378 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16380 unsigned int present;
16381 unsigned char bits;
16383 present = snd_hda_jack_detect(codec, 0x21);
16384 bits = present ? HDA_AMP_MUTE : 0;
16385 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16386 AMP_IN_MUTE(0), bits);
16387 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16388 AMP_IN_MUTE(0), bits);
16389 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16390 AMP_IN_MUTE(0), bits);
16391 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16392 AMP_IN_MUTE(0), bits);
16395 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16397 unsigned int present;
16398 unsigned char bits;
16400 present = snd_hda_jack_detect(codec, 0x15);
16401 bits = present ? HDA_AMP_MUTE : 0;
16402 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16403 AMP_IN_MUTE(0), bits);
16404 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16405 AMP_IN_MUTE(0), bits);
16406 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16407 AMP_IN_MUTE(0), bits);
16408 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16409 AMP_IN_MUTE(0), bits);
16412 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16414 unsigned int present;
16415 unsigned char bits;
16417 present = snd_hda_jack_detect(codec, 0x1b);
16418 bits = present ? 0 : PIN_OUT;
16419 snd_hda_codec_write(codec, 0x14, 0,
16420 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16423 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16425 unsigned int present1, present2;
16427 present1 = snd_hda_jack_detect(codec, 0x21);
16428 present2 = snd_hda_jack_detect(codec, 0x15);
16430 if (present1 || present2) {
16431 snd_hda_codec_write_cache(codec, 0x14, 0,
16432 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16434 snd_hda_codec_write_cache(codec, 0x14, 0,
16435 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16439 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16441 unsigned int present1, present2;
16443 present1 = snd_hda_jack_detect(codec, 0x1b);
16444 present2 = snd_hda_jack_detect(codec, 0x15);
16446 if (present1 || present2) {
16447 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16448 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16449 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16450 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16452 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16453 AMP_IN_MUTE(0), 0);
16454 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16455 AMP_IN_MUTE(0), 0);
16459 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16462 switch (res >> 26) {
16463 case ALC880_HP_EVENT:
16464 alc663_m51va_speaker_automute(codec);
16466 case ALC880_MIC_EVENT:
16467 alc_mic_automute(codec);
16472 static void alc663_m51va_setup(struct hda_codec *codec)
16474 struct alc_spec *spec = codec->spec;
16475 spec->ext_mic.pin = 0x18;
16476 spec->ext_mic.mux_idx = 0;
16477 spec->int_mic.pin = 0x12;
16478 spec->int_mic.mux_idx = 1;
16479 spec->auto_mic = 1;
16482 static void alc663_m51va_inithook(struct hda_codec *codec)
16484 alc663_m51va_speaker_automute(codec);
16485 alc_mic_automute(codec);
16488 /* ***************** Mode1 ******************************/
16489 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
16490 #define alc663_mode1_setup alc663_m51va_setup
16491 #define alc663_mode1_inithook alc663_m51va_inithook
16493 /* ***************** Mode2 ******************************/
16494 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16497 switch (res >> 26) {
16498 case ALC880_HP_EVENT:
16499 alc662_f5z_speaker_automute(codec);
16501 case ALC880_MIC_EVENT:
16502 alc_mic_automute(codec);
16507 #define alc662_mode2_setup alc663_m51va_setup
16509 static void alc662_mode2_inithook(struct hda_codec *codec)
16511 alc662_f5z_speaker_automute(codec);
16512 alc_mic_automute(codec);
16514 /* ***************** Mode3 ******************************/
16515 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16518 switch (res >> 26) {
16519 case ALC880_HP_EVENT:
16520 alc663_two_hp_m1_speaker_automute(codec);
16522 case ALC880_MIC_EVENT:
16523 alc_mic_automute(codec);
16528 #define alc663_mode3_setup alc663_m51va_setup
16530 static void alc663_mode3_inithook(struct hda_codec *codec)
16532 alc663_two_hp_m1_speaker_automute(codec);
16533 alc_mic_automute(codec);
16535 /* ***************** Mode4 ******************************/
16536 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16539 switch (res >> 26) {
16540 case ALC880_HP_EVENT:
16541 alc663_21jd_two_speaker_automute(codec);
16543 case ALC880_MIC_EVENT:
16544 alc_mic_automute(codec);
16549 #define alc663_mode4_setup alc663_m51va_setup
16551 static void alc663_mode4_inithook(struct hda_codec *codec)
16553 alc663_21jd_two_speaker_automute(codec);
16554 alc_mic_automute(codec);
16556 /* ***************** Mode5 ******************************/
16557 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16560 switch (res >> 26) {
16561 case ALC880_HP_EVENT:
16562 alc663_15jd_two_speaker_automute(codec);
16564 case ALC880_MIC_EVENT:
16565 alc_mic_automute(codec);
16570 #define alc663_mode5_setup alc663_m51va_setup
16572 static void alc663_mode5_inithook(struct hda_codec *codec)
16574 alc663_15jd_two_speaker_automute(codec);
16575 alc_mic_automute(codec);
16577 /* ***************** Mode6 ******************************/
16578 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16581 switch (res >> 26) {
16582 case ALC880_HP_EVENT:
16583 alc663_two_hp_m2_speaker_automute(codec);
16585 case ALC880_MIC_EVENT:
16586 alc_mic_automute(codec);
16591 #define alc663_mode6_setup alc663_m51va_setup
16593 static void alc663_mode6_inithook(struct hda_codec *codec)
16595 alc663_two_hp_m2_speaker_automute(codec);
16596 alc_mic_automute(codec);
16599 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16601 unsigned int present;
16602 unsigned char bits;
16604 present = snd_hda_jack_detect(codec, 0x21);
16605 bits = present ? HDA_AMP_MUTE : 0;
16606 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16607 HDA_AMP_MUTE, bits);
16608 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16609 HDA_AMP_MUTE, bits);
16612 static void alc663_g71v_front_automute(struct hda_codec *codec)
16614 unsigned int present;
16615 unsigned char bits;
16617 present = snd_hda_jack_detect(codec, 0x15);
16618 bits = present ? HDA_AMP_MUTE : 0;
16619 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16620 HDA_AMP_MUTE, bits);
16623 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16626 switch (res >> 26) {
16627 case ALC880_HP_EVENT:
16628 alc663_g71v_hp_automute(codec);
16630 case ALC880_FRONT_EVENT:
16631 alc663_g71v_front_automute(codec);
16633 case ALC880_MIC_EVENT:
16634 alc_mic_automute(codec);
16639 #define alc663_g71v_setup alc663_m51va_setup
16641 static void alc663_g71v_inithook(struct hda_codec *codec)
16643 alc663_g71v_front_automute(codec);
16644 alc663_g71v_hp_automute(codec);
16645 alc_mic_automute(codec);
16648 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16651 switch (res >> 26) {
16652 case ALC880_HP_EVENT:
16653 alc663_m51va_speaker_automute(codec);
16655 case ALC880_MIC_EVENT:
16656 alc_mic_automute(codec);
16661 #define alc663_g50v_setup alc663_m51va_setup
16663 static void alc663_g50v_inithook(struct hda_codec *codec)
16665 alc663_m51va_speaker_automute(codec);
16666 alc_mic_automute(codec);
16669 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16670 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16671 ALC262_HIPPO_MASTER_SWITCH,
16673 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16674 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16675 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16677 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16678 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16679 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16683 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16684 /* Master Playback automatically created from Speaker and Headphone */
16685 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16686 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16687 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16690 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16691 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16692 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16694 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16695 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16700 #ifdef CONFIG_SND_HDA_POWER_SAVE
16701 #define alc662_loopbacks alc880_loopbacks
16705 /* pcm configuration: identical with ALC880 */
16706 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16707 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16708 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16709 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16712 * configuration and preset
16714 static const char *alc662_models[ALC662_MODEL_LAST] = {
16715 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16716 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16717 [ALC662_3ST_6ch] = "3stack-6ch",
16718 [ALC662_5ST_DIG] = "6stack-dig",
16719 [ALC662_LENOVO_101E] = "lenovo-101e",
16720 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16721 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16722 [ALC662_ECS] = "ecs",
16723 [ALC663_ASUS_M51VA] = "m51va",
16724 [ALC663_ASUS_G71V] = "g71v",
16725 [ALC663_ASUS_H13] = "h13",
16726 [ALC663_ASUS_G50V] = "g50v",
16727 [ALC663_ASUS_MODE1] = "asus-mode1",
16728 [ALC662_ASUS_MODE2] = "asus-mode2",
16729 [ALC663_ASUS_MODE3] = "asus-mode3",
16730 [ALC663_ASUS_MODE4] = "asus-mode4",
16731 [ALC663_ASUS_MODE5] = "asus-mode5",
16732 [ALC663_ASUS_MODE6] = "asus-mode6",
16733 [ALC272_DELL] = "dell",
16734 [ALC272_DELL_ZM1] = "dell-zm1",
16735 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16736 [ALC662_AUTO] = "auto",
16739 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16740 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16741 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16742 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16743 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16744 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16745 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16746 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16747 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16748 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16749 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16750 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16751 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16752 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16753 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16754 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16755 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16756 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16757 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16758 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16759 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16760 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16761 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16762 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16763 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16764 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16765 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16766 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16767 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16768 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16769 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16770 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16771 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16772 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16773 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16774 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16775 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16776 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16777 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16778 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16779 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16780 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16781 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16782 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16783 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16784 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16785 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16786 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16787 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16788 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16789 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16790 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16791 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16792 ALC662_3ST_6ch_DIG),
16793 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
16794 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16795 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16796 ALC662_3ST_6ch_DIG),
16797 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16798 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16799 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16800 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16801 ALC662_3ST_6ch_DIG),
16802 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16807 static struct alc_config_preset alc662_presets[] = {
16808 [ALC662_3ST_2ch_DIG] = {
16809 .mixers = { alc662_3ST_2ch_mixer },
16810 .init_verbs = { alc662_init_verbs },
16811 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16812 .dac_nids = alc662_dac_nids,
16813 .dig_out_nid = ALC662_DIGOUT_NID,
16814 .dig_in_nid = ALC662_DIGIN_NID,
16815 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16816 .channel_mode = alc662_3ST_2ch_modes,
16817 .input_mux = &alc662_capture_source,
16819 [ALC662_3ST_6ch_DIG] = {
16820 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16821 .init_verbs = { alc662_init_verbs },
16822 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16823 .dac_nids = alc662_dac_nids,
16824 .dig_out_nid = ALC662_DIGOUT_NID,
16825 .dig_in_nid = ALC662_DIGIN_NID,
16826 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16827 .channel_mode = alc662_3ST_6ch_modes,
16829 .input_mux = &alc662_capture_source,
16831 [ALC662_3ST_6ch] = {
16832 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16833 .init_verbs = { alc662_init_verbs },
16834 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16835 .dac_nids = alc662_dac_nids,
16836 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16837 .channel_mode = alc662_3ST_6ch_modes,
16839 .input_mux = &alc662_capture_source,
16841 [ALC662_5ST_DIG] = {
16842 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16843 .init_verbs = { alc662_init_verbs },
16844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16845 .dac_nids = alc662_dac_nids,
16846 .dig_out_nid = ALC662_DIGOUT_NID,
16847 .dig_in_nid = ALC662_DIGIN_NID,
16848 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16849 .channel_mode = alc662_5stack_modes,
16850 .input_mux = &alc662_capture_source,
16852 [ALC662_LENOVO_101E] = {
16853 .mixers = { alc662_lenovo_101e_mixer },
16854 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16855 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16856 .dac_nids = alc662_dac_nids,
16857 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16858 .channel_mode = alc662_3ST_2ch_modes,
16859 .input_mux = &alc662_lenovo_101e_capture_source,
16860 .unsol_event = alc662_lenovo_101e_unsol_event,
16861 .init_hook = alc662_lenovo_101e_all_automute,
16863 [ALC662_ASUS_EEEPC_P701] = {
16864 .mixers = { alc662_eeepc_p701_mixer },
16865 .init_verbs = { alc662_init_verbs,
16866 alc662_eeepc_sue_init_verbs },
16867 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16868 .dac_nids = alc662_dac_nids,
16869 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16870 .channel_mode = alc662_3ST_2ch_modes,
16871 .unsol_event = alc662_eeepc_unsol_event,
16872 .setup = alc662_eeepc_setup,
16873 .init_hook = alc662_eeepc_inithook,
16875 [ALC662_ASUS_EEEPC_EP20] = {
16876 .mixers = { alc662_eeepc_ep20_mixer,
16877 alc662_chmode_mixer },
16878 .init_verbs = { alc662_init_verbs,
16879 alc662_eeepc_ep20_sue_init_verbs },
16880 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16881 .dac_nids = alc662_dac_nids,
16882 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16883 .channel_mode = alc662_3ST_6ch_modes,
16884 .input_mux = &alc662_lenovo_101e_capture_source,
16885 .unsol_event = alc662_eeepc_unsol_event,
16886 .setup = alc662_eeepc_ep20_setup,
16887 .init_hook = alc662_eeepc_ep20_inithook,
16890 .mixers = { alc662_ecs_mixer },
16891 .init_verbs = { alc662_init_verbs,
16892 alc662_ecs_init_verbs },
16893 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16894 .dac_nids = alc662_dac_nids,
16895 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16896 .channel_mode = alc662_3ST_2ch_modes,
16897 .unsol_event = alc662_eeepc_unsol_event,
16898 .setup = alc662_eeepc_setup,
16899 .init_hook = alc662_eeepc_inithook,
16901 [ALC663_ASUS_M51VA] = {
16902 .mixers = { alc663_m51va_mixer },
16903 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16905 .dac_nids = alc662_dac_nids,
16906 .dig_out_nid = ALC662_DIGOUT_NID,
16907 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16908 .channel_mode = alc662_3ST_2ch_modes,
16909 .unsol_event = alc663_m51va_unsol_event,
16910 .setup = alc663_m51va_setup,
16911 .init_hook = alc663_m51va_inithook,
16913 [ALC663_ASUS_G71V] = {
16914 .mixers = { alc663_g71v_mixer },
16915 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16916 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16917 .dac_nids = alc662_dac_nids,
16918 .dig_out_nid = ALC662_DIGOUT_NID,
16919 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16920 .channel_mode = alc662_3ST_2ch_modes,
16921 .unsol_event = alc663_g71v_unsol_event,
16922 .setup = alc663_g71v_setup,
16923 .init_hook = alc663_g71v_inithook,
16925 [ALC663_ASUS_H13] = {
16926 .mixers = { alc663_m51va_mixer },
16927 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16928 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16929 .dac_nids = alc662_dac_nids,
16930 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16931 .channel_mode = alc662_3ST_2ch_modes,
16932 .unsol_event = alc663_m51va_unsol_event,
16933 .init_hook = alc663_m51va_inithook,
16935 [ALC663_ASUS_G50V] = {
16936 .mixers = { alc663_g50v_mixer },
16937 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16938 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16939 .dac_nids = alc662_dac_nids,
16940 .dig_out_nid = ALC662_DIGOUT_NID,
16941 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16942 .channel_mode = alc662_3ST_6ch_modes,
16943 .input_mux = &alc663_capture_source,
16944 .unsol_event = alc663_g50v_unsol_event,
16945 .setup = alc663_g50v_setup,
16946 .init_hook = alc663_g50v_inithook,
16948 [ALC663_ASUS_MODE1] = {
16949 .mixers = { alc663_m51va_mixer },
16950 .cap_mixer = alc662_auto_capture_mixer,
16951 .init_verbs = { alc662_init_verbs,
16952 alc663_21jd_amic_init_verbs },
16953 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16955 .dac_nids = alc662_dac_nids,
16956 .dig_out_nid = ALC662_DIGOUT_NID,
16957 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16958 .channel_mode = alc662_3ST_2ch_modes,
16959 .unsol_event = alc663_mode1_unsol_event,
16960 .setup = alc663_mode1_setup,
16961 .init_hook = alc663_mode1_inithook,
16963 [ALC662_ASUS_MODE2] = {
16964 .mixers = { alc662_1bjd_mixer },
16965 .cap_mixer = alc662_auto_capture_mixer,
16966 .init_verbs = { alc662_init_verbs,
16967 alc662_1bjd_amic_init_verbs },
16968 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16969 .dac_nids = alc662_dac_nids,
16970 .dig_out_nid = ALC662_DIGOUT_NID,
16971 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16972 .channel_mode = alc662_3ST_2ch_modes,
16973 .unsol_event = alc662_mode2_unsol_event,
16974 .setup = alc662_mode2_setup,
16975 .init_hook = alc662_mode2_inithook,
16977 [ALC663_ASUS_MODE3] = {
16978 .mixers = { alc663_two_hp_m1_mixer },
16979 .cap_mixer = alc662_auto_capture_mixer,
16980 .init_verbs = { alc662_init_verbs,
16981 alc663_two_hp_amic_m1_init_verbs },
16982 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16984 .dac_nids = alc662_dac_nids,
16985 .dig_out_nid = ALC662_DIGOUT_NID,
16986 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16987 .channel_mode = alc662_3ST_2ch_modes,
16988 .unsol_event = alc663_mode3_unsol_event,
16989 .setup = alc663_mode3_setup,
16990 .init_hook = alc663_mode3_inithook,
16992 [ALC663_ASUS_MODE4] = {
16993 .mixers = { alc663_asus_21jd_clfe_mixer },
16994 .cap_mixer = alc662_auto_capture_mixer,
16995 .init_verbs = { alc662_init_verbs,
16996 alc663_21jd_amic_init_verbs},
16997 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16999 .dac_nids = alc662_dac_nids,
17000 .dig_out_nid = ALC662_DIGOUT_NID,
17001 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17002 .channel_mode = alc662_3ST_2ch_modes,
17003 .unsol_event = alc663_mode4_unsol_event,
17004 .setup = alc663_mode4_setup,
17005 .init_hook = alc663_mode4_inithook,
17007 [ALC663_ASUS_MODE5] = {
17008 .mixers = { alc663_asus_15jd_clfe_mixer },
17009 .cap_mixer = alc662_auto_capture_mixer,
17010 .init_verbs = { alc662_init_verbs,
17011 alc663_15jd_amic_init_verbs },
17012 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17014 .dac_nids = alc662_dac_nids,
17015 .dig_out_nid = ALC662_DIGOUT_NID,
17016 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17017 .channel_mode = alc662_3ST_2ch_modes,
17018 .unsol_event = alc663_mode5_unsol_event,
17019 .setup = alc663_mode5_setup,
17020 .init_hook = alc663_mode5_inithook,
17022 [ALC663_ASUS_MODE6] = {
17023 .mixers = { alc663_two_hp_m2_mixer },
17024 .cap_mixer = alc662_auto_capture_mixer,
17025 .init_verbs = { alc662_init_verbs,
17026 alc663_two_hp_amic_m2_init_verbs },
17027 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17029 .dac_nids = alc662_dac_nids,
17030 .dig_out_nid = ALC662_DIGOUT_NID,
17031 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17032 .channel_mode = alc662_3ST_2ch_modes,
17033 .unsol_event = alc663_mode6_unsol_event,
17034 .setup = alc663_mode6_setup,
17035 .init_hook = alc663_mode6_inithook,
17038 .mixers = { alc663_m51va_mixer },
17039 .cap_mixer = alc272_auto_capture_mixer,
17040 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17041 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17042 .dac_nids = alc662_dac_nids,
17043 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17044 .adc_nids = alc272_adc_nids,
17045 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17046 .capsrc_nids = alc272_capsrc_nids,
17047 .channel_mode = alc662_3ST_2ch_modes,
17048 .unsol_event = alc663_m51va_unsol_event,
17049 .setup = alc663_m51va_setup,
17050 .init_hook = alc663_m51va_inithook,
17052 [ALC272_DELL_ZM1] = {
17053 .mixers = { alc663_m51va_mixer },
17054 .cap_mixer = alc662_auto_capture_mixer,
17055 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17056 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17057 .dac_nids = alc662_dac_nids,
17058 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17059 .adc_nids = alc662_adc_nids,
17061 .capsrc_nids = alc662_capsrc_nids,
17062 .channel_mode = alc662_3ST_2ch_modes,
17063 .unsol_event = alc663_m51va_unsol_event,
17064 .setup = alc663_m51va_setup,
17065 .init_hook = alc663_m51va_inithook,
17067 [ALC272_SAMSUNG_NC10] = {
17068 .mixers = { alc272_nc10_mixer },
17069 .init_verbs = { alc662_init_verbs,
17070 alc663_21jd_amic_init_verbs },
17071 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17072 .dac_nids = alc272_dac_nids,
17073 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17074 .channel_mode = alc662_3ST_2ch_modes,
17075 /*.input_mux = &alc272_nc10_capture_source,*/
17076 .unsol_event = alc663_mode4_unsol_event,
17077 .setup = alc663_mode4_setup,
17078 .init_hook = alc663_mode4_inithook,
17084 * BIOS auto configuration
17087 /* convert from MIX nid to DAC */
17088 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17092 else if (nid >= 0x0c && nid <= 0x0e)
17093 return nid - 0x0c + 0x02;
17098 /* get MIX nid connected to the given pin targeted to DAC */
17099 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17105 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17106 for (i = 0; i < num; i++) {
17107 if (alc662_mix_to_dac(mix[i]) == dac)
17113 /* look for an empty DAC slot */
17114 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17116 struct alc_spec *spec = codec->spec;
17120 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17123 for (i = 0; i < num; i++) {
17124 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17127 for (j = 0; j < spec->multiout.num_dacs; j++)
17128 if (spec->multiout.dac_nids[j] == nid)
17130 if (j >= spec->multiout.num_dacs)
17136 /* fill in the dac_nids table from the parsed pin configuration */
17137 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17138 const struct auto_pin_cfg *cfg)
17140 struct alc_spec *spec = codec->spec;
17144 spec->multiout.dac_nids = spec->private_dac_nids;
17145 for (i = 0; i < cfg->line_outs; i++) {
17146 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17149 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17154 static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17155 hda_nid_t nid, unsigned int chs)
17157 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17158 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17161 static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17162 hda_nid_t nid, unsigned int chs)
17164 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17165 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17168 #define alc662_add_stereo_vol(spec, pfx, nid) \
17169 alc662_add_vol_ctl(spec, pfx, nid, 3)
17170 #define alc662_add_stereo_sw(spec, pfx, nid) \
17171 alc662_add_sw_ctl(spec, pfx, nid, 3)
17173 /* add playback controls from the parsed DAC table */
17174 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17175 const struct auto_pin_cfg *cfg)
17177 struct alc_spec *spec = codec->spec;
17178 static const char *chname[4] = {
17179 "Front", "Surround", NULL /*CLFE*/, "Side"
17181 hda_nid_t nid, mix;
17184 for (i = 0; i < cfg->line_outs; i++) {
17185 nid = spec->multiout.dac_nids[i];
17188 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17193 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17196 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17199 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17202 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17207 if (cfg->line_outs == 1 &&
17208 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17215 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17218 if (cfg->line_outs == 1 &&
17219 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17221 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17229 /* add playback controls for speaker and HP outputs */
17230 /* return DAC nid if any new DAC is assigned */
17231 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17234 struct alc_spec *spec = codec->spec;
17235 hda_nid_t nid, mix;
17240 nid = alc662_look_for_dac(codec, pin);
17242 /* the corresponding DAC is already occupied */
17243 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17244 return 0; /* no way */
17245 /* create a switch only */
17246 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17247 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17250 mix = alc662_dac_to_mix(codec, pin, nid);
17253 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17256 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17262 /* create playback/capture controls for input pins */
17263 #define alc662_auto_create_input_ctls \
17264 alc882_auto_create_input_ctls
17266 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17267 hda_nid_t nid, int pin_type,
17273 alc_set_pin_output(codec, nid, pin_type);
17274 /* need the manual connection? */
17275 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17278 for (i = 0; i < num; i++) {
17279 if (alc662_mix_to_dac(srcs[i]) != dac)
17281 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17286 static void alc662_auto_init_multi_out(struct hda_codec *codec)
17288 struct alc_spec *spec = codec->spec;
17289 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17292 for (i = 0; i <= HDA_SIDE; i++) {
17293 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17295 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17296 spec->multiout.dac_nids[i]);
17300 static void alc662_auto_init_hp_out(struct hda_codec *codec)
17302 struct alc_spec *spec = codec->spec;
17305 pin = spec->autocfg.hp_pins[0];
17307 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17308 spec->multiout.hp_nid);
17309 pin = spec->autocfg.speaker_pins[0];
17311 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17312 spec->multiout.extra_out_nid[0]);
17315 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17317 static void alc662_auto_init_analog_input(struct hda_codec *codec)
17319 struct alc_spec *spec = codec->spec;
17322 for (i = 0; i < AUTO_PIN_LAST; i++) {
17323 hda_nid_t nid = spec->autocfg.input_pins[i];
17324 if (alc_is_input_pin(codec, nid)) {
17325 alc_set_input_pin(codec, nid, i);
17326 if (nid != ALC662_PIN_CD_NID &&
17327 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17328 snd_hda_codec_write(codec, nid, 0,
17329 AC_VERB_SET_AMP_GAIN_MUTE,
17335 #define alc662_auto_init_input_src alc882_auto_init_input_src
17337 static int alc662_parse_auto_config(struct hda_codec *codec)
17339 struct alc_spec *spec = codec->spec;
17341 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17343 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17347 if (!spec->autocfg.line_outs)
17348 return 0; /* can't find valid BIOS pin config */
17350 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17353 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17356 err = alc662_auto_create_extra_out(codec,
17357 spec->autocfg.speaker_pins[0],
17362 spec->multiout.extra_out_nid[0] = err;
17363 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17368 spec->multiout.hp_nid = err;
17369 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17373 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17375 if (spec->autocfg.dig_outs)
17376 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17378 if (spec->kctls.list)
17379 add_mixer(spec, spec->kctls.list);
17381 spec->num_mux_defs = 1;
17382 spec->input_mux = &spec->private_imux[0];
17384 add_verb(spec, alc662_auto_init_verbs);
17385 if (codec->vendor_id == 0x10ec0663)
17386 add_verb(spec, alc663_auto_init_verbs);
17388 err = alc_auto_add_mic_boost(codec);
17392 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17397 /* additional initialization for auto-configuration model */
17398 static void alc662_auto_init(struct hda_codec *codec)
17400 struct alc_spec *spec = codec->spec;
17401 alc662_auto_init_multi_out(codec);
17402 alc662_auto_init_hp_out(codec);
17403 alc662_auto_init_analog_input(codec);
17404 alc662_auto_init_input_src(codec);
17405 if (spec->unsol_event)
17406 alc_inithook(codec);
17409 static int patch_alc662(struct hda_codec *codec)
17411 struct alc_spec *spec;
17412 int err, board_config;
17414 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17418 codec->spec = spec;
17420 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17422 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17425 if (board_config < 0) {
17426 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17428 board_config = ALC662_AUTO;
17431 if (board_config == ALC662_AUTO) {
17432 /* automatic parse from the BIOS config */
17433 err = alc662_parse_auto_config(codec);
17439 "hda_codec: Cannot set up configuration "
17440 "from BIOS. Using base mode...\n");
17441 board_config = ALC662_3ST_2ch_DIG;
17445 err = snd_hda_attach_beep_device(codec, 0x1);
17451 if (board_config != ALC662_AUTO)
17452 setup_preset(codec, &alc662_presets[board_config]);
17454 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17455 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17457 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17458 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17460 if (!spec->adc_nids) {
17461 spec->adc_nids = alc662_adc_nids;
17462 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17464 if (!spec->capsrc_nids)
17465 spec->capsrc_nids = alc662_capsrc_nids;
17467 if (!spec->cap_mixer)
17468 set_capture_mixer(codec);
17469 if (codec->vendor_id == 0x10ec0662)
17470 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17472 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17474 spec->vmaster_nid = 0x02;
17476 codec->patch_ops = alc_patch_ops;
17477 if (board_config == ALC662_AUTO)
17478 spec->init_hook = alc662_auto_init;
17479 #ifdef CONFIG_SND_HDA_POWER_SAVE
17480 if (!spec->loopback.amplist)
17481 spec->loopback.amplist = alc662_loopbacks;
17483 codec->proc_widget_hook = print_realtek_coef;
17491 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17492 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17493 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17494 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17495 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17496 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17497 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17498 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17499 .patch = patch_alc861 },
17500 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17501 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17502 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17503 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17504 .patch = patch_alc882 },
17505 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17506 .patch = patch_alc662 },
17507 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17508 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17509 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17510 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17511 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17512 .patch = patch_alc882 },
17513 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17514 .patch = patch_alc882 },
17515 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17516 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17517 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17518 .patch = patch_alc882 },
17519 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17520 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17521 {} /* terminator */
17524 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17526 MODULE_LICENSE("GPL");
17527 MODULE_DESCRIPTION("Realtek HD-audio codec");
17529 static struct hda_codec_preset_list realtek_list = {
17530 .preset = snd_hda_preset_realtek,
17531 .owner = THIS_MODULE,
17534 static int __init patch_realtek_init(void)
17536 return snd_hda_add_codec_preset(&realtek_list);
17539 static void __exit patch_realtek_exit(void)
17541 snd_hda_delete_codec_preset(&realtek_list);
17544 module_init(patch_realtek_init)
17545 module_exit(patch_realtek_exit)