2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
222 ALC883_TARGA_2ch_DIG,
225 ALC888_ACER_ASPIRE_4930G,
229 ALC883_LENOVO_101E_2ch,
230 ALC883_LENOVO_NB0763,
231 ALC888_LENOVO_MS7195_DIG,
238 ALC883_FUJITSU_PI2515,
239 ALC888_FUJITSU_XA3530,
240 ALC883_3ST_6ch_INTEL,
248 /* styles of capture selection */
250 CAPT_MUX = 0, /* only mux based */
251 CAPT_MIX, /* only mixer based */
252 CAPT_1MUX_MIX, /* first mux and other mixers */
256 #define GPIO_MASK 0x03
258 /* extra amp-initialization sequence types */
268 /* codec parameterization */
269 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
270 unsigned int num_mixers;
271 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
272 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
274 const struct hda_verb *init_verbs[5]; /* initialization verbs
278 unsigned int num_init_verbs;
280 char *stream_name_analog; /* analog PCM stream */
281 struct hda_pcm_stream *stream_analog_playback;
282 struct hda_pcm_stream *stream_analog_capture;
283 struct hda_pcm_stream *stream_analog_alt_playback;
284 struct hda_pcm_stream *stream_analog_alt_capture;
286 char *stream_name_digital; /* digital PCM stream */
287 struct hda_pcm_stream *stream_digital_playback;
288 struct hda_pcm_stream *stream_digital_capture;
291 struct hda_multi_out multiout; /* playback set-up
292 * max_channels, dacs must be set
293 * dig_out_nid and hp_nid are optional
295 hda_nid_t alt_dac_nid;
296 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
300 unsigned int num_adc_nids;
302 hda_nid_t *capsrc_nids;
303 hda_nid_t dig_in_nid; /* digital-in NID; optional */
304 int capture_style; /* capture style (CAPT_*) */
307 unsigned int num_mux_defs;
308 const struct hda_input_mux *input_mux;
309 unsigned int cur_mux[3];
312 const struct hda_channel_mode *channel_mode;
313 int num_channel_mode;
316 /* PCM information */
317 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
319 /* dynamic controls, init_verbs and input_mux */
320 struct auto_pin_cfg autocfg;
321 struct snd_array kctls;
322 struct hda_input_mux private_imux[3];
323 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
326 void (*init_hook)(struct hda_codec *codec);
327 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
329 /* for pin sensing */
330 unsigned int sense_updated: 1;
331 unsigned int jack_present: 1;
332 unsigned int master_sw: 1;
335 unsigned int no_analog :1; /* digital I/O only */
338 /* for virtual master */
339 hda_nid_t vmaster_nid;
340 #ifdef CONFIG_SND_HDA_POWER_SAVE
341 struct hda_loopback_check loopback;
346 unsigned int pll_coef_idx, pll_coef_bit;
350 * configuration template - to be copied to the spec instance
352 struct alc_config_preset {
353 struct snd_kcontrol_new *mixers[5]; /* should be identical size
356 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
357 const struct hda_verb *init_verbs[5];
358 unsigned int num_dacs;
360 hda_nid_t dig_out_nid; /* optional */
361 hda_nid_t hp_nid; /* optional */
362 hda_nid_t *slave_dig_outs;
363 unsigned int num_adc_nids;
365 hda_nid_t *capsrc_nids;
366 hda_nid_t dig_in_nid;
367 unsigned int num_channel_mode;
368 const struct hda_channel_mode *channel_mode;
370 unsigned int num_mux_defs;
371 const struct hda_input_mux *input_mux;
372 void (*unsol_event)(struct hda_codec *, unsigned int);
373 void (*init_hook)(struct hda_codec *);
374 #ifdef CONFIG_SND_HDA_POWER_SAVE
375 struct hda_amp_list *loopbacks;
383 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_info *uinfo)
386 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
387 struct alc_spec *spec = codec->spec;
388 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
389 if (mux_idx >= spec->num_mux_defs)
391 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
394 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
398 struct alc_spec *spec = codec->spec;
399 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
401 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
405 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
406 struct snd_ctl_elem_value *ucontrol)
408 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
409 struct alc_spec *spec = codec->spec;
410 const struct hda_input_mux *imux;
411 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
412 unsigned int mux_idx;
413 hda_nid_t nid = spec->capsrc_nids ?
414 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
416 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
417 imux = &spec->input_mux[mux_idx];
419 if (spec->capture_style &&
420 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
421 /* Matrix-mixer style (e.g. ALC882) */
422 unsigned int *cur_val = &spec->cur_mux[adc_idx];
425 idx = ucontrol->value.enumerated.item[0];
426 if (idx >= imux->num_items)
427 idx = imux->num_items - 1;
430 for (i = 0; i < imux->num_items; i++) {
431 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
432 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
433 imux->items[i].index,
439 /* MUX style (e.g. ALC880) */
440 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
441 &spec->cur_mux[adc_idx]);
446 * channel mode setting
448 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
449 struct snd_ctl_elem_info *uinfo)
451 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
452 struct alc_spec *spec = codec->spec;
453 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
454 spec->num_channel_mode);
457 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
458 struct snd_ctl_elem_value *ucontrol)
460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
461 struct alc_spec *spec = codec->spec;
462 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
463 spec->num_channel_mode,
464 spec->multiout.max_channels);
467 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
470 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
471 struct alc_spec *spec = codec->spec;
472 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
473 spec->num_channel_mode,
474 &spec->multiout.max_channels);
475 if (err >= 0 && spec->need_dac_fix)
476 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
481 * Control the mode of pin widget settings via the mixer. "pc" is used
482 * instead of "%" to avoid consequences of accidently treating the % as
483 * being part of a format specifier. Maximum allowed length of a value is
484 * 63 characters plus NULL terminator.
486 * Note: some retasking pin complexes seem to ignore requests for input
487 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
488 * are requested. Therefore order this list so that this behaviour will not
489 * cause problems when mixer clients move through the enum sequentially.
490 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
493 static char *alc_pin_mode_names[] = {
494 "Mic 50pc bias", "Mic 80pc bias",
495 "Line in", "Line out", "Headphone out",
497 static unsigned char alc_pin_mode_values[] = {
498 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
500 /* The control can present all 5 options, or it can limit the options based
501 * in the pin being assumed to be exclusively an input or an output pin. In
502 * addition, "input" pins may or may not process the mic bias option
503 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
504 * accept requests for bias as of chip versions up to March 2006) and/or
505 * wiring in the computer.
507 #define ALC_PIN_DIR_IN 0x00
508 #define ALC_PIN_DIR_OUT 0x01
509 #define ALC_PIN_DIR_INOUT 0x02
510 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
511 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
513 /* Info about the pin modes supported by the different pin direction modes.
514 * For each direction the minimum and maximum values are given.
516 static signed char alc_pin_mode_dir_info[5][2] = {
517 { 0, 2 }, /* ALC_PIN_DIR_IN */
518 { 3, 4 }, /* ALC_PIN_DIR_OUT */
519 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
520 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
521 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
523 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
524 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
525 #define alc_pin_mode_n_items(_dir) \
526 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
528 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_info *uinfo)
531 unsigned int item_num = uinfo->value.enumerated.item;
532 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
534 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
536 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
538 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
539 item_num = alc_pin_mode_min(dir);
540 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
544 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
549 hda_nid_t nid = kcontrol->private_value & 0xffff;
550 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
551 long *valp = ucontrol->value.integer.value;
552 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
553 AC_VERB_GET_PIN_WIDGET_CONTROL,
556 /* Find enumerated value for current pinctl setting */
557 i = alc_pin_mode_min(dir);
558 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
560 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
564 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
569 hda_nid_t nid = kcontrol->private_value & 0xffff;
570 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
571 long val = *ucontrol->value.integer.value;
572 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
573 AC_VERB_GET_PIN_WIDGET_CONTROL,
576 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
577 val = alc_pin_mode_min(dir);
579 change = pinctl != alc_pin_mode_values[val];
581 /* Set pin mode to that requested */
582 snd_hda_codec_write_cache(codec, nid, 0,
583 AC_VERB_SET_PIN_WIDGET_CONTROL,
584 alc_pin_mode_values[val]);
586 /* Also enable the retasking pin's input/output as required
587 * for the requested pin mode. Enum values of 2 or less are
590 * Dynamically switching the input/output buffers probably
591 * reduces noise slightly (particularly on input) so we'll
592 * do it. However, having both input and output buffers
593 * enabled simultaneously doesn't seem to be problematic if
594 * this turns out to be necessary in the future.
597 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
598 HDA_AMP_MUTE, HDA_AMP_MUTE);
599 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
602 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
603 HDA_AMP_MUTE, HDA_AMP_MUTE);
604 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
611 #define ALC_PIN_MODE(xname, nid, dir) \
612 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
613 .info = alc_pin_mode_info, \
614 .get = alc_pin_mode_get, \
615 .put = alc_pin_mode_put, \
616 .private_value = nid | (dir<<16) }
618 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
619 * together using a mask with more than one bit set. This control is
620 * currently used only by the ALC260 test model. At this stage they are not
621 * needed for any "production" models.
623 #ifdef CONFIG_SND_DEBUG
624 #define alc_gpio_data_info snd_ctl_boolean_mono_info
626 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_value *ucontrol)
629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
630 hda_nid_t nid = kcontrol->private_value & 0xffff;
631 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
632 long *valp = ucontrol->value.integer.value;
633 unsigned int val = snd_hda_codec_read(codec, nid, 0,
634 AC_VERB_GET_GPIO_DATA, 0x00);
636 *valp = (val & mask) != 0;
639 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644 hda_nid_t nid = kcontrol->private_value & 0xffff;
645 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
646 long val = *ucontrol->value.integer.value;
647 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
648 AC_VERB_GET_GPIO_DATA,
651 /* Set/unset the masked GPIO bit(s) as needed */
652 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
657 snd_hda_codec_write_cache(codec, nid, 0,
658 AC_VERB_SET_GPIO_DATA, gpio_data);
662 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
663 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
664 .info = alc_gpio_data_info, \
665 .get = alc_gpio_data_get, \
666 .put = alc_gpio_data_put, \
667 .private_value = nid | (mask<<16) }
668 #endif /* CONFIG_SND_DEBUG */
670 /* A switch control to allow the enabling of the digital IO pins on the
671 * ALC260. This is incredibly simplistic; the intention of this control is
672 * to provide something in the test model allowing digital outputs to be
673 * identified if present. If models are found which can utilise these
674 * outputs a more complete mixer control can be devised for those models if
677 #ifdef CONFIG_SND_DEBUG
678 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
680 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684 hda_nid_t nid = kcontrol->private_value & 0xffff;
685 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686 long *valp = ucontrol->value.integer.value;
687 unsigned int val = snd_hda_codec_read(codec, nid, 0,
688 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
690 *valp = (val & mask) != 0;
693 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
694 struct snd_ctl_elem_value *ucontrol)
697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
698 hda_nid_t nid = kcontrol->private_value & 0xffff;
699 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
700 long val = *ucontrol->value.integer.value;
701 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
702 AC_VERB_GET_DIGI_CONVERT_1,
705 /* Set/unset the masked control bit(s) as needed */
706 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
711 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
716 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
717 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
718 .info = alc_spdif_ctrl_info, \
719 .get = alc_spdif_ctrl_get, \
720 .put = alc_spdif_ctrl_put, \
721 .private_value = nid | (mask<<16) }
722 #endif /* CONFIG_SND_DEBUG */
724 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
725 * Again, this is only used in the ALC26x test models to help identify when
726 * the EAPD line must be asserted for features to work.
728 #ifdef CONFIG_SND_DEBUG
729 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
731 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
732 struct snd_ctl_elem_value *ucontrol)
734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
735 hda_nid_t nid = kcontrol->private_value & 0xffff;
736 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
737 long *valp = ucontrol->value.integer.value;
738 unsigned int val = snd_hda_codec_read(codec, nid, 0,
739 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
741 *valp = (val & mask) != 0;
745 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
746 struct snd_ctl_elem_value *ucontrol)
749 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
750 hda_nid_t nid = kcontrol->private_value & 0xffff;
751 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
752 long val = *ucontrol->value.integer.value;
753 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
754 AC_VERB_GET_EAPD_BTLENABLE,
757 /* Set/unset the masked control bit(s) as needed */
758 change = (!val ? 0 : mask) != (ctrl_data & mask);
763 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
769 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
770 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
771 .info = alc_eapd_ctrl_info, \
772 .get = alc_eapd_ctrl_get, \
773 .put = alc_eapd_ctrl_put, \
774 .private_value = nid | (mask<<16) }
775 #endif /* CONFIG_SND_DEBUG */
778 * set up the input pin config (depending on the given auto-pin type)
780 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
783 unsigned int val = PIN_IN;
785 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
787 pincap = snd_hda_query_pin_caps(codec, nid);
788 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
789 if (pincap & AC_PINCAP_VREF_80)
792 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
797 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
799 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
801 spec->mixers[spec->num_mixers++] = mix;
804 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
806 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
808 spec->init_verbs[spec->num_init_verbs++] = verb;
811 #ifdef CONFIG_PROC_FS
815 static void print_realtek_coef(struct snd_info_buffer *buffer,
816 struct hda_codec *codec, hda_nid_t nid)
822 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
823 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
824 coeff = snd_hda_codec_read(codec, nid, 0,
825 AC_VERB_GET_COEF_INDEX, 0);
826 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
829 #define print_realtek_coef NULL
833 * set up from the preset table
835 static void setup_preset(struct alc_spec *spec,
836 const struct alc_config_preset *preset)
840 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
841 add_mixer(spec, preset->mixers[i]);
842 spec->cap_mixer = preset->cap_mixer;
843 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
845 add_verb(spec, preset->init_verbs[i]);
847 spec->channel_mode = preset->channel_mode;
848 spec->num_channel_mode = preset->num_channel_mode;
849 spec->need_dac_fix = preset->need_dac_fix;
851 spec->multiout.max_channels = spec->channel_mode[0].channels;
853 spec->multiout.num_dacs = preset->num_dacs;
854 spec->multiout.dac_nids = preset->dac_nids;
855 spec->multiout.dig_out_nid = preset->dig_out_nid;
856 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
857 spec->multiout.hp_nid = preset->hp_nid;
859 spec->num_mux_defs = preset->num_mux_defs;
860 if (!spec->num_mux_defs)
861 spec->num_mux_defs = 1;
862 spec->input_mux = preset->input_mux;
864 spec->num_adc_nids = preset->num_adc_nids;
865 spec->adc_nids = preset->adc_nids;
866 spec->capsrc_nids = preset->capsrc_nids;
867 spec->dig_in_nid = preset->dig_in_nid;
869 spec->unsol_event = preset->unsol_event;
870 spec->init_hook = preset->init_hook;
871 #ifdef CONFIG_SND_HDA_POWER_SAVE
872 spec->loopback.amplist = preset->loopbacks;
876 /* Enable GPIO mask and set output */
877 static struct hda_verb alc_gpio1_init_verbs[] = {
878 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
879 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
880 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
884 static struct hda_verb alc_gpio2_init_verbs[] = {
885 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
887 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
891 static struct hda_verb alc_gpio3_init_verbs[] = {
892 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
893 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
894 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
899 * Fix hardware PLL issue
900 * On some codecs, the analog PLL gating control must be off while
901 * the default value is 1.
903 static void alc_fix_pll(struct hda_codec *codec)
905 struct alc_spec *spec = codec->spec;
910 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
912 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
913 AC_VERB_GET_PROC_COEF, 0);
914 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
916 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
917 val & ~(1 << spec->pll_coef_bit));
920 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
921 unsigned int coef_idx, unsigned int coef_bit)
923 struct alc_spec *spec = codec->spec;
925 spec->pll_coef_idx = coef_idx;
926 spec->pll_coef_bit = coef_bit;
930 static void alc_automute_pin(struct hda_codec *codec)
932 struct alc_spec *spec = codec->spec;
933 unsigned int present;
934 unsigned int nid = spec->autocfg.hp_pins[0];
937 /* need to execute and sync at first */
938 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
939 present = snd_hda_codec_read(codec, nid, 0,
940 AC_VERB_GET_PIN_SENSE, 0);
941 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
942 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
943 nid = spec->autocfg.speaker_pins[i];
946 snd_hda_codec_write(codec, nid, 0,
947 AC_VERB_SET_PIN_WIDGET_CONTROL,
948 spec->jack_present ? 0 : PIN_OUT);
952 #if 0 /* it's broken in some acses -- temporarily disabled */
953 static void alc_mic_automute(struct hda_codec *codec)
955 struct alc_spec *spec = codec->spec;
956 unsigned int present;
957 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
958 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
959 unsigned int mix_nid = spec->capsrc_nids[0];
960 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
962 capsrc_idx_mic = mic_nid - 0x18;
963 capsrc_idx_fmic = fmic_nid - 0x18;
964 present = snd_hda_codec_read(codec, mic_nid, 0,
965 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
966 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
967 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
968 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
969 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
970 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
971 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
974 #define alc_mic_automute(codec) do {} while(0) /* NOP */
975 #endif /* disabled */
977 /* unsolicited event for HP jack sensing */
978 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
980 if (codec->vendor_id == 0x10ec0880)
985 case ALC880_HP_EVENT:
986 alc_automute_pin(codec);
988 case ALC880_MIC_EVENT:
989 alc_mic_automute(codec);
994 static void alc_inithook(struct hda_codec *codec)
996 alc_automute_pin(codec);
997 alc_mic_automute(codec);
1000 /* additional initialization for ALC888 variants */
1001 static void alc888_coef_init(struct hda_codec *codec)
1005 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1006 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1007 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1008 if ((tmp & 0xf0) == 0x20)
1010 snd_hda_codec_read(codec, 0x20, 0,
1011 AC_VERB_SET_PROC_COEF, 0x830);
1014 snd_hda_codec_read(codec, 0x20, 0,
1015 AC_VERB_SET_PROC_COEF, 0x3030);
1018 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1023 case ALC_INIT_GPIO1:
1024 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1026 case ALC_INIT_GPIO2:
1027 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1029 case ALC_INIT_GPIO3:
1030 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1032 case ALC_INIT_DEFAULT:
1033 switch (codec->vendor_id) {
1035 snd_hda_codec_write(codec, 0x0f, 0,
1036 AC_VERB_SET_EAPD_BTLENABLE, 2);
1037 snd_hda_codec_write(codec, 0x10, 0,
1038 AC_VERB_SET_EAPD_BTLENABLE, 2);
1050 snd_hda_codec_write(codec, 0x14, 0,
1051 AC_VERB_SET_EAPD_BTLENABLE, 2);
1052 snd_hda_codec_write(codec, 0x15, 0,
1053 AC_VERB_SET_EAPD_BTLENABLE, 2);
1056 switch (codec->vendor_id) {
1058 snd_hda_codec_write(codec, 0x1a, 0,
1059 AC_VERB_SET_COEF_INDEX, 7);
1060 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1061 AC_VERB_GET_PROC_COEF, 0);
1062 snd_hda_codec_write(codec, 0x1a, 0,
1063 AC_VERB_SET_COEF_INDEX, 7);
1064 snd_hda_codec_write(codec, 0x1a, 0,
1065 AC_VERB_SET_PROC_COEF,
1075 snd_hda_codec_write(codec, 0x20, 0,
1076 AC_VERB_SET_COEF_INDEX, 7);
1077 tmp = snd_hda_codec_read(codec, 0x20, 0,
1078 AC_VERB_GET_PROC_COEF, 0);
1079 snd_hda_codec_write(codec, 0x20, 0,
1080 AC_VERB_SET_COEF_INDEX, 7);
1081 snd_hda_codec_write(codec, 0x20, 0,
1082 AC_VERB_SET_PROC_COEF,
1086 alc888_coef_init(codec);
1090 snd_hda_codec_write(codec, 0x20, 0,
1091 AC_VERB_SET_COEF_INDEX, 7);
1092 tmp = snd_hda_codec_read(codec, 0x20, 0,
1093 AC_VERB_GET_PROC_COEF, 0);
1094 snd_hda_codec_write(codec, 0x20, 0,
1095 AC_VERB_SET_COEF_INDEX, 7);
1096 snd_hda_codec_write(codec, 0x20, 0,
1097 AC_VERB_SET_PROC_COEF,
1105 static void alc_init_auto_hp(struct hda_codec *codec)
1107 struct alc_spec *spec = codec->spec;
1109 if (!spec->autocfg.hp_pins[0])
1112 if (!spec->autocfg.speaker_pins[0]) {
1113 if (spec->autocfg.line_out_pins[0] &&
1114 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1115 spec->autocfg.speaker_pins[0] =
1116 spec->autocfg.line_out_pins[0];
1121 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1122 spec->autocfg.hp_pins[0]);
1123 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1124 AC_VERB_SET_UNSOLICITED_ENABLE,
1125 AC_USRSP_EN | ALC880_HP_EVENT);
1126 spec->unsol_event = alc_sku_unsol_event;
1129 /* check subsystem ID and set up device-specific initialization;
1130 * return 1 if initialized, 0 if invalid SSID
1132 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1133 * 31 ~ 16 : Manufacture ID
1135 * 7 ~ 0 : Assembly ID
1136 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1138 static int alc_subsystem_id(struct hda_codec *codec,
1139 hda_nid_t porta, hda_nid_t porte,
1142 unsigned int ass, tmp, i;
1144 struct alc_spec *spec = codec->spec;
1146 ass = codec->subsystem_id & 0xffff;
1147 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1150 /* invalid SSID, check the special NID pin defcfg instead */
1152 * 31~30 : port conetcivity
1155 * 19~16 : Check sum (15:1)
1160 if (codec->vendor_id == 0x10ec0260)
1162 ass = snd_hda_codec_get_pincfg(codec, nid);
1163 snd_printd("realtek: No valid SSID, "
1164 "checking pincfg 0x%08x for NID 0x%x\n",
1166 if (!(ass & 1) && !(ass & 0x100000))
1168 if ((ass >> 30) != 1) /* no physical connection */
1173 for (i = 1; i < 16; i++) {
1177 if (((ass >> 16) & 0xf) != tmp)
1180 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1181 ass & 0xffff, codec->vendor_id);
1185 * 2 : 0 --> Desktop, 1 --> Laptop
1186 * 3~5 : External Amplifier control
1189 tmp = (ass & 0x38) >> 3; /* external Amp control */
1192 spec->init_amp = ALC_INIT_GPIO1;
1195 spec->init_amp = ALC_INIT_GPIO2;
1198 spec->init_amp = ALC_INIT_GPIO3;
1201 spec->init_amp = ALC_INIT_DEFAULT;
1205 /* is laptop or Desktop and enable the function "Mute internal speaker
1206 * when the external headphone out jack is plugged"
1208 if (!(ass & 0x8000))
1211 * 10~8 : Jack location
1212 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1214 * 15 : 1 --> enable the function "Mute internal speaker
1215 * when the external headphone out jack is plugged"
1217 if (!spec->autocfg.hp_pins[0]) {
1218 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1220 spec->autocfg.hp_pins[0] = porta;
1222 spec->autocfg.hp_pins[0] = porte;
1224 spec->autocfg.hp_pins[0] = portd;
1229 alc_init_auto_hp(codec);
1233 static void alc_ssid_check(struct hda_codec *codec,
1234 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1236 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1237 struct alc_spec *spec = codec->spec;
1238 snd_printd("realtek: "
1239 "Enable default setup for auto mode as fallback\n");
1240 spec->init_amp = ALC_INIT_DEFAULT;
1241 alc_init_auto_hp(codec);
1246 * Fix-up pin default configurations
1254 static void alc_fix_pincfg(struct hda_codec *codec,
1255 const struct snd_pci_quirk *quirk,
1256 const struct alc_pincfg **pinfix)
1258 const struct alc_pincfg *cfg;
1260 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1264 cfg = pinfix[quirk->value];
1265 for (; cfg->nid; cfg++)
1266 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1276 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1277 /* Mic-in jack as mic in */
1278 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1279 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1280 /* Line-in jack as Line in */
1281 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1282 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1283 /* Line-Out as Front */
1284 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1291 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1292 /* Mic-in jack as mic in */
1293 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1294 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1295 /* Line-in jack as Surround */
1296 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1297 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1298 /* Line-Out as Front */
1299 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1306 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1307 /* Mic-in jack as CLFE */
1308 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1309 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1310 /* Line-in jack as Surround */
1311 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1312 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1313 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1314 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1321 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1322 /* Mic-in jack as CLFE */
1323 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1324 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1325 /* Line-in jack as Surround */
1326 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1327 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1328 /* Line-Out as Side */
1329 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1333 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1334 { 2, alc888_4ST_ch2_intel_init },
1335 { 4, alc888_4ST_ch4_intel_init },
1336 { 6, alc888_4ST_ch6_intel_init },
1337 { 8, alc888_4ST_ch8_intel_init },
1341 * ALC888 Fujitsu Siemens Amillo xa3530
1344 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1345 /* Front Mic: set to PIN_IN (empty by default) */
1346 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1347 /* Connect Internal HP to Front */
1348 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1350 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1351 /* Connect Bass HP to Front */
1352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1353 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1354 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1355 /* Connect Line-Out side jack (SPDIF) to Side */
1356 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1357 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1358 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1359 /* Connect Mic jack to CLFE */
1360 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1363 /* Connect Line-in jack to Surround */
1364 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1365 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1366 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1367 /* Connect HP out jack to Front */
1368 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1369 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1370 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1371 /* Enable unsolicited event for HP jack and Line-out jack */
1372 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1373 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1377 static void alc_automute_amp(struct hda_codec *codec)
1379 struct alc_spec *spec = codec->spec;
1380 unsigned int val, mute;
1384 spec->jack_present = 0;
1385 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1386 nid = spec->autocfg.hp_pins[i];
1389 val = snd_hda_codec_read(codec, nid, 0,
1390 AC_VERB_GET_PIN_SENSE, 0);
1391 if (val & AC_PINSENSE_PRESENCE) {
1392 spec->jack_present = 1;
1397 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1398 /* Toggle internal speakers muting */
1399 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1400 nid = spec->autocfg.speaker_pins[i];
1403 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1404 HDA_AMP_MUTE, mute);
1408 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1411 if (codec->vendor_id == 0x10ec0880)
1415 if (res == ALC880_HP_EVENT)
1416 alc_automute_amp(codec);
1419 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1421 struct alc_spec *spec = codec->spec;
1423 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1424 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1425 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1426 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1427 alc_automute_amp(codec);
1431 * ALC888 Acer Aspire 4930G model
1434 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1435 /* Front Mic: set to PIN_IN (empty by default) */
1436 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1437 /* Unselect Front Mic by default in input mixer 3 */
1438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1439 /* Enable unsolicited event for HP jack */
1440 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1441 /* Connect Internal HP to front */
1442 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1443 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1445 /* Connect HP out to front */
1446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1448 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1452 static struct hda_input_mux alc888_2_capture_sources[2] = {
1453 /* Front mic only available on one ADC */
1460 { "Front Mic", 0xb },
1473 static struct snd_kcontrol_new alc888_base_mixer[] = {
1474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1475 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1476 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1477 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1478 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1480 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1481 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1482 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1483 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1484 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1485 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1486 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1487 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1488 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1490 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1495 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1497 struct alc_spec *spec = codec->spec;
1499 spec->autocfg.hp_pins[0] = 0x15;
1500 spec->autocfg.speaker_pins[0] = 0x14;
1501 alc_automute_amp(codec);
1505 * ALC880 3-stack model
1507 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1508 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1509 * F-Mic = 0x1b, HP = 0x19
1512 static hda_nid_t alc880_dac_nids[4] = {
1513 /* front, rear, clfe, rear_surr */
1514 0x02, 0x05, 0x04, 0x03
1517 static hda_nid_t alc880_adc_nids[3] = {
1522 /* The datasheet says the node 0x07 is connected from inputs,
1523 * but it shows zero connection in the real implementation on some devices.
1524 * Note: this is a 915GAV bug, fixed on 915GLV
1526 static hda_nid_t alc880_adc_nids_alt[2] = {
1531 #define ALC880_DIGOUT_NID 0x06
1532 #define ALC880_DIGIN_NID 0x0a
1534 static struct hda_input_mux alc880_capture_source = {
1538 { "Front Mic", 0x3 },
1544 /* channel source setting (2/6 channel selection for 3-stack) */
1546 static struct hda_verb alc880_threestack_ch2_init[] = {
1547 /* set line-in to input, mute it */
1548 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1549 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1550 /* set mic-in to input vref 80%, mute it */
1551 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1552 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1557 static struct hda_verb alc880_threestack_ch6_init[] = {
1558 /* set line-in to output, unmute it */
1559 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1560 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1561 /* set mic-in to output, unmute it */
1562 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1563 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1567 static struct hda_channel_mode alc880_threestack_modes[2] = {
1568 { 2, alc880_threestack_ch2_init },
1569 { 6, alc880_threestack_ch6_init },
1572 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1573 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1574 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1575 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1576 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1577 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1578 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1579 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1580 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1589 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1592 .name = "Channel Mode",
1593 .info = alc_ch_mode_info,
1594 .get = alc_ch_mode_get,
1595 .put = alc_ch_mode_put,
1600 /* capture mixer elements */
1601 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1602 struct snd_ctl_elem_info *uinfo)
1604 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1605 struct alc_spec *spec = codec->spec;
1608 mutex_lock(&codec->control_mutex);
1609 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1611 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1612 mutex_unlock(&codec->control_mutex);
1616 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1617 unsigned int size, unsigned int __user *tlv)
1619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1620 struct alc_spec *spec = codec->spec;
1623 mutex_lock(&codec->control_mutex);
1624 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1626 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1627 mutex_unlock(&codec->control_mutex);
1631 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1632 struct snd_ctl_elem_value *ucontrol);
1634 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1635 struct snd_ctl_elem_value *ucontrol,
1638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1639 struct alc_spec *spec = codec->spec;
1640 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1643 mutex_lock(&codec->control_mutex);
1644 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1646 err = func(kcontrol, ucontrol);
1647 mutex_unlock(&codec->control_mutex);
1651 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1652 struct snd_ctl_elem_value *ucontrol)
1654 return alc_cap_getput_caller(kcontrol, ucontrol,
1655 snd_hda_mixer_amp_volume_get);
1658 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol)
1661 return alc_cap_getput_caller(kcontrol, ucontrol,
1662 snd_hda_mixer_amp_volume_put);
1665 /* capture mixer elements */
1666 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1668 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1669 struct snd_ctl_elem_value *ucontrol)
1671 return alc_cap_getput_caller(kcontrol, ucontrol,
1672 snd_hda_mixer_amp_switch_get);
1675 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1676 struct snd_ctl_elem_value *ucontrol)
1678 return alc_cap_getput_caller(kcontrol, ucontrol,
1679 snd_hda_mixer_amp_switch_put);
1682 #define _DEFINE_CAPMIX(num) \
1684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1685 .name = "Capture Switch", \
1686 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1688 .info = alc_cap_sw_info, \
1689 .get = alc_cap_sw_get, \
1690 .put = alc_cap_sw_put, \
1693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1694 .name = "Capture Volume", \
1695 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1696 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1697 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1699 .info = alc_cap_vol_info, \
1700 .get = alc_cap_vol_get, \
1701 .put = alc_cap_vol_put, \
1702 .tlv = { .c = alc_cap_vol_tlv }, \
1705 #define _DEFINE_CAPSRC(num) \
1707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1708 /* .name = "Capture Source", */ \
1709 .name = "Input Source", \
1711 .info = alc_mux_enum_info, \
1712 .get = alc_mux_enum_get, \
1713 .put = alc_mux_enum_put, \
1716 #define DEFINE_CAPMIX(num) \
1717 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1718 _DEFINE_CAPMIX(num), \
1719 _DEFINE_CAPSRC(num), \
1723 #define DEFINE_CAPMIX_NOSRC(num) \
1724 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1725 _DEFINE_CAPMIX(num), \
1729 /* up to three ADCs */
1733 DEFINE_CAPMIX_NOSRC(1);
1734 DEFINE_CAPMIX_NOSRC(2);
1735 DEFINE_CAPMIX_NOSRC(3);
1738 * ALC880 5-stack model
1740 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1742 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1743 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1746 /* additional mixers to alc880_three_stack_mixer */
1747 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1748 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1749 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1753 /* channel source setting (6/8 channel selection for 5-stack) */
1755 static struct hda_verb alc880_fivestack_ch6_init[] = {
1756 /* set line-in to input, mute it */
1757 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1758 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1763 static struct hda_verb alc880_fivestack_ch8_init[] = {
1764 /* set line-in to output, unmute it */
1765 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1766 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1770 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1771 { 6, alc880_fivestack_ch6_init },
1772 { 8, alc880_fivestack_ch8_init },
1777 * ALC880 6-stack model
1779 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1780 * Side = 0x05 (0x0f)
1781 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1782 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1785 static hda_nid_t alc880_6st_dac_nids[4] = {
1786 /* front, rear, clfe, rear_surr */
1787 0x02, 0x03, 0x04, 0x05
1790 static struct hda_input_mux alc880_6stack_capture_source = {
1794 { "Front Mic", 0x1 },
1800 /* fixed 8-channels */
1801 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1805 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1806 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1807 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1808 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1809 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1810 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1811 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1812 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1813 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1814 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1815 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1816 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1817 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1822 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1823 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1826 .name = "Channel Mode",
1827 .info = alc_ch_mode_info,
1828 .get = alc_ch_mode_get,
1829 .put = alc_ch_mode_put,
1838 * W810 has rear IO for:
1841 * Center/LFE (DAC 04)
1844 * The system also has a pair of internal speakers, and a headphone jack.
1845 * These are both connected to Line2 on the codec, hence to DAC 02.
1847 * There is a variable resistor to control the speaker or headphone
1848 * volume. This is a hardware-only device without a software API.
1850 * Plugging headphones in will disable the internal speakers. This is
1851 * implemented in hardware, not via the driver using jack sense. In
1852 * a similar fashion, plugging into the rear socket marked "front" will
1853 * disable both the speakers and headphones.
1855 * For input, there's a microphone jack, and an "audio in" jack.
1856 * These may not do anything useful with this driver yet, because I
1857 * haven't setup any initialization verbs for these yet...
1860 static hda_nid_t alc880_w810_dac_nids[3] = {
1861 /* front, rear/surround, clfe */
1865 /* fixed 6 channels */
1866 static struct hda_channel_mode alc880_w810_modes[1] = {
1870 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1871 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1872 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1873 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1874 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1875 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1876 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1877 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1878 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1879 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1880 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1888 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1889 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1893 static hda_nid_t alc880_z71v_dac_nids[1] = {
1896 #define ALC880_Z71V_HP_DAC 0x03
1898 /* fixed 2 channels */
1899 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1903 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1905 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1906 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1907 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1908 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1909 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1910 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1911 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1917 * ALC880 F1734 model
1919 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1920 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1923 static hda_nid_t alc880_f1734_dac_nids[1] = {
1926 #define ALC880_F1734_HP_DAC 0x02
1928 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1929 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1930 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1931 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1932 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1933 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1934 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1940 static struct hda_input_mux alc880_f1734_capture_source = {
1952 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1953 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1954 * Mic = 0x18, Line = 0x1a
1957 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1958 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1960 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1963 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1964 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1965 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1974 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1976 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1977 .name = "Channel Mode",
1978 .info = alc_ch_mode_info,
1979 .get = alc_ch_mode_get,
1980 .put = alc_ch_mode_put,
1986 * ALC880 ASUS W1V model
1988 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1989 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1990 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1993 /* additional mixers to alc880_asus_mixer */
1994 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1995 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1996 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2001 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2002 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2003 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2006 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2009 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2010 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2015 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2016 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2017 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2018 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2019 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2020 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2021 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2022 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2023 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2024 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2025 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2026 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2027 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2029 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2031 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2033 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2034 .name = "Channel Mode",
2035 .info = alc_ch_mode_info,
2036 .get = alc_ch_mode_get,
2037 .put = alc_ch_mode_put,
2042 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2044 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2045 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2046 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2047 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2048 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2049 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2050 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2051 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2052 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2056 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2057 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2058 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2059 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2060 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2067 * virtual master controls
2071 * slave controls for virtual master
2073 static const char *alc_slave_vols[] = {
2074 "Front Playback Volume",
2075 "Surround Playback Volume",
2076 "Center Playback Volume",
2077 "LFE Playback Volume",
2078 "Side Playback Volume",
2079 "Headphone Playback Volume",
2080 "Speaker Playback Volume",
2081 "Mono Playback Volume",
2082 "Line-Out Playback Volume",
2083 "PCM Playback Volume",
2087 static const char *alc_slave_sws[] = {
2088 "Front Playback Switch",
2089 "Surround Playback Switch",
2090 "Center Playback Switch",
2091 "LFE Playback Switch",
2092 "Side Playback Switch",
2093 "Headphone Playback Switch",
2094 "Speaker Playback Switch",
2095 "Mono Playback Switch",
2096 "IEC958 Playback Switch",
2101 * build control elements
2104 static void alc_free_kctls(struct hda_codec *codec);
2106 /* additional beep mixers; the actual parameters are overwritten at build */
2107 static struct snd_kcontrol_new alc_beep_mixer[] = {
2108 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2109 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2113 static int alc_build_controls(struct hda_codec *codec)
2115 struct alc_spec *spec = codec->spec;
2119 for (i = 0; i < spec->num_mixers; i++) {
2120 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2124 if (spec->cap_mixer) {
2125 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2129 if (spec->multiout.dig_out_nid) {
2130 err = snd_hda_create_spdif_out_ctls(codec,
2131 spec->multiout.dig_out_nid);
2134 if (!spec->no_analog) {
2135 err = snd_hda_create_spdif_share_sw(codec,
2139 spec->multiout.share_spdif = 1;
2142 if (spec->dig_in_nid) {
2143 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2148 /* create beep controls if needed */
2149 if (spec->beep_amp) {
2150 struct snd_kcontrol_new *knew;
2151 for (knew = alc_beep_mixer; knew->name; knew++) {
2152 struct snd_kcontrol *kctl;
2153 kctl = snd_ctl_new1(knew, codec);
2156 kctl->private_value = spec->beep_amp;
2157 err = snd_hda_ctl_add(codec, kctl);
2163 /* if we have no master control, let's create it */
2164 if (!spec->no_analog &&
2165 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2166 unsigned int vmaster_tlv[4];
2167 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2168 HDA_OUTPUT, vmaster_tlv);
2169 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2170 vmaster_tlv, alc_slave_vols);
2174 if (!spec->no_analog &&
2175 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2176 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2177 NULL, alc_slave_sws);
2182 alc_free_kctls(codec); /* no longer needed */
2188 * initialize the codec volumes, etc
2192 * generic initialization of ADC, input mixers and output mixers
2194 static struct hda_verb alc880_volume_init_verbs[] = {
2196 * Unmute ADC0-2 and set the default input to mic-in
2198 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2200 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2201 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2202 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2203 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2205 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2207 * Note: PASD motherboards uses the Line In 2 as the input for front
2210 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2215 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2216 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2217 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2220 * Set up output mixers (0x0c - 0x0f)
2222 /* set vol=0 to output mixers */
2223 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2224 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2227 /* set up input amps for analog loopback */
2228 /* Amp Indices: DAC = 0, mixer = 1 */
2229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2231 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2232 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2235 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2236 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2242 * 3-stack pin configuration:
2243 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2245 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2247 * preset connection lists of input pins
2248 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2250 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2251 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2252 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2255 * Set pin mode and muting
2257 /* set front pin widgets 0x14 for output */
2258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2259 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2260 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2261 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2262 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2263 /* Mic2 (as headphone out) for HP output */
2264 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2265 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266 /* Line In pin widget for input */
2267 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2268 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2269 /* Line2 (as front mic) pin widget for input and vref at 80% */
2270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2271 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2272 /* CD pin widget for input */
2273 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2279 * 5-stack pin configuration:
2280 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2281 * line-in/side = 0x1a, f-mic = 0x1b
2283 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2285 * preset connection lists of input pins
2286 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2288 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2289 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2292 * Set pin mode and muting
2294 /* set pin widgets 0x14-0x17 for output */
2295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2297 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2298 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2299 /* unmute pins for output (no gain on this amp) */
2300 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2305 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2308 /* Mic2 (as headphone out) for HP output */
2309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2311 /* Line In pin widget for input */
2312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2314 /* Line2 (as front mic) pin widget for input and vref at 80% */
2315 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2316 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2317 /* CD pin widget for input */
2318 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2324 * W810 pin configuration:
2325 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2327 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2328 /* hphone/speaker input selector: front DAC */
2329 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2332 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2334 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2335 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2338 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2339 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2345 * Z71V pin configuration:
2346 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2348 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2350 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2352 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2354 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2355 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2356 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2357 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2363 * 6-stack pin configuration:
2364 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2365 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2367 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2368 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2370 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2371 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2372 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2374 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2375 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2376 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2377 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2379 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2381 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2382 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2383 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2384 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2385 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2386 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2387 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2393 * Uniwill pin configuration:
2394 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2397 static struct hda_verb alc880_uniwill_init_verbs[] = {
2398 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2400 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2401 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2402 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2403 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2404 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2405 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2406 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2407 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2417 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2418 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2419 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2420 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2421 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2422 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2423 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2425 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2426 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2433 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2435 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2436 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2440 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2441 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2442 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2443 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2444 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2445 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2446 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2447 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2448 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2449 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2455 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2456 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2458 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2459 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2464 static struct hda_verb alc880_beep_init_verbs[] = {
2465 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2469 /* auto-toggle front mic */
2470 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2472 unsigned int present;
2475 present = snd_hda_codec_read(codec, 0x18, 0,
2476 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2477 bits = present ? HDA_AMP_MUTE : 0;
2478 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2481 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2483 struct alc_spec *spec = codec->spec;
2485 spec->autocfg.hp_pins[0] = 0x14;
2486 spec->autocfg.speaker_pins[0] = 0x15;
2487 spec->autocfg.speaker_pins[0] = 0x16;
2488 alc_automute_amp(codec);
2489 alc880_uniwill_mic_automute(codec);
2492 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2495 /* Looks like the unsol event is incompatible with the standard
2496 * definition. 4bit tag is placed at 28 bit!
2498 switch (res >> 28) {
2499 case ALC880_MIC_EVENT:
2500 alc880_uniwill_mic_automute(codec);
2503 alc_automute_amp_unsol_event(codec, res);
2508 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2510 struct alc_spec *spec = codec->spec;
2512 spec->autocfg.hp_pins[0] = 0x14;
2513 spec->autocfg.speaker_pins[0] = 0x15;
2514 alc_automute_amp(codec);
2517 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2519 unsigned int present;
2521 present = snd_hda_codec_read(codec, 0x21, 0,
2522 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2523 present &= HDA_AMP_VOLMASK;
2524 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2525 HDA_AMP_VOLMASK, present);
2526 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2527 HDA_AMP_VOLMASK, present);
2530 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2533 /* Looks like the unsol event is incompatible with the standard
2534 * definition. 4bit tag is placed at 28 bit!
2536 if ((res >> 28) == ALC880_DCVOL_EVENT)
2537 alc880_uniwill_p53_dcvol_automute(codec);
2539 alc_automute_amp_unsol_event(codec, res);
2543 * F1734 pin configuration:
2544 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2546 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2547 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2548 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2549 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2550 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2551 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2558 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2559 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2562 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2563 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2564 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2565 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2566 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2568 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2569 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2575 * ASUS pin configuration:
2576 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2578 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2579 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2580 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2581 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2582 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2585 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2587 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2588 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2590 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2591 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2594 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2595 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2597 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2599 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2601 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2606 /* Enable GPIO mask and set output */
2607 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2608 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2610 /* Clevo m520g init */
2611 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2612 /* headphone output */
2613 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2616 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2618 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2619 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2621 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2622 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2623 /* Mic1 (rear panel) */
2624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2626 /* Mic2 (front panel) */
2627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2628 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2630 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2632 /* change to EAPD mode */
2633 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2634 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2639 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2640 /* change to EAPD mode */
2641 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2642 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2644 /* Headphone output */
2645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2647 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2648 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2650 /* Line In pin widget for input */
2651 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2652 /* CD pin widget for input */
2653 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2654 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2657 /* change to EAPD mode */
2658 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2659 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2665 * LG m1 express dual
2668 * Rear Line-In/Out (blue): 0x14
2669 * Build-in Mic-In: 0x15
2671 * HP-Out (green): 0x1b
2672 * Mic-In/Out (red): 0x19
2676 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2677 static hda_nid_t alc880_lg_dac_nids[3] = {
2681 /* seems analog CD is not working */
2682 static struct hda_input_mux alc880_lg_capture_source = {
2687 { "Internal Mic", 0x6 },
2691 /* 2,4,6 channel modes */
2692 static struct hda_verb alc880_lg_ch2_init[] = {
2693 /* set line-in and mic-in to input */
2694 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2695 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2699 static struct hda_verb alc880_lg_ch4_init[] = {
2700 /* set line-in to out and mic-in to input */
2701 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2702 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2706 static struct hda_verb alc880_lg_ch6_init[] = {
2707 /* set line-in and mic-in to output */
2708 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2709 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2713 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2714 { 2, alc880_lg_ch2_init },
2715 { 4, alc880_lg_ch4_init },
2716 { 6, alc880_lg_ch6_init },
2719 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2720 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2721 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2722 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2723 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2724 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2725 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2726 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2727 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2730 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2731 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2732 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2733 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2736 .name = "Channel Mode",
2737 .info = alc_ch_mode_info,
2738 .get = alc_ch_mode_get,
2739 .put = alc_ch_mode_put,
2744 static struct hda_verb alc880_lg_init_verbs[] = {
2745 /* set capture source to mic-in */
2746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2748 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2749 /* mute all amp mixer inputs */
2750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2753 /* line-in to input */
2754 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2760 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2761 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2762 /* mic-in to input */
2763 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2767 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2769 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2771 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2775 /* toggle speaker-output according to the hp-jack state */
2776 static void alc880_lg_init_hook(struct hda_codec *codec)
2778 struct alc_spec *spec = codec->spec;
2780 spec->autocfg.hp_pins[0] = 0x1b;
2781 spec->autocfg.speaker_pins[0] = 0x17;
2782 alc_automute_amp(codec);
2791 * Built-in Mic-In: 0x19
2797 static struct hda_input_mux alc880_lg_lw_capture_source = {
2801 { "Internal Mic", 0x1 },
2806 #define alc880_lg_lw_modes alc880_threestack_modes
2808 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2810 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2811 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2812 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2813 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2814 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2816 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2821 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2822 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2825 .name = "Channel Mode",
2826 .info = alc_ch_mode_info,
2827 .get = alc_ch_mode_get,
2828 .put = alc_ch_mode_put,
2833 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2834 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2835 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2836 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2838 /* set capture source to mic-in */
2839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2840 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2841 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2844 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2847 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2848 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2849 /* mic-in to input */
2850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2853 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2854 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2856 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2860 /* toggle speaker-output according to the hp-jack state */
2861 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2863 struct alc_spec *spec = codec->spec;
2865 spec->autocfg.hp_pins[0] = 0x1b;
2866 spec->autocfg.speaker_pins[0] = 0x14;
2867 alc_automute_amp(codec);
2870 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2871 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2872 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2874 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2875 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2876 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2880 static struct hda_input_mux alc880_medion_rim_capture_source = {
2884 { "Internal Mic", 0x1 },
2888 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2889 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2894 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2895 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2896 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2897 /* Mic2 (as headphone out) for HP output */
2898 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2899 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2900 /* Internal Speaker */
2901 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2902 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2904 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2905 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2907 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2911 /* toggle speaker-output according to the hp-jack state */
2912 static void alc880_medion_rim_automute(struct hda_codec *codec)
2914 struct alc_spec *spec = codec->spec;
2915 alc_automute_amp(codec);
2917 if (spec->jack_present)
2918 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2920 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2923 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2926 /* Looks like the unsol event is incompatible with the standard
2927 * definition. 4bit tag is placed at 28 bit!
2929 if ((res >> 28) == ALC880_HP_EVENT)
2930 alc880_medion_rim_automute(codec);
2933 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
2935 struct alc_spec *spec = codec->spec;
2937 spec->autocfg.hp_pins[0] = 0x14;
2938 spec->autocfg.speaker_pins[0] = 0x1b;
2939 alc880_medion_rim_automute(codec);
2942 #ifdef CONFIG_SND_HDA_POWER_SAVE
2943 static struct hda_amp_list alc880_loopbacks[] = {
2944 { 0x0b, HDA_INPUT, 0 },
2945 { 0x0b, HDA_INPUT, 1 },
2946 { 0x0b, HDA_INPUT, 2 },
2947 { 0x0b, HDA_INPUT, 3 },
2948 { 0x0b, HDA_INPUT, 4 },
2952 static struct hda_amp_list alc880_lg_loopbacks[] = {
2953 { 0x0b, HDA_INPUT, 1 },
2954 { 0x0b, HDA_INPUT, 6 },
2955 { 0x0b, HDA_INPUT, 7 },
2964 static int alc_init(struct hda_codec *codec)
2966 struct alc_spec *spec = codec->spec;
2970 alc_auto_init_amp(codec, spec->init_amp);
2972 for (i = 0; i < spec->num_init_verbs; i++)
2973 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2975 if (spec->init_hook)
2976 spec->init_hook(codec);
2981 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2983 struct alc_spec *spec = codec->spec;
2985 if (spec->unsol_event)
2986 spec->unsol_event(codec, res);
2989 #ifdef CONFIG_SND_HDA_POWER_SAVE
2990 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2992 struct alc_spec *spec = codec->spec;
2993 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2998 * Analog playback callbacks
3000 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3001 struct hda_codec *codec,
3002 struct snd_pcm_substream *substream)
3004 struct alc_spec *spec = codec->spec;
3005 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3009 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3010 struct hda_codec *codec,
3011 unsigned int stream_tag,
3012 unsigned int format,
3013 struct snd_pcm_substream *substream)
3015 struct alc_spec *spec = codec->spec;
3016 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3017 stream_tag, format, substream);
3020 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3021 struct hda_codec *codec,
3022 struct snd_pcm_substream *substream)
3024 struct alc_spec *spec = codec->spec;
3025 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3031 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3032 struct hda_codec *codec,
3033 struct snd_pcm_substream *substream)
3035 struct alc_spec *spec = codec->spec;
3036 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3039 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3040 struct hda_codec *codec,
3041 unsigned int stream_tag,
3042 unsigned int format,
3043 struct snd_pcm_substream *substream)
3045 struct alc_spec *spec = codec->spec;
3046 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3047 stream_tag, format, substream);
3050 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3051 struct hda_codec *codec,
3052 struct snd_pcm_substream *substream)
3054 struct alc_spec *spec = codec->spec;
3055 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3058 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3059 struct hda_codec *codec,
3060 struct snd_pcm_substream *substream)
3062 struct alc_spec *spec = codec->spec;
3063 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3069 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3070 struct hda_codec *codec,
3071 unsigned int stream_tag,
3072 unsigned int format,
3073 struct snd_pcm_substream *substream)
3075 struct alc_spec *spec = codec->spec;
3077 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3078 stream_tag, 0, format);
3082 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3083 struct hda_codec *codec,
3084 struct snd_pcm_substream *substream)
3086 struct alc_spec *spec = codec->spec;
3088 snd_hda_codec_cleanup_stream(codec,
3089 spec->adc_nids[substream->number + 1]);
3096 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3100 /* NID is set in alc_build_pcms */
3102 .open = alc880_playback_pcm_open,
3103 .prepare = alc880_playback_pcm_prepare,
3104 .cleanup = alc880_playback_pcm_cleanup
3108 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3112 /* NID is set in alc_build_pcms */
3115 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3119 /* NID is set in alc_build_pcms */
3122 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3123 .substreams = 2, /* can be overridden */
3126 /* NID is set in alc_build_pcms */
3128 .prepare = alc880_alt_capture_pcm_prepare,
3129 .cleanup = alc880_alt_capture_pcm_cleanup
3133 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3137 /* NID is set in alc_build_pcms */
3139 .open = alc880_dig_playback_pcm_open,
3140 .close = alc880_dig_playback_pcm_close,
3141 .prepare = alc880_dig_playback_pcm_prepare,
3142 .cleanup = alc880_dig_playback_pcm_cleanup
3146 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3150 /* NID is set in alc_build_pcms */
3153 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3154 static struct hda_pcm_stream alc_pcm_null_stream = {
3160 static int alc_build_pcms(struct hda_codec *codec)
3162 struct alc_spec *spec = codec->spec;
3163 struct hda_pcm *info = spec->pcm_rec;
3166 codec->num_pcms = 1;
3167 codec->pcm_info = info;
3169 if (spec->no_analog)
3172 info->name = spec->stream_name_analog;
3173 if (spec->stream_analog_playback) {
3174 if (snd_BUG_ON(!spec->multiout.dac_nids))
3176 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3177 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3179 if (spec->stream_analog_capture) {
3180 if (snd_BUG_ON(!spec->adc_nids))
3182 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3183 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3186 if (spec->channel_mode) {
3187 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3188 for (i = 0; i < spec->num_channel_mode; i++) {
3189 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3190 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3196 /* SPDIF for stream index #1 */
3197 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3198 codec->num_pcms = 2;
3199 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3200 info = spec->pcm_rec + 1;
3201 info->name = spec->stream_name_digital;
3202 if (spec->dig_out_type)
3203 info->pcm_type = spec->dig_out_type;
3205 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3206 if (spec->multiout.dig_out_nid &&
3207 spec->stream_digital_playback) {
3208 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3209 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3211 if (spec->dig_in_nid &&
3212 spec->stream_digital_capture) {
3213 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3214 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3216 /* FIXME: do we need this for all Realtek codec models? */
3217 codec->spdif_status_reset = 1;
3220 if (spec->no_analog)
3223 /* If the use of more than one ADC is requested for the current
3224 * model, configure a second analog capture-only PCM.
3226 /* Additional Analaog capture for index #2 */
3227 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3228 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3229 codec->num_pcms = 3;
3230 info = spec->pcm_rec + 2;
3231 info->name = spec->stream_name_analog;
3232 if (spec->alt_dac_nid) {
3233 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3234 *spec->stream_analog_alt_playback;
3235 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3238 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3239 alc_pcm_null_stream;
3240 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3242 if (spec->num_adc_nids > 1) {
3243 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3244 *spec->stream_analog_alt_capture;
3245 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3247 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3248 spec->num_adc_nids - 1;
3250 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3251 alc_pcm_null_stream;
3252 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3259 static void alc_free_kctls(struct hda_codec *codec)
3261 struct alc_spec *spec = codec->spec;
3263 if (spec->kctls.list) {
3264 struct snd_kcontrol_new *kctl = spec->kctls.list;
3266 for (i = 0; i < spec->kctls.used; i++)
3267 kfree(kctl[i].name);
3269 snd_array_free(&spec->kctls);
3272 static void alc_free(struct hda_codec *codec)
3274 struct alc_spec *spec = codec->spec;
3279 alc_free_kctls(codec);
3281 snd_hda_detach_beep_device(codec);
3284 #ifdef SND_HDA_NEEDS_RESUME
3285 static int alc_resume(struct hda_codec *codec)
3287 codec->patch_ops.init(codec);
3288 snd_hda_codec_resume_amp(codec);
3289 snd_hda_codec_resume_cache(codec);
3296 static struct hda_codec_ops alc_patch_ops = {
3297 .build_controls = alc_build_controls,
3298 .build_pcms = alc_build_pcms,
3301 .unsol_event = alc_unsol_event,
3302 #ifdef SND_HDA_NEEDS_RESUME
3303 .resume = alc_resume,
3305 #ifdef CONFIG_SND_HDA_POWER_SAVE
3306 .check_power_status = alc_check_power_status,
3312 * Test configuration for debugging
3314 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3317 #ifdef CONFIG_SND_DEBUG
3318 static hda_nid_t alc880_test_dac_nids[4] = {
3319 0x02, 0x03, 0x04, 0x05
3322 static struct hda_input_mux alc880_test_capture_source = {
3331 { "Surround", 0x6 },
3335 static struct hda_channel_mode alc880_test_modes[4] = {
3342 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3343 struct snd_ctl_elem_info *uinfo)
3345 static char *texts[] = {
3346 "N/A", "Line Out", "HP Out",
3347 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3349 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3351 uinfo->value.enumerated.items = 8;
3352 if (uinfo->value.enumerated.item >= 8)
3353 uinfo->value.enumerated.item = 7;
3354 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3358 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3359 struct snd_ctl_elem_value *ucontrol)
3361 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3362 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3363 unsigned int pin_ctl, item = 0;
3365 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3366 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3367 if (pin_ctl & AC_PINCTL_OUT_EN) {
3368 if (pin_ctl & AC_PINCTL_HP_EN)
3372 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3373 switch (pin_ctl & AC_PINCTL_VREFEN) {
3374 case AC_PINCTL_VREF_HIZ: item = 3; break;
3375 case AC_PINCTL_VREF_50: item = 4; break;
3376 case AC_PINCTL_VREF_GRD: item = 5; break;
3377 case AC_PINCTL_VREF_80: item = 6; break;
3378 case AC_PINCTL_VREF_100: item = 7; break;
3381 ucontrol->value.enumerated.item[0] = item;
3385 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3386 struct snd_ctl_elem_value *ucontrol)
3388 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3389 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3390 static unsigned int ctls[] = {
3391 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3392 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3393 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3394 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3395 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3396 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3398 unsigned int old_ctl, new_ctl;
3400 old_ctl = snd_hda_codec_read(codec, nid, 0,
3401 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3402 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3403 if (old_ctl != new_ctl) {
3405 snd_hda_codec_write_cache(codec, nid, 0,
3406 AC_VERB_SET_PIN_WIDGET_CONTROL,
3408 val = ucontrol->value.enumerated.item[0] >= 3 ?
3410 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3417 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3418 struct snd_ctl_elem_info *uinfo)
3420 static char *texts[] = {
3421 "Front", "Surround", "CLFE", "Side"
3423 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3425 uinfo->value.enumerated.items = 4;
3426 if (uinfo->value.enumerated.item >= 4)
3427 uinfo->value.enumerated.item = 3;
3428 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3432 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3433 struct snd_ctl_elem_value *ucontrol)
3435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3436 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3439 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3440 ucontrol->value.enumerated.item[0] = sel & 3;
3444 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3445 struct snd_ctl_elem_value *ucontrol)
3447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3448 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3451 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3452 if (ucontrol->value.enumerated.item[0] != sel) {
3453 sel = ucontrol->value.enumerated.item[0] & 3;
3454 snd_hda_codec_write_cache(codec, nid, 0,
3455 AC_VERB_SET_CONNECT_SEL, sel);
3461 #define PIN_CTL_TEST(xname,nid) { \
3462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3464 .info = alc_test_pin_ctl_info, \
3465 .get = alc_test_pin_ctl_get, \
3466 .put = alc_test_pin_ctl_put, \
3467 .private_value = nid \
3470 #define PIN_SRC_TEST(xname,nid) { \
3471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3473 .info = alc_test_pin_src_info, \
3474 .get = alc_test_pin_src_get, \
3475 .put = alc_test_pin_src_put, \
3476 .private_value = nid \
3479 static struct snd_kcontrol_new alc880_test_mixer[] = {
3480 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3481 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3482 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3483 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3485 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3486 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3487 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3488 PIN_CTL_TEST("Front Pin Mode", 0x14),
3489 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3490 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3491 PIN_CTL_TEST("Side Pin Mode", 0x17),
3492 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3493 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3494 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3495 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3496 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3497 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3498 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3499 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3500 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3501 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3502 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3503 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3504 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3505 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3506 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3507 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3511 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3512 .name = "Channel Mode",
3513 .info = alc_ch_mode_info,
3514 .get = alc_ch_mode_get,
3515 .put = alc_ch_mode_put,
3520 static struct hda_verb alc880_test_init_verbs[] = {
3521 /* Unmute inputs of 0x0c - 0x0f */
3522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3524 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3525 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3526 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3527 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3529 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3530 /* Vol output for 0x0c-0x0f */
3531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3533 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3534 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3535 /* Set output pins 0x14-0x17 */
3536 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3540 /* Unmute output pins 0x14-0x17 */
3541 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3545 /* Set input pins 0x18-0x1c */
3546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3549 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3551 /* Mute input pins 0x18-0x1b */
3552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3553 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3558 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3562 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3563 /* Analog input/passthru */
3564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3568 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3576 static const char *alc880_models[ALC880_MODEL_LAST] = {
3577 [ALC880_3ST] = "3stack",
3578 [ALC880_TCL_S700] = "tcl",
3579 [ALC880_3ST_DIG] = "3stack-digout",
3580 [ALC880_CLEVO] = "clevo",
3581 [ALC880_5ST] = "5stack",
3582 [ALC880_5ST_DIG] = "5stack-digout",
3583 [ALC880_W810] = "w810",
3584 [ALC880_Z71V] = "z71v",
3585 [ALC880_6ST] = "6stack",
3586 [ALC880_6ST_DIG] = "6stack-digout",
3587 [ALC880_ASUS] = "asus",
3588 [ALC880_ASUS_W1V] = "asus-w1v",
3589 [ALC880_ASUS_DIG] = "asus-dig",
3590 [ALC880_ASUS_DIG2] = "asus-dig2",
3591 [ALC880_UNIWILL_DIG] = "uniwill",
3592 [ALC880_UNIWILL_P53] = "uniwill-p53",
3593 [ALC880_FUJITSU] = "fujitsu",
3594 [ALC880_F1734] = "F1734",
3596 [ALC880_LG_LW] = "lg-lw",
3597 [ALC880_MEDION_RIM] = "medion",
3598 #ifdef CONFIG_SND_DEBUG
3599 [ALC880_TEST] = "test",
3601 [ALC880_AUTO] = "auto",
3604 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3605 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3606 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3607 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3608 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3609 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3610 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3611 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3612 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3613 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3614 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3615 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3616 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3617 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3618 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3619 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3620 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3621 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3622 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3623 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3624 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3625 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3626 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3627 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3628 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3629 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3630 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3631 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3632 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3633 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3634 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3635 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3636 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3637 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3638 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3639 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3640 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3641 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3642 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3643 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3644 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3645 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3646 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3647 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3648 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3649 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3650 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3651 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3652 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3653 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3654 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3655 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3656 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3657 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3658 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3659 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3660 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3661 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3662 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3663 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3664 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3665 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3666 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3667 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3668 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3669 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3670 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3671 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3672 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3674 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3675 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3676 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3681 * ALC880 codec presets
3683 static struct alc_config_preset alc880_presets[] = {
3685 .mixers = { alc880_three_stack_mixer },
3686 .init_verbs = { alc880_volume_init_verbs,
3687 alc880_pin_3stack_init_verbs },
3688 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3689 .dac_nids = alc880_dac_nids,
3690 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3691 .channel_mode = alc880_threestack_modes,
3693 .input_mux = &alc880_capture_source,
3695 [ALC880_3ST_DIG] = {
3696 .mixers = { alc880_three_stack_mixer },
3697 .init_verbs = { alc880_volume_init_verbs,
3698 alc880_pin_3stack_init_verbs },
3699 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3700 .dac_nids = alc880_dac_nids,
3701 .dig_out_nid = ALC880_DIGOUT_NID,
3702 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3703 .channel_mode = alc880_threestack_modes,
3705 .input_mux = &alc880_capture_source,
3707 [ALC880_TCL_S700] = {
3708 .mixers = { alc880_tcl_s700_mixer },
3709 .init_verbs = { alc880_volume_init_verbs,
3710 alc880_pin_tcl_S700_init_verbs,
3711 alc880_gpio2_init_verbs },
3712 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3713 .dac_nids = alc880_dac_nids,
3714 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3715 .num_adc_nids = 1, /* single ADC */
3717 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3718 .channel_mode = alc880_2_jack_modes,
3719 .input_mux = &alc880_capture_source,
3722 .mixers = { alc880_three_stack_mixer,
3723 alc880_five_stack_mixer},
3724 .init_verbs = { alc880_volume_init_verbs,
3725 alc880_pin_5stack_init_verbs },
3726 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3727 .dac_nids = alc880_dac_nids,
3728 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3729 .channel_mode = alc880_fivestack_modes,
3730 .input_mux = &alc880_capture_source,
3732 [ALC880_5ST_DIG] = {
3733 .mixers = { alc880_three_stack_mixer,
3734 alc880_five_stack_mixer },
3735 .init_verbs = { alc880_volume_init_verbs,
3736 alc880_pin_5stack_init_verbs },
3737 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3738 .dac_nids = alc880_dac_nids,
3739 .dig_out_nid = ALC880_DIGOUT_NID,
3740 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3741 .channel_mode = alc880_fivestack_modes,
3742 .input_mux = &alc880_capture_source,
3745 .mixers = { alc880_six_stack_mixer },
3746 .init_verbs = { alc880_volume_init_verbs,
3747 alc880_pin_6stack_init_verbs },
3748 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3749 .dac_nids = alc880_6st_dac_nids,
3750 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3751 .channel_mode = alc880_sixstack_modes,
3752 .input_mux = &alc880_6stack_capture_source,
3754 [ALC880_6ST_DIG] = {
3755 .mixers = { alc880_six_stack_mixer },
3756 .init_verbs = { alc880_volume_init_verbs,
3757 alc880_pin_6stack_init_verbs },
3758 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3759 .dac_nids = alc880_6st_dac_nids,
3760 .dig_out_nid = ALC880_DIGOUT_NID,
3761 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3762 .channel_mode = alc880_sixstack_modes,
3763 .input_mux = &alc880_6stack_capture_source,
3766 .mixers = { alc880_w810_base_mixer },
3767 .init_verbs = { alc880_volume_init_verbs,
3768 alc880_pin_w810_init_verbs,
3769 alc880_gpio2_init_verbs },
3770 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3771 .dac_nids = alc880_w810_dac_nids,
3772 .dig_out_nid = ALC880_DIGOUT_NID,
3773 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3774 .channel_mode = alc880_w810_modes,
3775 .input_mux = &alc880_capture_source,
3778 .mixers = { alc880_z71v_mixer },
3779 .init_verbs = { alc880_volume_init_verbs,
3780 alc880_pin_z71v_init_verbs },
3781 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3782 .dac_nids = alc880_z71v_dac_nids,
3783 .dig_out_nid = ALC880_DIGOUT_NID,
3785 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3786 .channel_mode = alc880_2_jack_modes,
3787 .input_mux = &alc880_capture_source,
3790 .mixers = { alc880_f1734_mixer },
3791 .init_verbs = { alc880_volume_init_verbs,
3792 alc880_pin_f1734_init_verbs },
3793 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3794 .dac_nids = alc880_f1734_dac_nids,
3796 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3797 .channel_mode = alc880_2_jack_modes,
3798 .input_mux = &alc880_f1734_capture_source,
3799 .unsol_event = alc880_uniwill_p53_unsol_event,
3800 .init_hook = alc880_uniwill_p53_init_hook,
3803 .mixers = { alc880_asus_mixer },
3804 .init_verbs = { alc880_volume_init_verbs,
3805 alc880_pin_asus_init_verbs,
3806 alc880_gpio1_init_verbs },
3807 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3808 .dac_nids = alc880_asus_dac_nids,
3809 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3810 .channel_mode = alc880_asus_modes,
3812 .input_mux = &alc880_capture_source,
3814 [ALC880_ASUS_DIG] = {
3815 .mixers = { alc880_asus_mixer },
3816 .init_verbs = { alc880_volume_init_verbs,
3817 alc880_pin_asus_init_verbs,
3818 alc880_gpio1_init_verbs },
3819 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3820 .dac_nids = alc880_asus_dac_nids,
3821 .dig_out_nid = ALC880_DIGOUT_NID,
3822 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3823 .channel_mode = alc880_asus_modes,
3825 .input_mux = &alc880_capture_source,
3827 [ALC880_ASUS_DIG2] = {
3828 .mixers = { alc880_asus_mixer },
3829 .init_verbs = { alc880_volume_init_verbs,
3830 alc880_pin_asus_init_verbs,
3831 alc880_gpio2_init_verbs }, /* use GPIO2 */
3832 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3833 .dac_nids = alc880_asus_dac_nids,
3834 .dig_out_nid = ALC880_DIGOUT_NID,
3835 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3836 .channel_mode = alc880_asus_modes,
3838 .input_mux = &alc880_capture_source,
3840 [ALC880_ASUS_W1V] = {
3841 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3842 .init_verbs = { alc880_volume_init_verbs,
3843 alc880_pin_asus_init_verbs,
3844 alc880_gpio1_init_verbs },
3845 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3846 .dac_nids = alc880_asus_dac_nids,
3847 .dig_out_nid = ALC880_DIGOUT_NID,
3848 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3849 .channel_mode = alc880_asus_modes,
3851 .input_mux = &alc880_capture_source,
3853 [ALC880_UNIWILL_DIG] = {
3854 .mixers = { alc880_asus_mixer },
3855 .init_verbs = { alc880_volume_init_verbs,
3856 alc880_pin_asus_init_verbs },
3857 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3858 .dac_nids = alc880_asus_dac_nids,
3859 .dig_out_nid = ALC880_DIGOUT_NID,
3860 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3861 .channel_mode = alc880_asus_modes,
3863 .input_mux = &alc880_capture_source,
3865 [ALC880_UNIWILL] = {
3866 .mixers = { alc880_uniwill_mixer },
3867 .init_verbs = { alc880_volume_init_verbs,
3868 alc880_uniwill_init_verbs },
3869 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3870 .dac_nids = alc880_asus_dac_nids,
3871 .dig_out_nid = ALC880_DIGOUT_NID,
3872 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3873 .channel_mode = alc880_threestack_modes,
3875 .input_mux = &alc880_capture_source,
3876 .unsol_event = alc880_uniwill_unsol_event,
3877 .init_hook = alc880_uniwill_init_hook,
3879 [ALC880_UNIWILL_P53] = {
3880 .mixers = { alc880_uniwill_p53_mixer },
3881 .init_verbs = { alc880_volume_init_verbs,
3882 alc880_uniwill_p53_init_verbs },
3883 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3884 .dac_nids = alc880_asus_dac_nids,
3885 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3886 .channel_mode = alc880_threestack_modes,
3887 .input_mux = &alc880_capture_source,
3888 .unsol_event = alc880_uniwill_p53_unsol_event,
3889 .init_hook = alc880_uniwill_p53_init_hook,
3891 [ALC880_FUJITSU] = {
3892 .mixers = { alc880_fujitsu_mixer },
3893 .init_verbs = { alc880_volume_init_verbs,
3894 alc880_uniwill_p53_init_verbs,
3895 alc880_beep_init_verbs },
3896 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3897 .dac_nids = alc880_dac_nids,
3898 .dig_out_nid = ALC880_DIGOUT_NID,
3899 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3900 .channel_mode = alc880_2_jack_modes,
3901 .input_mux = &alc880_capture_source,
3902 .unsol_event = alc880_uniwill_p53_unsol_event,
3903 .init_hook = alc880_uniwill_p53_init_hook,
3906 .mixers = { alc880_three_stack_mixer },
3907 .init_verbs = { alc880_volume_init_verbs,
3908 alc880_pin_clevo_init_verbs },
3909 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3910 .dac_nids = alc880_dac_nids,
3912 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3913 .channel_mode = alc880_threestack_modes,
3915 .input_mux = &alc880_capture_source,
3918 .mixers = { alc880_lg_mixer },
3919 .init_verbs = { alc880_volume_init_verbs,
3920 alc880_lg_init_verbs },
3921 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3922 .dac_nids = alc880_lg_dac_nids,
3923 .dig_out_nid = ALC880_DIGOUT_NID,
3924 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3925 .channel_mode = alc880_lg_ch_modes,
3927 .input_mux = &alc880_lg_capture_source,
3928 .unsol_event = alc_automute_amp_unsol_event,
3929 .init_hook = alc880_lg_init_hook,
3930 #ifdef CONFIG_SND_HDA_POWER_SAVE
3931 .loopbacks = alc880_lg_loopbacks,
3935 .mixers = { alc880_lg_lw_mixer },
3936 .init_verbs = { alc880_volume_init_verbs,
3937 alc880_lg_lw_init_verbs },
3938 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3939 .dac_nids = alc880_dac_nids,
3940 .dig_out_nid = ALC880_DIGOUT_NID,
3941 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3942 .channel_mode = alc880_lg_lw_modes,
3943 .input_mux = &alc880_lg_lw_capture_source,
3944 .unsol_event = alc_automute_amp_unsol_event,
3945 .init_hook = alc880_lg_lw_init_hook,
3947 [ALC880_MEDION_RIM] = {
3948 .mixers = { alc880_medion_rim_mixer },
3949 .init_verbs = { alc880_volume_init_verbs,
3950 alc880_medion_rim_init_verbs,
3951 alc_gpio2_init_verbs },
3952 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3953 .dac_nids = alc880_dac_nids,
3954 .dig_out_nid = ALC880_DIGOUT_NID,
3955 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3956 .channel_mode = alc880_2_jack_modes,
3957 .input_mux = &alc880_medion_rim_capture_source,
3958 .unsol_event = alc880_medion_rim_unsol_event,
3959 .init_hook = alc880_medion_rim_init_hook,
3961 #ifdef CONFIG_SND_DEBUG
3963 .mixers = { alc880_test_mixer },
3964 .init_verbs = { alc880_test_init_verbs },
3965 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3966 .dac_nids = alc880_test_dac_nids,
3967 .dig_out_nid = ALC880_DIGOUT_NID,
3968 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3969 .channel_mode = alc880_test_modes,
3970 .input_mux = &alc880_test_capture_source,
3976 * Automatic parse of I/O pins from the BIOS configuration
3981 ALC_CTL_WIDGET_MUTE,
3984 static struct snd_kcontrol_new alc880_control_templates[] = {
3985 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3986 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3987 HDA_BIND_MUTE(NULL, 0, 0, 0),
3990 /* add dynamic controls */
3991 static int add_control(struct alc_spec *spec, int type, const char *name,
3994 struct snd_kcontrol_new *knew;
3996 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3997 knew = snd_array_new(&spec->kctls);
4000 *knew = alc880_control_templates[type];
4001 knew->name = kstrdup(name, GFP_KERNEL);
4004 knew->private_value = val;
4008 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4009 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4010 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4011 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4012 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4013 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4014 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4015 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4016 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4017 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4018 #define ALC880_PIN_CD_NID 0x1c
4020 /* fill in the dac_nids table from the parsed pin configuration */
4021 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4022 const struct auto_pin_cfg *cfg)
4028 memset(assigned, 0, sizeof(assigned));
4029 spec->multiout.dac_nids = spec->private_dac_nids;
4031 /* check the pins hardwired to audio widget */
4032 for (i = 0; i < cfg->line_outs; i++) {
4033 nid = cfg->line_out_pins[i];
4034 if (alc880_is_fixed_pin(nid)) {
4035 int idx = alc880_fixed_pin_idx(nid);
4036 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4040 /* left pins can be connect to any audio widget */
4041 for (i = 0; i < cfg->line_outs; i++) {
4042 nid = cfg->line_out_pins[i];
4043 if (alc880_is_fixed_pin(nid))
4045 /* search for an empty channel */
4046 for (j = 0; j < cfg->line_outs; j++) {
4048 spec->multiout.dac_nids[i] =
4049 alc880_idx_to_dac(j);
4055 spec->multiout.num_dacs = cfg->line_outs;
4059 /* add playback controls from the parsed DAC table */
4060 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4061 const struct auto_pin_cfg *cfg)
4064 static const char *chname[4] = {
4065 "Front", "Surround", NULL /*CLFE*/, "Side"
4070 for (i = 0; i < cfg->line_outs; i++) {
4071 if (!spec->multiout.dac_nids[i])
4073 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4076 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4077 "Center Playback Volume",
4078 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4082 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4083 "LFE Playback Volume",
4084 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4088 err = add_control(spec, ALC_CTL_BIND_MUTE,
4089 "Center Playback Switch",
4090 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4094 err = add_control(spec, ALC_CTL_BIND_MUTE,
4095 "LFE Playback Switch",
4096 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4101 sprintf(name, "%s Playback Volume", chname[i]);
4102 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4103 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4107 sprintf(name, "%s Playback Switch", chname[i]);
4108 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4109 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4118 /* add playback controls for speaker and HP outputs */
4119 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4129 if (alc880_is_fixed_pin(pin)) {
4130 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4131 /* specify the DAC as the extra output */
4132 if (!spec->multiout.hp_nid)
4133 spec->multiout.hp_nid = nid;
4135 spec->multiout.extra_out_nid[0] = nid;
4136 /* control HP volume/switch on the output mixer amp */
4137 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4138 sprintf(name, "%s Playback Volume", pfx);
4139 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4140 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4143 sprintf(name, "%s Playback Switch", pfx);
4144 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4145 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4148 } else if (alc880_is_multi_pin(pin)) {
4149 /* set manual connection */
4150 /* we have only a switch on HP-out PIN */
4151 sprintf(name, "%s Playback Switch", pfx);
4152 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4153 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4160 /* create input playback/capture controls for the given pin */
4161 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4162 const char *ctlname,
4163 int idx, hda_nid_t mix_nid)
4168 sprintf(name, "%s Playback Volume", ctlname);
4169 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4170 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4173 sprintf(name, "%s Playback Switch", ctlname);
4174 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4175 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4181 /* create playback/capture controls for input pins */
4182 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4183 const struct auto_pin_cfg *cfg)
4185 struct hda_input_mux *imux = &spec->private_imux[0];
4188 for (i = 0; i < AUTO_PIN_LAST; i++) {
4189 if (alc880_is_input_pin(cfg->input_pins[i])) {
4190 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4191 err = new_analog_input(spec, cfg->input_pins[i],
4192 auto_pin_cfg_labels[i],
4196 imux->items[imux->num_items].label =
4197 auto_pin_cfg_labels[i];
4198 imux->items[imux->num_items].index =
4199 alc880_input_pin_idx(cfg->input_pins[i]);
4206 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4207 unsigned int pin_type)
4209 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4212 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4216 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4217 hda_nid_t nid, int pin_type,
4220 alc_set_pin_output(codec, nid, pin_type);
4221 /* need the manual connection? */
4222 if (alc880_is_multi_pin(nid)) {
4223 struct alc_spec *spec = codec->spec;
4224 int idx = alc880_multi_pin_idx(nid);
4225 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4226 AC_VERB_SET_CONNECT_SEL,
4227 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4231 static int get_pin_type(int line_out_type)
4233 if (line_out_type == AUTO_PIN_HP_OUT)
4239 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4241 struct alc_spec *spec = codec->spec;
4244 for (i = 0; i < spec->autocfg.line_outs; i++) {
4245 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4246 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4247 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4251 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4253 struct alc_spec *spec = codec->spec;
4256 pin = spec->autocfg.speaker_pins[0];
4257 if (pin) /* connect to front */
4258 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4259 pin = spec->autocfg.hp_pins[0];
4260 if (pin) /* connect to front */
4261 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4264 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4266 struct alc_spec *spec = codec->spec;
4269 for (i = 0; i < AUTO_PIN_LAST; i++) {
4270 hda_nid_t nid = spec->autocfg.input_pins[i];
4271 if (alc880_is_input_pin(nid)) {
4272 alc_set_input_pin(codec, nid, i);
4273 if (nid != ALC880_PIN_CD_NID &&
4274 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4275 snd_hda_codec_write(codec, nid, 0,
4276 AC_VERB_SET_AMP_GAIN_MUTE,
4282 /* parse the BIOS configuration and set up the alc_spec */
4283 /* return 1 if successful, 0 if the proper config is not found,
4284 * or a negative error code
4286 static int alc880_parse_auto_config(struct hda_codec *codec)
4288 struct alc_spec *spec = codec->spec;
4290 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4292 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4296 if (!spec->autocfg.line_outs)
4297 return 0; /* can't find valid BIOS pin config */
4299 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4302 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4305 err = alc880_auto_create_extra_out(spec,
4306 spec->autocfg.speaker_pins[0],
4310 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4314 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4318 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4320 /* check multiple SPDIF-out (for recent codecs) */
4321 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4323 err = snd_hda_get_connections(codec,
4324 spec->autocfg.dig_out_pins[i],
4329 spec->multiout.dig_out_nid = dig_nid;
4331 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4332 spec->slave_dig_outs[i - 1] = dig_nid;
4333 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4337 if (spec->autocfg.dig_in_pin)
4338 spec->dig_in_nid = ALC880_DIGIN_NID;
4340 if (spec->kctls.list)
4341 add_mixer(spec, spec->kctls.list);
4343 add_verb(spec, alc880_volume_init_verbs);
4345 spec->num_mux_defs = 1;
4346 spec->input_mux = &spec->private_imux[0];
4348 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4353 /* additional initialization for auto-configuration model */
4354 static void alc880_auto_init(struct hda_codec *codec)
4356 struct alc_spec *spec = codec->spec;
4357 alc880_auto_init_multi_out(codec);
4358 alc880_auto_init_extra_out(codec);
4359 alc880_auto_init_analog_input(codec);
4360 if (spec->unsol_event)
4361 alc_inithook(codec);
4364 static void set_capture_mixer(struct alc_spec *spec)
4366 static struct snd_kcontrol_new *caps[2][3] = {
4367 { alc_capture_mixer_nosrc1,
4368 alc_capture_mixer_nosrc2,
4369 alc_capture_mixer_nosrc3 },
4370 { alc_capture_mixer1,
4372 alc_capture_mixer3 },
4374 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4376 if (spec->input_mux && spec->input_mux->num_items > 1)
4380 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4384 #define set_beep_amp(spec, nid, idx, dir) \
4385 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4388 * OK, here we have finally the patch for ALC880
4391 static int patch_alc880(struct hda_codec *codec)
4393 struct alc_spec *spec;
4397 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4403 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4406 if (board_config < 0) {
4407 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4408 "trying auto-probe from BIOS...\n");
4409 board_config = ALC880_AUTO;
4412 if (board_config == ALC880_AUTO) {
4413 /* automatic parse from the BIOS config */
4414 err = alc880_parse_auto_config(codec);
4420 "hda_codec: Cannot set up configuration "
4421 "from BIOS. Using 3-stack mode...\n");
4422 board_config = ALC880_3ST;
4426 err = snd_hda_attach_beep_device(codec, 0x1);
4432 if (board_config != ALC880_AUTO)
4433 setup_preset(spec, &alc880_presets[board_config]);
4435 spec->stream_name_analog = "ALC880 Analog";
4436 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4437 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4438 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4440 spec->stream_name_digital = "ALC880 Digital";
4441 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4442 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4444 if (!spec->adc_nids && spec->input_mux) {
4445 /* check whether NID 0x07 is valid */
4446 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4448 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4449 if (wcap != AC_WID_AUD_IN) {
4450 spec->adc_nids = alc880_adc_nids_alt;
4451 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4453 spec->adc_nids = alc880_adc_nids;
4454 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4457 set_capture_mixer(spec);
4458 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4460 spec->vmaster_nid = 0x0c;
4462 codec->patch_ops = alc_patch_ops;
4463 if (board_config == ALC880_AUTO)
4464 spec->init_hook = alc880_auto_init;
4465 #ifdef CONFIG_SND_HDA_POWER_SAVE
4466 if (!spec->loopback.amplist)
4467 spec->loopback.amplist = alc880_loopbacks;
4469 codec->proc_widget_hook = print_realtek_coef;
4479 static hda_nid_t alc260_dac_nids[1] = {
4484 static hda_nid_t alc260_adc_nids[1] = {
4489 static hda_nid_t alc260_adc_nids_alt[1] = {
4494 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4495 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4497 static hda_nid_t alc260_dual_adc_nids[2] = {
4502 #define ALC260_DIGOUT_NID 0x03
4503 #define ALC260_DIGIN_NID 0x06
4505 static struct hda_input_mux alc260_capture_source = {
4509 { "Front Mic", 0x1 },
4515 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4516 * headphone jack and the internal CD lines since these are the only pins at
4517 * which audio can appear. For flexibility, also allow the option of
4518 * recording the mixer output on the second ADC (ADC0 doesn't have a
4519 * connection to the mixer output).
4521 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4525 { "Mic/Line", 0x0 },
4527 { "Headphone", 0x2 },
4533 { "Mic/Line", 0x0 },
4535 { "Headphone", 0x2 },
4542 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4543 * the Fujitsu S702x, but jacks are marked differently.
4545 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4552 { "Headphone", 0x5 },
4561 { "Headphone", 0x6 },
4567 /* Maxdata Favorit 100XS */
4568 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4572 { "Line/Mic", 0x0 },
4579 { "Line/Mic", 0x0 },
4587 * This is just place-holder, so there's something for alc_build_pcms to look
4588 * at when it calculates the maximum number of channels. ALC260 has no mixer
4589 * element which allows changing the channel mode, so the verb list is
4592 static struct hda_channel_mode alc260_modes[1] = {
4597 /* Mixer combinations
4599 * basic: base_output + input + pc_beep + capture
4600 * HP: base_output + input + capture_alt
4601 * HP_3013: hp_3013 + input + capture
4602 * fujitsu: fujitsu + capture
4603 * acer: acer + capture
4606 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4607 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4608 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4609 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4610 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4611 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4612 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4616 static struct snd_kcontrol_new alc260_input_mixer[] = {
4617 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4618 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4619 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4620 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4622 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4623 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4624 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4628 /* update HP, line and mono out pins according to the master switch */
4629 static void alc260_hp_master_update(struct hda_codec *codec,
4630 hda_nid_t hp, hda_nid_t line,
4633 struct alc_spec *spec = codec->spec;
4634 unsigned int val = spec->master_sw ? PIN_HP : 0;
4635 /* change HP and line-out pins */
4636 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4638 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4640 /* mono (speaker) depending on the HP jack sense */
4641 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4642 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4646 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4647 struct snd_ctl_elem_value *ucontrol)
4649 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4650 struct alc_spec *spec = codec->spec;
4651 *ucontrol->value.integer.value = spec->master_sw;
4655 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4656 struct snd_ctl_elem_value *ucontrol)
4658 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4659 struct alc_spec *spec = codec->spec;
4660 int val = !!*ucontrol->value.integer.value;
4661 hda_nid_t hp, line, mono;
4663 if (val == spec->master_sw)
4665 spec->master_sw = val;
4666 hp = (kcontrol->private_value >> 16) & 0xff;
4667 line = (kcontrol->private_value >> 8) & 0xff;
4668 mono = kcontrol->private_value & 0xff;
4669 alc260_hp_master_update(codec, hp, line, mono);
4673 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4676 .name = "Master Playback Switch",
4677 .info = snd_ctl_boolean_mono_info,
4678 .get = alc260_hp_master_sw_get,
4679 .put = alc260_hp_master_sw_put,
4680 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4682 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4683 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4685 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4686 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4688 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4692 static struct hda_verb alc260_hp_unsol_verbs[] = {
4693 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4697 static void alc260_hp_automute(struct hda_codec *codec)
4699 struct alc_spec *spec = codec->spec;
4700 unsigned int present;
4702 present = snd_hda_codec_read(codec, 0x10, 0,
4703 AC_VERB_GET_PIN_SENSE, 0);
4704 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4705 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4708 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4710 if ((res >> 26) == ALC880_HP_EVENT)
4711 alc260_hp_automute(codec);
4714 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4717 .name = "Master Playback Switch",
4718 .info = snd_ctl_boolean_mono_info,
4719 .get = alc260_hp_master_sw_get,
4720 .put = alc260_hp_master_sw_put,
4721 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4723 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4724 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4725 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4726 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4727 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4729 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4730 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4734 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4735 .ops = &snd_hda_bind_vol,
4737 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4738 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4739 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4744 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4745 .ops = &snd_hda_bind_sw,
4747 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4748 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4753 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4754 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4755 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4756 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4761 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4762 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4766 static void alc260_hp_3013_automute(struct hda_codec *codec)
4768 struct alc_spec *spec = codec->spec;
4769 unsigned int present;
4771 present = snd_hda_codec_read(codec, 0x15, 0,
4772 AC_VERB_GET_PIN_SENSE, 0);
4773 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4774 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4777 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4780 if ((res >> 26) == ALC880_HP_EVENT)
4781 alc260_hp_3013_automute(codec);
4784 static void alc260_hp_3012_automute(struct hda_codec *codec)
4786 unsigned int present, bits;
4788 present = snd_hda_codec_read(codec, 0x10, 0,
4789 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4791 bits = present ? 0 : PIN_OUT;
4792 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4794 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4796 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4800 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4803 if ((res >> 26) == ALC880_HP_EVENT)
4804 alc260_hp_3012_automute(codec);
4807 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4808 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4810 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4811 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4812 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4813 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4814 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4815 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4816 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4817 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4818 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4819 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4820 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4824 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4825 * versions of the ALC260 don't act on requests to enable mic bias from NID
4826 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4827 * datasheet doesn't mention this restriction. At this stage it's not clear
4828 * whether this behaviour is intentional or is a hardware bug in chip
4829 * revisions available in early 2006. Therefore for now allow the
4830 * "Headphone Jack Mode" control to span all choices, but if it turns out
4831 * that the lack of mic bias for this NID is intentional we could change the
4832 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4834 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4835 * don't appear to make the mic bias available from the "line" jack, even
4836 * though the NID used for this jack (0x14) can supply it. The theory is
4837 * that perhaps Acer have included blocking capacitors between the ALC260
4838 * and the output jack. If this turns out to be the case for all such
4839 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4840 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4842 * The C20x Tablet series have a mono internal speaker which is controlled
4843 * via the chip's Mono sum widget and pin complex, so include the necessary
4844 * controls for such models. On models without a "mono speaker" the control
4845 * won't do anything.
4847 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4848 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4849 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4850 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4851 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4853 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4855 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4856 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4858 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4859 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4860 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4861 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4862 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4866 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4868 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4869 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4870 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4871 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4872 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4873 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4874 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4878 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4879 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4881 static struct snd_kcontrol_new alc260_will_mixer[] = {
4882 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4883 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4885 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4886 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4887 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4888 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4889 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4890 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4891 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4895 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4896 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4898 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4899 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4900 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4902 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4903 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4904 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4905 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4906 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4907 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4908 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4913 * initialization verbs
4915 static struct hda_verb alc260_init_verbs[] = {
4916 /* Line In pin widget for input */
4917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4918 /* CD pin widget for input */
4919 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4920 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4921 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4922 /* Mic2 (front panel) pin widget for input and vref at 80% */
4923 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4924 /* LINE-2 is used for line-out in rear */
4925 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4926 /* select line-out */
4927 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4929 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4931 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4933 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4934 /* mute capture amp left and right */
4935 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4936 /* set connection select to line in (default select for this ADC) */
4937 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4938 /* mute capture amp left and right */
4939 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4940 /* set connection select to line in (default select for this ADC) */
4941 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4942 /* set vol=0 Line-Out mixer amp left and right */
4943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4944 /* unmute pin widget amp left and right (no gain on this amp) */
4945 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4946 /* set vol=0 HP mixer amp left and right */
4947 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4948 /* unmute pin widget amp left and right (no gain on this amp) */
4949 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4950 /* set vol=0 Mono mixer amp left and right */
4951 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4952 /* unmute pin widget amp left and right (no gain on this amp) */
4953 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4954 /* unmute LINE-2 out pin */
4955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4956 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4959 /* mute analog inputs */
4960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4964 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4965 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4966 /* mute Front out path */
4967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4968 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4969 /* mute Headphone out path */
4970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4971 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4972 /* mute Mono out path */
4973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4974 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4978 #if 0 /* should be identical with alc260_init_verbs? */
4979 static struct hda_verb alc260_hp_init_verbs[] = {
4980 /* Headphone and output */
4981 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4983 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4984 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4985 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4986 /* Mic2 (front panel) pin widget for input and vref at 80% */
4987 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4988 /* Line In pin widget for input */
4989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4990 /* Line-2 pin widget for output */
4991 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4992 /* CD pin widget for input */
4993 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4994 /* unmute amp left and right */
4995 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4996 /* set connection select to line in (default select for this ADC) */
4997 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4998 /* unmute Line-Out mixer amp left and right (volume = 0) */
4999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5000 /* mute pin widget amp left and right (no gain on this amp) */
5001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5002 /* unmute HP mixer amp left and right (volume = 0) */
5003 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5004 /* mute pin widget amp left and right (no gain on this amp) */
5005 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5006 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5009 /* mute analog inputs */
5010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5014 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5015 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5016 /* Unmute Front out path */
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5019 /* Unmute Headphone out path */
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5022 /* Unmute Mono out path */
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5029 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5030 /* Line out and output */
5031 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5033 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5034 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5035 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5036 /* Mic2 (front panel) pin widget for input and vref at 80% */
5037 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5038 /* Line In pin widget for input */
5039 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5040 /* Headphone pin widget for output */
5041 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5042 /* CD pin widget for input */
5043 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5044 /* unmute amp left and right */
5045 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5046 /* set connection select to line in (default select for this ADC) */
5047 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5048 /* unmute Line-Out mixer amp left and right (volume = 0) */
5049 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5050 /* mute pin widget amp left and right (no gain on this amp) */
5051 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5052 /* unmute HP mixer amp left and right (volume = 0) */
5053 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5054 /* mute pin widget amp left and right (no gain on this amp) */
5055 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5056 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5059 /* mute analog inputs */
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5065 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5066 /* Unmute Front out path */
5067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5069 /* Unmute Headphone out path */
5070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5072 /* Unmute Mono out path */
5073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5078 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5079 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5080 * audio = 0x16, internal speaker = 0x10.
5082 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5083 /* Disable all GPIOs */
5084 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5085 /* Internal speaker is connected to headphone pin */
5086 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5087 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5088 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5089 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5090 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5091 /* Ensure all other unused pins are disabled and muted. */
5092 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5093 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5094 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5095 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5096 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5097 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5098 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5101 /* Disable digital (SPDIF) pins */
5102 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5103 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5105 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5106 * when acting as an output.
5108 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5110 /* Start with output sum widgets muted and their output gains at min */
5111 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5112 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5113 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5116 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5117 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5118 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5119 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5121 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5122 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5123 /* Unmute Line1 pin widget output buffer since it starts as an output.
5124 * If the pin mode is changed by the user the pin mode control will
5125 * take care of enabling the pin's input/output buffers as needed.
5126 * Therefore there's no need to enable the input buffer at this
5129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5130 /* Unmute input buffer of pin widget used for Line-in (no equiv
5133 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5135 /* Mute capture amp left and right */
5136 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5137 /* Set ADC connection select to match default mixer setting - line
5140 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5142 /* Do the same for the second ADC: mute capture input amp and
5143 * set ADC connection to line in (on mic1 pin)
5145 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5146 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5148 /* Mute all inputs to mixer widget (even unconnected ones) */
5149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5161 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5162 * similar laptops (adapted from Fujitsu init verbs).
5164 static struct hda_verb alc260_acer_init_verbs[] = {
5165 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5166 * the headphone jack. Turn this on and rely on the standard mute
5167 * methods whenever the user wants to turn these outputs off.
5169 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5170 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5171 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5172 /* Internal speaker/Headphone jack is connected to Line-out pin */
5173 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5174 /* Internal microphone/Mic jack is connected to Mic1 pin */
5175 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5176 /* Line In jack is connected to Line1 pin */
5177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5178 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5179 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5180 /* Ensure all other unused pins are disabled and muted. */
5181 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5182 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5183 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5184 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5187 /* Disable digital (SPDIF) pins */
5188 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5189 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5191 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5192 * bus when acting as outputs.
5194 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5195 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5197 /* Start with output sum widgets muted and their output gains at min */
5198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5203 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5204 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5205 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5206 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5208 /* Unmute Line-out pin widget amp left and right
5209 * (no equiv mixer ctrl)
5211 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5212 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5213 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5214 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5215 * inputs. If the pin mode is changed by the user the pin mode control
5216 * will take care of enabling the pin's input/output buffers as needed.
5217 * Therefore there's no need to enable the input buffer at this
5220 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223 /* Mute capture amp left and right */
5224 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5225 /* Set ADC connection select to match default mixer setting - mic
5228 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5230 /* Do similar with the second ADC: mute capture input amp and
5231 * set ADC connection to mic to match ALSA's default state.
5233 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5234 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5236 /* Mute all inputs to mixer widget (even unconnected ones) */
5237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5238 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5239 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5243 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5244 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5249 /* Initialisation sequence for Maxdata Favorit 100XS
5250 * (adapted from Acer init verbs).
5252 static struct hda_verb alc260_favorit100_init_verbs[] = {
5253 /* GPIO 0 enables the output jack.
5254 * Turn this on and rely on the standard mute
5255 * methods whenever the user wants to turn these outputs off.
5257 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5258 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5259 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5260 /* Line/Mic input jack is connected to Mic1 pin */
5261 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5262 /* Ensure all other unused pins are disabled and muted. */
5263 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5264 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5265 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5266 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5267 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5268 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5270 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5272 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273 /* Disable digital (SPDIF) pins */
5274 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5275 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5277 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5278 * bus when acting as outputs.
5280 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5281 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5283 /* Start with output sum widgets muted and their output gains at min */
5284 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5289 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5290 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5291 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5292 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5294 /* Unmute Line-out pin widget amp left and right
5295 * (no equiv mixer ctrl)
5297 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5298 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5299 * inputs. If the pin mode is changed by the user the pin mode control
5300 * will take care of enabling the pin's input/output buffers as needed.
5301 * Therefore there's no need to enable the input buffer at this
5304 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5306 /* Mute capture amp left and right */
5307 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5308 /* Set ADC connection select to match default mixer setting - mic
5311 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5313 /* Do similar with the second ADC: mute capture input amp and
5314 * set ADC connection to mic to match ALSA's default state.
5316 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5317 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5319 /* Mute all inputs to mixer widget (even unconnected ones) */
5320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5332 static struct hda_verb alc260_will_verbs[] = {
5333 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5334 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5335 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5336 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5337 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5338 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5342 static struct hda_verb alc260_replacer_672v_verbs[] = {
5343 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5344 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5345 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5347 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5348 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5349 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5351 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5355 /* toggle speaker-output according to the hp-jack state */
5356 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5358 unsigned int present;
5360 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5361 present = snd_hda_codec_read(codec, 0x0f, 0,
5362 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5364 snd_hda_codec_write_cache(codec, 0x01, 0,
5365 AC_VERB_SET_GPIO_DATA, 1);
5366 snd_hda_codec_write_cache(codec, 0x0f, 0,
5367 AC_VERB_SET_PIN_WIDGET_CONTROL,
5370 snd_hda_codec_write_cache(codec, 0x01, 0,
5371 AC_VERB_SET_GPIO_DATA, 0);
5372 snd_hda_codec_write_cache(codec, 0x0f, 0,
5373 AC_VERB_SET_PIN_WIDGET_CONTROL,
5378 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5381 if ((res >> 26) == ALC880_HP_EVENT)
5382 alc260_replacer_672v_automute(codec);
5385 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5386 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5387 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5388 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5389 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5390 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5391 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5392 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5393 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5394 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5395 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5399 /* Test configuration for debugging, modelled after the ALC880 test
5402 #ifdef CONFIG_SND_DEBUG
5403 static hda_nid_t alc260_test_dac_nids[1] = {
5406 static hda_nid_t alc260_test_adc_nids[2] = {
5409 /* For testing the ALC260, each input MUX needs its own definition since
5410 * the signal assignments are different. This assumes that the first ADC
5413 static struct hda_input_mux alc260_test_capture_sources[2] = {
5417 { "MIC1 pin", 0x0 },
5418 { "MIC2 pin", 0x1 },
5419 { "LINE1 pin", 0x2 },
5420 { "LINE2 pin", 0x3 },
5422 { "LINE-OUT pin", 0x5 },
5423 { "HP-OUT pin", 0x6 },
5429 { "MIC1 pin", 0x0 },
5430 { "MIC2 pin", 0x1 },
5431 { "LINE1 pin", 0x2 },
5432 { "LINE2 pin", 0x3 },
5435 { "LINE-OUT pin", 0x6 },
5436 { "HP-OUT pin", 0x7 },
5440 static struct snd_kcontrol_new alc260_test_mixer[] = {
5441 /* Output driver widgets */
5442 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5443 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5444 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5445 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5446 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5447 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5449 /* Modes for retasking pin widgets
5450 * Note: the ALC260 doesn't seem to act on requests to enable mic
5451 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5452 * mention this restriction. At this stage it's not clear whether
5453 * this behaviour is intentional or is a hardware bug in chip
5454 * revisions available at least up until early 2006. Therefore for
5455 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5456 * choices, but if it turns out that the lack of mic bias for these
5457 * NIDs is intentional we could change their modes from
5458 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5460 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5461 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5462 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5463 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5464 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5465 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5467 /* Loopback mixer controls */
5468 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5469 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5470 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5471 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5472 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5473 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5474 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5475 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5476 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5477 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5478 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5479 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5480 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5481 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5483 /* Controls for GPIO pins, assuming they are configured as outputs */
5484 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5485 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5486 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5487 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5489 /* Switches to allow the digital IO pins to be enabled. The datasheet
5490 * is ambigious as to which NID is which; testing on laptops which
5491 * make this output available should provide clarification.
5493 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5494 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5496 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5497 * this output to turn on an external amplifier.
5499 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5500 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5504 static struct hda_verb alc260_test_init_verbs[] = {
5505 /* Enable all GPIOs as outputs with an initial value of 0 */
5506 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5507 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5508 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5510 /* Enable retasking pins as output, initially without power amp */
5511 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5512 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5514 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5515 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5516 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5518 /* Disable digital (SPDIF) pins initially, but users can enable
5519 * them via a mixer switch. In the case of SPDIF-out, this initverb
5520 * payload also sets the generation to 0, output to be in "consumer"
5521 * PCM format, copyright asserted, no pre-emphasis and no validity
5524 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5525 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5527 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5528 * OUT1 sum bus when acting as an output.
5530 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5531 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5532 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5533 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5535 /* Start with output sum widgets muted and their output gains at min */
5536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5542 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5543 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5544 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5546 /* Unmute retasking pin widget output buffers since the default
5547 * state appears to be output. As the pin mode is changed by the
5548 * user the pin mode control will take care of enabling the pin's
5549 * input/output buffers as needed.
5551 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5552 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5555 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5556 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5557 /* Also unmute the mono-out pin widget */
5558 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5560 /* Mute capture amp left and right */
5561 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5562 /* Set ADC connection select to match default mixer setting (mic1
5565 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5567 /* Do the same for the second ADC: mute capture input amp and
5568 * set ADC connection to mic1 pin
5570 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5571 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5573 /* Mute all inputs to mixer widget (even unconnected ones) */
5574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5587 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5588 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5590 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5591 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5594 * for BIOS auto-configuration
5597 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5598 const char *pfx, int *vol_bits)
5601 unsigned long vol_val, sw_val;
5605 if (nid >= 0x0f && nid < 0x11) {
5606 nid_vol = nid - 0x7;
5607 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5608 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5609 } else if (nid == 0x11) {
5610 nid_vol = nid - 0x7;
5611 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5612 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5613 } else if (nid >= 0x12 && nid <= 0x15) {
5615 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5616 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5620 if (!(*vol_bits & (1 << nid_vol))) {
5621 /* first control for the volume widget */
5622 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5623 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5626 *vol_bits |= (1 << nid_vol);
5628 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5629 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5635 /* add playback controls from the parsed DAC table */
5636 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5637 const struct auto_pin_cfg *cfg)
5643 spec->multiout.num_dacs = 1;
5644 spec->multiout.dac_nids = spec->private_dac_nids;
5645 spec->multiout.dac_nids[0] = 0x02;
5647 nid = cfg->line_out_pins[0];
5649 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5654 nid = cfg->speaker_pins[0];
5656 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5661 nid = cfg->hp_pins[0];
5663 err = alc260_add_playback_controls(spec, nid, "Headphone",
5671 /* create playback/capture controls for input pins */
5672 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5673 const struct auto_pin_cfg *cfg)
5675 struct hda_input_mux *imux = &spec->private_imux[0];
5678 for (i = 0; i < AUTO_PIN_LAST; i++) {
5679 if (cfg->input_pins[i] >= 0x12) {
5680 idx = cfg->input_pins[i] - 0x12;
5681 err = new_analog_input(spec, cfg->input_pins[i],
5682 auto_pin_cfg_labels[i], idx,
5686 imux->items[imux->num_items].label =
5687 auto_pin_cfg_labels[i];
5688 imux->items[imux->num_items].index = idx;
5691 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5692 idx = cfg->input_pins[i] - 0x09;
5693 err = new_analog_input(spec, cfg->input_pins[i],
5694 auto_pin_cfg_labels[i], idx,
5698 imux->items[imux->num_items].label =
5699 auto_pin_cfg_labels[i];
5700 imux->items[imux->num_items].index = idx;
5707 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5708 hda_nid_t nid, int pin_type,
5711 alc_set_pin_output(codec, nid, pin_type);
5712 /* need the manual connection? */
5714 int idx = nid - 0x12;
5715 snd_hda_codec_write(codec, idx + 0x0b, 0,
5716 AC_VERB_SET_CONNECT_SEL, sel_idx);
5720 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5722 struct alc_spec *spec = codec->spec;
5725 nid = spec->autocfg.line_out_pins[0];
5727 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5728 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5731 nid = spec->autocfg.speaker_pins[0];
5733 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5735 nid = spec->autocfg.hp_pins[0];
5737 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5740 #define ALC260_PIN_CD_NID 0x16
5741 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5743 struct alc_spec *spec = codec->spec;
5746 for (i = 0; i < AUTO_PIN_LAST; i++) {
5747 hda_nid_t nid = spec->autocfg.input_pins[i];
5749 alc_set_input_pin(codec, nid, i);
5750 if (nid != ALC260_PIN_CD_NID &&
5751 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5752 snd_hda_codec_write(codec, nid, 0,
5753 AC_VERB_SET_AMP_GAIN_MUTE,
5760 * generic initialization of ADC, input mixers and output mixers
5762 static struct hda_verb alc260_volume_init_verbs[] = {
5764 * Unmute ADC0-1 and set the default input to mic-in
5766 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5767 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5768 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5769 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5771 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5773 * Note: PASD motherboards uses the Line In 2 as the input for
5774 * front panel mic (mic 2)
5776 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5777 /* mute analog inputs */
5778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5785 * Set up output mixers (0x08 - 0x0a)
5787 /* set vol=0 to output mixers */
5788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5790 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5791 /* set up input amps for analog loopback */
5792 /* Amp Indices: DAC = 0, mixer = 1 */
5793 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5794 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5795 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5796 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5798 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5803 static int alc260_parse_auto_config(struct hda_codec *codec)
5805 struct alc_spec *spec = codec->spec;
5807 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5809 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5813 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5816 if (!spec->kctls.list)
5817 return 0; /* can't find valid BIOS pin config */
5818 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5822 spec->multiout.max_channels = 2;
5824 if (spec->autocfg.dig_outs)
5825 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5826 if (spec->kctls.list)
5827 add_mixer(spec, spec->kctls.list);
5829 add_verb(spec, alc260_volume_init_verbs);
5831 spec->num_mux_defs = 1;
5832 spec->input_mux = &spec->private_imux[0];
5834 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5839 /* additional initialization for auto-configuration model */
5840 static void alc260_auto_init(struct hda_codec *codec)
5842 struct alc_spec *spec = codec->spec;
5843 alc260_auto_init_multi_out(codec);
5844 alc260_auto_init_analog_input(codec);
5845 if (spec->unsol_event)
5846 alc_inithook(codec);
5849 #ifdef CONFIG_SND_HDA_POWER_SAVE
5850 static struct hda_amp_list alc260_loopbacks[] = {
5851 { 0x07, HDA_INPUT, 0 },
5852 { 0x07, HDA_INPUT, 1 },
5853 { 0x07, HDA_INPUT, 2 },
5854 { 0x07, HDA_INPUT, 3 },
5855 { 0x07, HDA_INPUT, 4 },
5861 * ALC260 configurations
5863 static const char *alc260_models[ALC260_MODEL_LAST] = {
5864 [ALC260_BASIC] = "basic",
5866 [ALC260_HP_3013] = "hp-3013",
5867 [ALC260_HP_DC7600] = "hp-dc7600",
5868 [ALC260_FUJITSU_S702X] = "fujitsu",
5869 [ALC260_ACER] = "acer",
5870 [ALC260_WILL] = "will",
5871 [ALC260_REPLACER_672V] = "replacer",
5872 [ALC260_FAVORIT100] = "favorit100",
5873 #ifdef CONFIG_SND_DEBUG
5874 [ALC260_TEST] = "test",
5876 [ALC260_AUTO] = "auto",
5879 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5880 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5881 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5882 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5883 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5884 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5885 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5886 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5887 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5888 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5889 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5890 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5891 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5892 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5893 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5894 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5895 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5896 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5897 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5898 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5902 static struct alc_config_preset alc260_presets[] = {
5904 .mixers = { alc260_base_output_mixer,
5905 alc260_input_mixer },
5906 .init_verbs = { alc260_init_verbs },
5907 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5908 .dac_nids = alc260_dac_nids,
5909 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5910 .adc_nids = alc260_adc_nids,
5911 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5912 .channel_mode = alc260_modes,
5913 .input_mux = &alc260_capture_source,
5916 .mixers = { alc260_hp_output_mixer,
5917 alc260_input_mixer },
5918 .init_verbs = { alc260_init_verbs,
5919 alc260_hp_unsol_verbs },
5920 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5921 .dac_nids = alc260_dac_nids,
5922 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5923 .adc_nids = alc260_adc_nids_alt,
5924 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5925 .channel_mode = alc260_modes,
5926 .input_mux = &alc260_capture_source,
5927 .unsol_event = alc260_hp_unsol_event,
5928 .init_hook = alc260_hp_automute,
5930 [ALC260_HP_DC7600] = {
5931 .mixers = { alc260_hp_dc7600_mixer,
5932 alc260_input_mixer },
5933 .init_verbs = { alc260_init_verbs,
5934 alc260_hp_dc7600_verbs },
5935 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5936 .dac_nids = alc260_dac_nids,
5937 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5938 .adc_nids = alc260_adc_nids_alt,
5939 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5940 .channel_mode = alc260_modes,
5941 .input_mux = &alc260_capture_source,
5942 .unsol_event = alc260_hp_3012_unsol_event,
5943 .init_hook = alc260_hp_3012_automute,
5945 [ALC260_HP_3013] = {
5946 .mixers = { alc260_hp_3013_mixer,
5947 alc260_input_mixer },
5948 .init_verbs = { alc260_hp_3013_init_verbs,
5949 alc260_hp_3013_unsol_verbs },
5950 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5951 .dac_nids = alc260_dac_nids,
5952 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5953 .adc_nids = alc260_adc_nids_alt,
5954 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5955 .channel_mode = alc260_modes,
5956 .input_mux = &alc260_capture_source,
5957 .unsol_event = alc260_hp_3013_unsol_event,
5958 .init_hook = alc260_hp_3013_automute,
5960 [ALC260_FUJITSU_S702X] = {
5961 .mixers = { alc260_fujitsu_mixer },
5962 .init_verbs = { alc260_fujitsu_init_verbs },
5963 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5964 .dac_nids = alc260_dac_nids,
5965 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5966 .adc_nids = alc260_dual_adc_nids,
5967 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5968 .channel_mode = alc260_modes,
5969 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5970 .input_mux = alc260_fujitsu_capture_sources,
5973 .mixers = { alc260_acer_mixer },
5974 .init_verbs = { alc260_acer_init_verbs },
5975 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5976 .dac_nids = alc260_dac_nids,
5977 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5978 .adc_nids = alc260_dual_adc_nids,
5979 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5980 .channel_mode = alc260_modes,
5981 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5982 .input_mux = alc260_acer_capture_sources,
5984 [ALC260_FAVORIT100] = {
5985 .mixers = { alc260_favorit100_mixer },
5986 .init_verbs = { alc260_favorit100_init_verbs },
5987 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5988 .dac_nids = alc260_dac_nids,
5989 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5990 .adc_nids = alc260_dual_adc_nids,
5991 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5992 .channel_mode = alc260_modes,
5993 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5994 .input_mux = alc260_favorit100_capture_sources,
5997 .mixers = { alc260_will_mixer },
5998 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5999 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6000 .dac_nids = alc260_dac_nids,
6001 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6002 .adc_nids = alc260_adc_nids,
6003 .dig_out_nid = ALC260_DIGOUT_NID,
6004 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6005 .channel_mode = alc260_modes,
6006 .input_mux = &alc260_capture_source,
6008 [ALC260_REPLACER_672V] = {
6009 .mixers = { alc260_replacer_672v_mixer },
6010 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6011 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6012 .dac_nids = alc260_dac_nids,
6013 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6014 .adc_nids = alc260_adc_nids,
6015 .dig_out_nid = ALC260_DIGOUT_NID,
6016 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6017 .channel_mode = alc260_modes,
6018 .input_mux = &alc260_capture_source,
6019 .unsol_event = alc260_replacer_672v_unsol_event,
6020 .init_hook = alc260_replacer_672v_automute,
6022 #ifdef CONFIG_SND_DEBUG
6024 .mixers = { alc260_test_mixer },
6025 .init_verbs = { alc260_test_init_verbs },
6026 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6027 .dac_nids = alc260_test_dac_nids,
6028 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6029 .adc_nids = alc260_test_adc_nids,
6030 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6031 .channel_mode = alc260_modes,
6032 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6033 .input_mux = alc260_test_capture_sources,
6038 static int patch_alc260(struct hda_codec *codec)
6040 struct alc_spec *spec;
6041 int err, board_config;
6043 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6049 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6052 if (board_config < 0) {
6053 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6054 "trying auto-probe from BIOS...\n");
6055 board_config = ALC260_AUTO;
6058 if (board_config == ALC260_AUTO) {
6059 /* automatic parse from the BIOS config */
6060 err = alc260_parse_auto_config(codec);
6066 "hda_codec: Cannot set up configuration "
6067 "from BIOS. Using base mode...\n");
6068 board_config = ALC260_BASIC;
6072 err = snd_hda_attach_beep_device(codec, 0x1);
6078 if (board_config != ALC260_AUTO)
6079 setup_preset(spec, &alc260_presets[board_config]);
6081 spec->stream_name_analog = "ALC260 Analog";
6082 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6083 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6085 spec->stream_name_digital = "ALC260 Digital";
6086 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6087 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6089 if (!spec->adc_nids && spec->input_mux) {
6090 /* check whether NID 0x04 is valid */
6091 unsigned int wcap = get_wcaps(codec, 0x04);
6092 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6094 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6095 spec->adc_nids = alc260_adc_nids_alt;
6096 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6098 spec->adc_nids = alc260_adc_nids;
6099 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6102 set_capture_mixer(spec);
6103 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6105 spec->vmaster_nid = 0x08;
6107 codec->patch_ops = alc_patch_ops;
6108 if (board_config == ALC260_AUTO)
6109 spec->init_hook = alc260_auto_init;
6110 #ifdef CONFIG_SND_HDA_POWER_SAVE
6111 if (!spec->loopback.amplist)
6112 spec->loopback.amplist = alc260_loopbacks;
6114 codec->proc_widget_hook = print_realtek_coef;
6123 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6124 * configuration. Each pin widget can choose any input DACs and a mixer.
6125 * Each ADC is connected from a mixer of all inputs. This makes possible
6126 * 6-channel independent captures.
6128 * In addition, an independent DAC for the multi-playback (not used in this
6131 #define ALC882_DIGOUT_NID 0x06
6132 #define ALC882_DIGIN_NID 0x0a
6134 static struct hda_channel_mode alc882_ch_modes[1] = {
6138 static hda_nid_t alc882_dac_nids[4] = {
6139 /* front, rear, clfe, rear_surr */
6140 0x02, 0x03, 0x04, 0x05
6143 /* identical with ALC880 */
6144 #define alc882_adc_nids alc880_adc_nids
6145 #define alc882_adc_nids_alt alc880_adc_nids_alt
6147 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6148 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6151 /* FIXME: should be a matrix-type input source selection */
6153 static struct hda_input_mux alc882_capture_source = {
6157 { "Front Mic", 0x1 },
6163 static struct hda_input_mux mb5_capture_source = {
6175 static struct hda_verb alc882_3ST_ch2_init[] = {
6176 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6177 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6178 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6179 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6186 static struct hda_verb alc882_3ST_ch6_init[] = {
6187 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6188 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6189 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6190 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6191 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6192 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6196 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6197 { 2, alc882_3ST_ch2_init },
6198 { 6, alc882_3ST_ch6_init },
6204 static struct hda_verb alc882_sixstack_ch6_init[] = {
6205 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6206 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6207 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6208 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6215 static struct hda_verb alc882_sixstack_ch8_init[] = {
6216 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6217 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6218 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6219 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6223 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6224 { 6, alc882_sixstack_ch6_init },
6225 { 8, alc882_sixstack_ch8_init },
6229 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6235 static struct hda_verb alc885_mbp_ch2_init[] = {
6236 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6237 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6238 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6245 static struct hda_verb alc885_mbp_ch6_init[] = {
6246 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6247 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6248 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6249 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6250 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6254 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6255 { 2, alc885_mbp_ch2_init },
6256 { 6, alc885_mbp_ch6_init },
6260 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6261 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6263 static struct snd_kcontrol_new alc882_base_mixer[] = {
6264 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6265 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6266 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6267 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6268 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6269 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6270 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6271 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6272 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6273 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6275 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6276 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6280 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6284 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6288 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6289 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6290 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6291 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6292 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6293 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6294 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6296 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6297 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6302 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6303 HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6304 HDA_BIND_MUTE ("Front Playback Switch", 0x0d, 0x02, HDA_INPUT),
6305 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6306 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
6307 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6308 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6309 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6310 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6311 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6312 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6315 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6316 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6317 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6318 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6319 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6320 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6321 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6323 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6328 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6329 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6330 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6331 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6332 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6333 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6334 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6335 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6338 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6339 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6340 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6341 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6345 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6346 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6348 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6349 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6350 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6352 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6353 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6354 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6355 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6356 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6357 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6358 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6361 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6365 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6366 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6367 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6368 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6369 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6370 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6374 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6379 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6382 .name = "Channel Mode",
6383 .info = alc_ch_mode_info,
6384 .get = alc_ch_mode_get,
6385 .put = alc_ch_mode_put,
6390 static struct hda_verb alc882_init_verbs[] = {
6391 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6398 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6402 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6408 /* Front Pin: output 0 (0x0c) */
6409 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6410 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6411 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6412 /* Rear Pin: output 1 (0x0d) */
6413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6414 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6415 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6416 /* CLFE Pin: output 2 (0x0e) */
6417 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6418 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6419 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6420 /* Side Pin: output 3 (0x0f) */
6421 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6422 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6423 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6424 /* Mic (rear) pin: input vref at 80% */
6425 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6426 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6427 /* Front Mic pin: input vref at 80% */
6428 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6429 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6430 /* Line In pin: input */
6431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6432 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6433 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6434 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6435 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6436 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6437 /* CD pin widget for input */
6438 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6440 /* FIXME: use matrix-type input source selection */
6441 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6442 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6457 /* ADC1: mute amp left and right */
6458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6459 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6460 /* ADC2: mute amp left and right */
6461 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6462 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6463 /* ADC3: mute amp left and right */
6464 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6470 static struct hda_verb alc882_eapd_verbs[] = {
6471 /* change to EAPD mode */
6472 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6473 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6478 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6479 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6480 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6481 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6484 /* FIXME: this looks suspicious...
6485 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6486 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6491 static struct hda_verb alc882_macpro_init_verbs[] = {
6492 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6496 /* Front Pin: output 0 (0x0c) */
6497 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6499 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6500 /* Front Mic pin: input vref at 80% */
6501 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6502 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6503 /* Speaker: output */
6504 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6505 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6506 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6507 /* Headphone output (output 0 - 0x0c) */
6508 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6510 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6512 /* FIXME: use matrix-type input source selection */
6513 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6514 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6529 /* ADC1: mute amp left and right */
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6531 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6532 /* ADC2: mute amp left and right */
6533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6534 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6535 /* ADC3: mute amp left and right */
6536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6537 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6543 static struct hda_verb alc885_mb5_init_verbs[] = {
6545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6546 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6547 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6552 /* Front Pin: output 0 (0x0d) */
6553 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6555 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},
6556 /* HP Pin: output 0 (0x0c) */
6557 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6558 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6559 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6560 /* Front Mic pin: input vref at 80% */
6561 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6570 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6574 /* Macbook Pro rev3 */
6575 static struct hda_verb alc885_mbp3_init_verbs[] = {
6576 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6584 /* Front Pin: output 0 (0x0c) */
6585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6588 /* HP Pin: output 0 (0x0d) */
6589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6593 /* Mic (rear) pin: input vref at 80% */
6594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6596 /* Front Mic pin: input vref at 80% */
6597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6599 /* Line In pin: use output 1 when in LineOut mode */
6600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6602 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6604 /* FIXME: use matrix-type input source selection */
6605 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6606 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6621 /* ADC1: mute amp left and right */
6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6623 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6624 /* ADC2: mute amp left and right */
6625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6626 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6627 /* ADC3: mute amp left and right */
6628 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6629 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6634 /* iMac 24 mixer. */
6635 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6636 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6637 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6641 /* iMac 24 init verbs. */
6642 static struct hda_verb alc885_imac24_init_verbs[] = {
6643 /* Internal speakers: output 0 (0x0c) */
6644 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6645 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6646 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6647 /* Internal speakers: output 0 (0x0c) */
6648 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6650 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6651 /* Headphone: output 0 (0x0c) */
6652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6653 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6654 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6655 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6656 /* Front Mic: input vref at 80% */
6657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6662 /* Toggle speaker-output according to the hp-jack state */
6663 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6665 struct alc_spec *spec = codec->spec;
6667 spec->autocfg.hp_pins[0] = 0x14;
6668 spec->autocfg.speaker_pins[0] = 0x18;
6669 spec->autocfg.speaker_pins[1] = 0x1a;
6670 alc_automute_amp(codec);
6673 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6675 struct alc_spec *spec = codec->spec;
6677 spec->autocfg.hp_pins[0] = 0x15;
6678 spec->autocfg.speaker_pins[0] = 0x14;
6679 alc_automute_amp(codec);
6683 static struct hda_verb alc882_targa_verbs[] = {
6684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6687 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6688 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6690 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6691 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6692 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6694 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6695 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6696 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6697 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6701 /* toggle speaker-output according to the hp-jack state */
6702 static void alc882_targa_automute(struct hda_codec *codec)
6704 struct alc_spec *spec = codec->spec;
6705 alc_automute_amp(codec);
6706 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6707 spec->jack_present ? 1 : 3);
6710 static void alc882_targa_init_hook(struct hda_codec *codec)
6712 struct alc_spec *spec = codec->spec;
6714 spec->autocfg.hp_pins[0] = 0x14;
6715 spec->autocfg.speaker_pins[0] = 0x1b;
6716 alc882_targa_automute(codec);
6719 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6721 if ((res >> 26) == ALC880_HP_EVENT)
6722 alc882_targa_automute(codec);
6725 static struct hda_verb alc882_asus_a7j_verbs[] = {
6726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6729 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6731 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6733 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6734 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6735 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6737 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6738 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6739 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6743 static struct hda_verb alc882_asus_a7m_verbs[] = {
6744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6751 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6752 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6753 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6755 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6756 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6757 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6761 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6763 unsigned int gpiostate, gpiomask, gpiodir;
6765 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6766 AC_VERB_GET_GPIO_DATA, 0);
6769 gpiostate |= (1 << pin);
6771 gpiostate &= ~(1 << pin);
6773 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6774 AC_VERB_GET_GPIO_MASK, 0);
6775 gpiomask |= (1 << pin);
6777 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6778 AC_VERB_GET_GPIO_DIRECTION, 0);
6779 gpiodir |= (1 << pin);
6782 snd_hda_codec_write(codec, codec->afg, 0,
6783 AC_VERB_SET_GPIO_MASK, gpiomask);
6784 snd_hda_codec_write(codec, codec->afg, 0,
6785 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6789 snd_hda_codec_write(codec, codec->afg, 0,
6790 AC_VERB_SET_GPIO_DATA, gpiostate);
6793 /* set up GPIO at initialization */
6794 static void alc885_macpro_init_hook(struct hda_codec *codec)
6796 alc882_gpio_mute(codec, 0, 0);
6797 alc882_gpio_mute(codec, 1, 0);
6800 /* set up GPIO and update auto-muting at initialization */
6801 static void alc885_imac24_init_hook(struct hda_codec *codec)
6803 alc885_macpro_init_hook(codec);
6804 alc885_imac24_automute_init_hook(codec);
6808 * generic initialization of ADC, input mixers and output mixers
6810 static struct hda_verb alc882_auto_init_verbs[] = {
6812 * Unmute ADC0-2 and set the default input to mic-in
6814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6816 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6818 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6821 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6823 * Note: PASD motherboards uses the Line In 2 as the input for
6824 * front panel mic (mic 2)
6826 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6834 * Set up output mixers (0x0c - 0x0f)
6836 /* set vol=0 to output mixers */
6837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6840 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6841 /* set up input amps for analog loopback */
6842 /* Amp Indices: DAC = 0, mixer = 1 */
6843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6846 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6848 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6851 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6852 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6854 /* FIXME: use matrix-type input source selection */
6855 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6856 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6857 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6858 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6859 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6860 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6863 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6864 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6865 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6867 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6868 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6869 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6870 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6875 #ifdef CONFIG_SND_HDA_POWER_SAVE
6876 #define alc882_loopbacks alc880_loopbacks
6879 /* pcm configuration: identiacal with ALC880 */
6880 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6881 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6882 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6883 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6886 * configuration and preset
6888 static const char *alc882_models[ALC882_MODEL_LAST] = {
6889 [ALC882_3ST_DIG] = "3stack-dig",
6890 [ALC882_6ST_DIG] = "6stack-dig",
6891 [ALC882_ARIMA] = "arima",
6892 [ALC882_W2JC] = "w2jc",
6893 [ALC882_TARGA] = "targa",
6894 [ALC882_ASUS_A7J] = "asus-a7j",
6895 [ALC882_ASUS_A7M] = "asus-a7m",
6896 [ALC885_MACPRO] = "macpro",
6897 [ALC885_MB5] = "mb5",
6898 [ALC885_MBP3] = "mbp3",
6899 [ALC885_IMAC24] = "imac24",
6900 [ALC882_AUTO] = "auto",
6903 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6904 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6905 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6906 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6907 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6908 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6909 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6910 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6911 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6912 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6913 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6914 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6915 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6919 static struct alc_config_preset alc882_presets[] = {
6920 [ALC882_3ST_DIG] = {
6921 .mixers = { alc882_base_mixer },
6922 .init_verbs = { alc882_init_verbs },
6923 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6924 .dac_nids = alc882_dac_nids,
6925 .dig_out_nid = ALC882_DIGOUT_NID,
6926 .dig_in_nid = ALC882_DIGIN_NID,
6927 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6928 .channel_mode = alc882_ch_modes,
6930 .input_mux = &alc882_capture_source,
6932 [ALC882_6ST_DIG] = {
6933 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6934 .init_verbs = { alc882_init_verbs },
6935 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6936 .dac_nids = alc882_dac_nids,
6937 .dig_out_nid = ALC882_DIGOUT_NID,
6938 .dig_in_nid = ALC882_DIGIN_NID,
6939 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6940 .channel_mode = alc882_sixstack_modes,
6941 .input_mux = &alc882_capture_source,
6944 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6945 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6946 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6947 .dac_nids = alc882_dac_nids,
6948 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6949 .channel_mode = alc882_sixstack_modes,
6950 .input_mux = &alc882_capture_source,
6953 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6954 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6955 alc880_gpio1_init_verbs },
6956 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6957 .dac_nids = alc882_dac_nids,
6958 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6959 .channel_mode = alc880_threestack_modes,
6961 .input_mux = &alc882_capture_source,
6962 .dig_out_nid = ALC882_DIGOUT_NID,
6965 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6966 .init_verbs = { alc885_mbp3_init_verbs,
6967 alc880_gpio1_init_verbs },
6968 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6969 .dac_nids = alc882_dac_nids,
6970 .channel_mode = alc885_mbp_6ch_modes,
6971 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6972 .input_mux = &alc882_capture_source,
6973 .dig_out_nid = ALC882_DIGOUT_NID,
6974 .dig_in_nid = ALC882_DIGIN_NID,
6975 .unsol_event = alc_automute_amp_unsol_event,
6976 .init_hook = alc885_mbp3_init_hook,
6979 .mixers = { alc885_mb5_mixer },
6980 .init_verbs = { alc885_mb5_init_verbs,
6981 alc880_gpio1_init_verbs },
6982 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6983 .dac_nids = alc882_dac_nids,
6984 .channel_mode = alc885_mbp_6ch_modes,
6985 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6986 .input_mux = &mb5_capture_source,
6987 .dig_out_nid = ALC882_DIGOUT_NID,
6988 .dig_in_nid = ALC882_DIGIN_NID,
6991 .mixers = { alc882_macpro_mixer },
6992 .init_verbs = { alc882_macpro_init_verbs },
6993 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6994 .dac_nids = alc882_dac_nids,
6995 .dig_out_nid = ALC882_DIGOUT_NID,
6996 .dig_in_nid = ALC882_DIGIN_NID,
6997 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6998 .channel_mode = alc882_ch_modes,
6999 .input_mux = &alc882_capture_source,
7000 .init_hook = alc885_macpro_init_hook,
7003 .mixers = { alc885_imac24_mixer },
7004 .init_verbs = { alc885_imac24_init_verbs },
7005 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7006 .dac_nids = alc882_dac_nids,
7007 .dig_out_nid = ALC882_DIGOUT_NID,
7008 .dig_in_nid = ALC882_DIGIN_NID,
7009 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7010 .channel_mode = alc882_ch_modes,
7011 .input_mux = &alc882_capture_source,
7012 .unsol_event = alc_automute_amp_unsol_event,
7013 .init_hook = alc885_imac24_init_hook,
7016 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7017 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7018 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7019 .dac_nids = alc882_dac_nids,
7020 .dig_out_nid = ALC882_DIGOUT_NID,
7021 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7022 .adc_nids = alc882_adc_nids,
7023 .capsrc_nids = alc882_capsrc_nids,
7024 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7025 .channel_mode = alc882_3ST_6ch_modes,
7027 .input_mux = &alc882_capture_source,
7028 .unsol_event = alc882_targa_unsol_event,
7029 .init_hook = alc882_targa_init_hook,
7031 [ALC882_ASUS_A7J] = {
7032 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7033 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7034 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7035 .dac_nids = alc882_dac_nids,
7036 .dig_out_nid = ALC882_DIGOUT_NID,
7037 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7038 .adc_nids = alc882_adc_nids,
7039 .capsrc_nids = alc882_capsrc_nids,
7040 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7041 .channel_mode = alc882_3ST_6ch_modes,
7043 .input_mux = &alc882_capture_source,
7045 [ALC882_ASUS_A7M] = {
7046 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7047 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7048 alc880_gpio1_init_verbs,
7049 alc882_asus_a7m_verbs },
7050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7051 .dac_nids = alc882_dac_nids,
7052 .dig_out_nid = ALC882_DIGOUT_NID,
7053 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7054 .channel_mode = alc880_threestack_modes,
7056 .input_mux = &alc882_capture_source,
7065 PINFIX_ABIT_AW9D_MAX
7068 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7069 { 0x15, 0x01080104 }, /* side */
7070 { 0x16, 0x01011012 }, /* rear */
7071 { 0x17, 0x01016011 }, /* clfe */
7075 static const struct alc_pincfg *alc882_pin_fixes[] = {
7076 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7079 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7080 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7085 * BIOS auto configuration
7087 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7088 hda_nid_t nid, int pin_type,
7092 struct alc_spec *spec = codec->spec;
7095 alc_set_pin_output(codec, nid, pin_type);
7096 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7099 idx = spec->multiout.dac_nids[dac_idx] - 2;
7100 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7104 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7106 struct alc_spec *spec = codec->spec;
7109 for (i = 0; i <= HDA_SIDE; i++) {
7110 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7111 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7113 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7118 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7120 struct alc_spec *spec = codec->spec;
7123 pin = spec->autocfg.hp_pins[0];
7124 if (pin) /* connect to front */
7126 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7127 pin = spec->autocfg.speaker_pins[0];
7129 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7132 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7133 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7135 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7137 struct alc_spec *spec = codec->spec;
7140 for (i = 0; i < AUTO_PIN_LAST; i++) {
7141 hda_nid_t nid = spec->autocfg.input_pins[i];
7144 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7145 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7146 snd_hda_codec_write(codec, nid, 0,
7147 AC_VERB_SET_AMP_GAIN_MUTE,
7152 static void alc882_auto_init_input_src(struct hda_codec *codec)
7154 struct alc_spec *spec = codec->spec;
7157 for (c = 0; c < spec->num_adc_nids; c++) {
7158 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7159 hda_nid_t nid = spec->capsrc_nids[c];
7160 unsigned int mux_idx;
7161 const struct hda_input_mux *imux;
7162 int conns, mute, idx, item;
7164 conns = snd_hda_get_connections(codec, nid, conn_list,
7165 ARRAY_SIZE(conn_list));
7168 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7169 imux = &spec->input_mux[mux_idx];
7170 for (idx = 0; idx < conns; idx++) {
7171 /* if the current connection is the selected one,
7172 * unmute it as default - otherwise mute it
7174 mute = AMP_IN_MUTE(idx);
7175 for (item = 0; item < imux->num_items; item++) {
7176 if (imux->items[item].index == idx) {
7177 if (spec->cur_mux[c] == item)
7178 mute = AMP_IN_UNMUTE(idx);
7182 /* check if we have a selector or mixer
7183 * we could check for the widget type instead, but
7184 * just check for Amp-In presence (in case of mixer
7185 * without amp-in there is something wrong, this
7186 * function shouldn't be used or capsrc nid is wrong)
7188 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7189 snd_hda_codec_write(codec, nid, 0,
7190 AC_VERB_SET_AMP_GAIN_MUTE,
7192 else if (mute != AMP_IN_MUTE(idx))
7193 snd_hda_codec_write(codec, nid, 0,
7194 AC_VERB_SET_CONNECT_SEL,
7200 /* add mic boosts if needed */
7201 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7203 struct alc_spec *spec = codec->spec;
7207 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7208 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7209 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7211 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7215 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7216 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7217 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7219 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7226 /* almost identical with ALC880 parser... */
7227 static int alc882_parse_auto_config(struct hda_codec *codec)
7229 struct alc_spec *spec = codec->spec;
7230 int err = alc880_parse_auto_config(codec);
7235 return 0; /* no config found */
7237 err = alc_auto_add_mic_boost(codec);
7241 /* hack - override the init verbs */
7242 spec->init_verbs[0] = alc882_auto_init_verbs;
7244 return 1; /* config found */
7247 /* additional initialization for auto-configuration model */
7248 static void alc882_auto_init(struct hda_codec *codec)
7250 struct alc_spec *spec = codec->spec;
7251 alc882_auto_init_multi_out(codec);
7252 alc882_auto_init_hp_out(codec);
7253 alc882_auto_init_analog_input(codec);
7254 alc882_auto_init_input_src(codec);
7255 if (spec->unsol_event)
7256 alc_inithook(codec);
7259 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7261 static int patch_alc882(struct hda_codec *codec)
7263 struct alc_spec *spec;
7264 int err, board_config;
7266 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7272 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7276 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7277 /* Pick up systems that don't supply PCI SSID */
7278 switch (codec->subsystem_id) {
7279 case 0x106b0c00: /* Mac Pro */
7280 board_config = ALC885_MACPRO;
7282 case 0x106b1000: /* iMac 24 */
7283 case 0x106b2800: /* AppleTV */
7284 case 0x106b3e00: /* iMac 24 Aluminium */
7285 board_config = ALC885_IMAC24;
7287 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7288 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7289 case 0x106b00a4: /* MacbookPro4,1 */
7290 case 0x106b2c00: /* Macbook Pro rev3 */
7291 case 0x106b3600: /* Macbook 3.1 */
7292 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7293 board_config = ALC885_MBP3;
7295 case 0x106b3f00: /* Macbook 5,1 */
7296 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7297 * seems not working, so apparently
7298 * no perfect solution yet
7300 board_config = ALC885_MB5;
7303 /* ALC889A is handled better as ALC888-compatible */
7304 if (codec->revision_id == 0x100101 ||
7305 codec->revision_id == 0x100103) {
7307 return patch_alc883(codec);
7309 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7310 "trying auto-probe from BIOS...\n");
7311 board_config = ALC882_AUTO;
7315 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7317 if (board_config == ALC882_AUTO) {
7318 /* automatic parse from the BIOS config */
7319 err = alc882_parse_auto_config(codec);
7325 "hda_codec: Cannot set up configuration "
7326 "from BIOS. Using base mode...\n");
7327 board_config = ALC882_3ST_DIG;
7331 err = snd_hda_attach_beep_device(codec, 0x1);
7337 if (board_config != ALC882_AUTO)
7338 setup_preset(spec, &alc882_presets[board_config]);
7340 if (codec->vendor_id == 0x10ec0885) {
7341 spec->stream_name_analog = "ALC885 Analog";
7342 spec->stream_name_digital = "ALC885 Digital";
7344 spec->stream_name_analog = "ALC882 Analog";
7345 spec->stream_name_digital = "ALC882 Digital";
7348 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7349 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7350 /* FIXME: setup DAC5 */
7351 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7352 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7354 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7355 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7357 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7358 if (!spec->adc_nids && spec->input_mux) {
7359 /* check whether NID 0x07 is valid */
7360 unsigned int wcap = get_wcaps(codec, 0x07);
7362 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7363 if (wcap != AC_WID_AUD_IN) {
7364 spec->adc_nids = alc882_adc_nids_alt;
7365 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7366 spec->capsrc_nids = alc882_capsrc_nids_alt;
7368 spec->adc_nids = alc882_adc_nids;
7369 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7370 spec->capsrc_nids = alc882_capsrc_nids;
7373 set_capture_mixer(spec);
7374 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7376 spec->vmaster_nid = 0x0c;
7378 codec->patch_ops = alc_patch_ops;
7379 if (board_config == ALC882_AUTO)
7380 spec->init_hook = alc882_auto_init;
7381 #ifdef CONFIG_SND_HDA_POWER_SAVE
7382 if (!spec->loopback.amplist)
7383 spec->loopback.amplist = alc882_loopbacks;
7385 codec->proc_widget_hook = print_realtek_coef;
7393 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7394 * configuration. Each pin widget can choose any input DACs and a mixer.
7395 * Each ADC is connected from a mixer of all inputs. This makes possible
7396 * 6-channel independent captures.
7398 * In addition, an independent DAC for the multi-playback (not used in this
7401 #define ALC883_DIGOUT_NID 0x06
7402 #define ALC883_DIGIN_NID 0x0a
7404 #define ALC1200_DIGOUT_NID 0x10
7406 static hda_nid_t alc883_dac_nids[4] = {
7407 /* front, rear, clfe, rear_surr */
7408 0x02, 0x03, 0x04, 0x05
7411 static hda_nid_t alc883_adc_nids[2] = {
7416 static hda_nid_t alc883_adc_nids_alt[1] = {
7421 static hda_nid_t alc883_adc_nids_rev[2] = {
7426 #define alc889_adc_nids alc880_adc_nids
7428 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7430 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7432 #define alc889_capsrc_nids alc882_capsrc_nids
7435 /* FIXME: should be a matrix-type input source selection */
7437 static struct hda_input_mux alc883_capture_source = {
7441 { "Front Mic", 0x1 },
7447 static struct hda_input_mux alc883_3stack_6ch_intel = {
7451 { "Front Mic", 0x0 },
7457 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7465 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7475 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7483 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7487 { "Front Mic", 0x1 },
7492 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7503 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7510 static struct hda_verb alc883_3ST_ch2_init[] = {
7511 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7512 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7513 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7514 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7521 static struct hda_verb alc883_3ST_ch4_init[] = {
7522 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7523 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7524 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7525 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7526 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7533 static struct hda_verb alc883_3ST_ch6_init[] = {
7534 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7535 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7536 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7537 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7538 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7539 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7543 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7544 { 2, alc883_3ST_ch2_init },
7545 { 4, alc883_3ST_ch4_init },
7546 { 6, alc883_3ST_ch6_init },
7552 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7553 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7554 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7555 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7556 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7563 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7564 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7565 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7566 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7567 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7568 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7575 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7576 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7577 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7578 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7579 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7580 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7581 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7585 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7586 { 2, alc883_3ST_ch2_intel_init },
7587 { 4, alc883_3ST_ch4_intel_init },
7588 { 6, alc883_3ST_ch6_intel_init },
7594 static struct hda_verb alc883_sixstack_ch6_init[] = {
7595 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7596 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7597 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7598 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7605 static struct hda_verb alc883_sixstack_ch8_init[] = {
7606 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7608 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7609 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7613 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7614 { 6, alc883_sixstack_ch6_init },
7615 { 8, alc883_sixstack_ch8_init },
7618 static struct hda_verb alc883_medion_eapd_verbs[] = {
7619 /* eanable EAPD on medion laptop */
7620 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7621 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7625 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7626 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7629 static struct snd_kcontrol_new alc883_base_mixer[] = {
7630 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7631 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7632 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7633 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7634 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7635 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7636 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7637 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7639 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7640 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7641 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7642 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7643 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7644 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7646 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7647 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7648 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7650 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7654 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7657 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7658 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7659 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7660 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7661 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7663 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7666 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7667 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7671 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7672 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7673 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7674 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7675 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7677 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7679 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7681 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7685 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7686 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7687 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7688 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7689 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7693 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7694 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7695 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7699 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7700 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7701 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7703 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7704 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7710 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7711 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7712 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7716 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7719 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7720 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7721 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7722 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7723 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7724 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7726 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7727 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7728 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7729 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7731 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7733 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7734 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7735 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7739 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7740 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7742 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7743 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7744 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7746 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7747 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7748 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7750 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7751 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7752 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7753 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7755 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7756 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7757 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7758 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7759 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7763 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7764 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7765 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7766 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7767 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7768 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7769 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7770 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7771 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7772 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7773 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7774 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7776 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7778 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7779 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7780 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7781 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7782 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7786 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7787 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7788 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7789 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7790 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7791 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7792 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7793 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7794 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7795 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7796 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7797 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7806 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7807 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7808 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7809 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7810 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7811 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7816 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7817 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7821 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7822 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7823 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7824 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7825 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7827 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7833 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7834 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7835 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7837 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7838 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7840 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7841 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7842 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7846 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7847 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7849 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7850 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7851 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7854 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7855 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7859 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7860 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7861 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7862 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7863 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7864 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7866 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7871 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7872 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7873 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7874 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7875 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7876 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7877 0x0d, 1, 0x0, HDA_OUTPUT),
7878 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7879 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7880 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7881 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7882 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7883 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7884 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7887 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7888 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7889 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7890 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7891 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7892 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7896 static struct hda_bind_ctls alc883_bind_cap_vol = {
7897 .ops = &snd_hda_bind_vol,
7899 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7900 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7905 static struct hda_bind_ctls alc883_bind_cap_switch = {
7906 .ops = &snd_hda_bind_sw,
7908 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7909 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7914 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7921 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7926 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7927 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7928 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7931 /* .name = "Capture Source", */
7932 .name = "Input Source",
7934 .info = alc_mux_enum_info,
7935 .get = alc_mux_enum_get,
7936 .put = alc_mux_enum_put,
7941 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7944 .name = "Channel Mode",
7945 .info = alc_ch_mode_info,
7946 .get = alc_ch_mode_get,
7947 .put = alc_ch_mode_put,
7952 static struct hda_verb alc883_init_verbs[] = {
7953 /* ADC1: mute amp left and right */
7954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7955 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7956 /* ADC2: mute amp left and right */
7957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7958 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7959 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7964 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7972 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7973 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7974 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7976 /* mute analog input loopbacks */
7977 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7983 /* Front Pin: output 0 (0x0c) */
7984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7985 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7986 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7987 /* Rear Pin: output 1 (0x0d) */
7988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7990 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7991 /* CLFE Pin: output 2 (0x0e) */
7992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7995 /* Side Pin: output 3 (0x0f) */
7996 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7997 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7998 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7999 /* Mic (rear) pin: input vref at 80% */
8000 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8002 /* Front Mic pin: input vref at 80% */
8003 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8004 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8005 /* Line In pin: input */
8006 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8008 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8009 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8010 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8011 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8012 /* CD pin widget for input */
8013 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8015 /* FIXME: use matrix-type input source selection */
8016 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8030 /* toggle speaker-output according to the hp-jack state */
8031 static void alc883_mitac_init_hook(struct hda_codec *codec)
8033 struct alc_spec *spec = codec->spec;
8035 spec->autocfg.hp_pins[0] = 0x15;
8036 spec->autocfg.speaker_pins[0] = 0x14;
8037 spec->autocfg.speaker_pins[1] = 0x17;
8038 alc_automute_amp(codec);
8041 /* auto-toggle front mic */
8043 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8045 unsigned int present;
8048 present = snd_hda_codec_read(codec, 0x18, 0,
8049 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8050 bits = present ? HDA_AMP_MUTE : 0;
8051 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8055 static struct hda_verb alc883_mitac_verbs[] = {
8057 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8058 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8060 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8061 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8063 /* enable unsolicited event */
8064 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8065 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8070 static struct hda_verb alc883_clevo_m720_verbs[] = {
8072 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8073 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8075 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8076 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8078 /* enable unsolicited event */
8079 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8080 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8085 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8087 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8088 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8090 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8093 /* enable unsolicited event */
8094 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8099 static struct hda_verb alc883_tagra_verbs[] = {
8100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8103 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8104 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8106 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8107 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8108 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8110 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8111 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8112 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8113 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8118 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8119 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8120 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8121 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8125 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8126 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8128 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8129 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8133 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8135 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8136 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8137 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8138 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8142 static struct hda_verb alc883_haier_w66_verbs[] = {
8143 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8144 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8146 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8148 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8150 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8151 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8155 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8157 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8159 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8161 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8162 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8163 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8167 static struct hda_verb alc888_6st_dell_verbs[] = {
8168 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8172 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8174 struct alc_spec *spec = codec->spec;
8176 spec->autocfg.hp_pins[0] = 0x1b;
8177 spec->autocfg.speaker_pins[0] = 0x14;
8178 spec->autocfg.speaker_pins[1] = 0x16;
8179 spec->autocfg.speaker_pins[2] = 0x18;
8180 alc_automute_amp(codec);
8183 static struct hda_verb alc888_3st_hp_verbs[] = {
8184 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8185 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8186 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8187 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8194 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8195 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8196 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8197 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8198 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8205 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8206 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8207 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8208 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8209 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8210 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8217 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8218 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8219 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8220 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8221 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8222 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8223 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8227 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8228 { 2, alc888_3st_hp_2ch_init },
8229 { 4, alc888_3st_hp_4ch_init },
8230 { 6, alc888_3st_hp_6ch_init },
8233 /* toggle front-jack and RCA according to the hp-jack state */
8234 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8236 unsigned int present;
8238 present = snd_hda_codec_read(codec, 0x1b, 0,
8239 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8240 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8241 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8242 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8243 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8246 /* toggle RCA according to the front-jack state */
8247 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8249 unsigned int present;
8251 present = snd_hda_codec_read(codec, 0x14, 0,
8252 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8253 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8254 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8257 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8260 if ((res >> 26) == ALC880_HP_EVENT)
8261 alc888_lenovo_ms7195_front_automute(codec);
8262 if ((res >> 26) == ALC880_FRONT_EVENT)
8263 alc888_lenovo_ms7195_rca_automute(codec);
8266 static struct hda_verb alc883_medion_md2_verbs[] = {
8267 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8268 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8272 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8276 /* toggle speaker-output according to the hp-jack state */
8277 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8279 struct alc_spec *spec = codec->spec;
8281 spec->autocfg.hp_pins[0] = 0x14;
8282 spec->autocfg.speaker_pins[0] = 0x15;
8283 alc_automute_amp(codec);
8286 /* toggle speaker-output according to the hp-jack state */
8287 #define alc883_tagra_init_hook alc882_targa_init_hook
8288 #define alc883_tagra_unsol_event alc882_targa_unsol_event
8290 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8292 unsigned int present;
8294 present = snd_hda_codec_read(codec, 0x18, 0,
8295 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8296 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8297 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8300 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8302 struct alc_spec *spec = codec->spec;
8304 spec->autocfg.hp_pins[0] = 0x15;
8305 spec->autocfg.speaker_pins[0] = 0x14;
8306 alc_automute_amp(codec);
8307 alc883_clevo_m720_mic_automute(codec);
8310 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8313 switch (res >> 26) {
8314 case ALC880_MIC_EVENT:
8315 alc883_clevo_m720_mic_automute(codec);
8318 alc_automute_amp_unsol_event(codec, res);
8323 /* toggle speaker-output according to the hp-jack state */
8324 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8326 struct alc_spec *spec = codec->spec;
8328 spec->autocfg.hp_pins[0] = 0x14;
8329 spec->autocfg.speaker_pins[0] = 0x15;
8330 alc_automute_amp(codec);
8333 static void alc883_haier_w66_init_hook(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 alc_automute_amp(codec);
8342 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8344 unsigned int present;
8347 present = snd_hda_codec_read(codec, 0x14, 0,
8348 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8349 bits = present ? HDA_AMP_MUTE : 0;
8350 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8351 HDA_AMP_MUTE, bits);
8354 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8356 unsigned int present;
8359 present = snd_hda_codec_read(codec, 0x1b, 0,
8360 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8361 bits = present ? HDA_AMP_MUTE : 0;
8362 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8363 HDA_AMP_MUTE, bits);
8364 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8365 HDA_AMP_MUTE, bits);
8368 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8371 if ((res >> 26) == ALC880_HP_EVENT)
8372 alc883_lenovo_101e_all_automute(codec);
8373 if ((res >> 26) == ALC880_FRONT_EVENT)
8374 alc883_lenovo_101e_ispeaker_automute(codec);
8377 /* toggle speaker-output according to the hp-jack state */
8378 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8380 struct alc_spec *spec = codec->spec;
8382 spec->autocfg.hp_pins[0] = 0x14;
8383 spec->autocfg.speaker_pins[0] = 0x15;
8384 spec->autocfg.speaker_pins[1] = 0x16;
8385 alc_automute_amp(codec);
8388 static struct hda_verb alc883_acer_eapd_verbs[] = {
8389 /* HP Pin: output 0 (0x0c) */
8390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8391 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8392 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8393 /* Front Pin: output 0 (0x0c) */
8394 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8395 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8396 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8397 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8398 /* eanable EAPD on medion laptop */
8399 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8400 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8401 /* enable unsolicited event */
8402 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8406 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8408 struct alc_spec *spec = codec->spec;
8410 spec->autocfg.hp_pins[0] = 0x1b;
8411 spec->autocfg.speaker_pins[0] = 0x14;
8412 spec->autocfg.speaker_pins[1] = 0x15;
8413 spec->autocfg.speaker_pins[2] = 0x16;
8414 spec->autocfg.speaker_pins[3] = 0x17;
8415 alc_automute_amp(codec);
8418 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8420 struct alc_spec *spec = codec->spec;
8422 spec->autocfg.hp_pins[0] = 0x1b;
8423 spec->autocfg.speaker_pins[0] = 0x14;
8424 spec->autocfg.speaker_pins[1] = 0x15;
8425 spec->autocfg.speaker_pins[2] = 0x16;
8426 spec->autocfg.speaker_pins[3] = 0x17;
8427 spec->autocfg.speaker_pins[4] = 0x1a;
8428 alc_automute_amp(codec);
8432 * generic initialization of ADC, input mixers and output mixers
8434 static struct hda_verb alc883_auto_init_verbs[] = {
8436 * Unmute ADC0-2 and set the default input to mic-in
8438 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8439 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8440 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8443 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8445 * Note: PASD motherboards uses the Line In 2 as the input for
8446 * front panel mic (mic 2)
8448 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8449 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8456 * Set up output mixers (0x0c - 0x0f)
8458 /* set vol=0 to output mixers */
8459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8463 /* set up input amps for analog loopback */
8464 /* Amp Indices: DAC = 0, mixer = 1 */
8465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8468 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8473 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8474 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8476 /* FIXME: use matrix-type input source selection */
8477 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8479 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8482 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8483 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8485 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8487 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8488 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8489 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8494 static struct hda_verb alc888_asus_m90v_verbs[] = {
8495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8496 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8497 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8498 /* enable unsolicited event */
8499 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8500 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8504 static void alc883_nb_mic_automute(struct hda_codec *codec)
8506 unsigned int present;
8508 present = snd_hda_codec_read(codec, 0x18, 0,
8509 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8510 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8511 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8512 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8513 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8516 static void alc883_M90V_init_hook(struct hda_codec *codec)
8518 struct alc_spec *spec = codec->spec;
8520 spec->autocfg.hp_pins[0] = 0x1b;
8521 spec->autocfg.speaker_pins[0] = 0x14;
8522 spec->autocfg.speaker_pins[1] = 0x15;
8523 spec->autocfg.speaker_pins[2] = 0x16;
8524 alc_automute_pin(codec);
8527 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8530 switch (res >> 26) {
8531 case ALC880_MIC_EVENT:
8532 alc883_nb_mic_automute(codec);
8535 alc_sku_unsol_event(codec, res);
8540 static void alc883_mode2_inithook(struct hda_codec *codec)
8542 alc883_M90V_init_hook(codec);
8543 alc883_nb_mic_automute(codec);
8546 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8550 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8551 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8552 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8553 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8554 /* enable unsolicited event */
8555 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8559 static void alc883_eee1601_inithook(struct hda_codec *codec)
8561 struct alc_spec *spec = codec->spec;
8563 spec->autocfg.hp_pins[0] = 0x14;
8564 spec->autocfg.speaker_pins[0] = 0x1b;
8565 alc_automute_pin(codec);
8568 #ifdef CONFIG_SND_HDA_POWER_SAVE
8569 #define alc883_loopbacks alc880_loopbacks
8572 /* pcm configuration: identiacal with ALC880 */
8573 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8574 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8575 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8576 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8577 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8580 * configuration and preset
8582 static const char *alc883_models[ALC883_MODEL_LAST] = {
8583 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8584 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8585 [ALC883_3ST_6ch] = "3stack-6ch",
8586 [ALC883_6ST_DIG] = "6stack-dig",
8587 [ALC883_TARGA_DIG] = "targa-dig",
8588 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8589 [ALC883_ACER] = "acer",
8590 [ALC883_ACER_ASPIRE] = "acer-aspire",
8591 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8592 [ALC883_MEDION] = "medion",
8593 [ALC883_MEDION_MD2] = "medion-md2",
8594 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8595 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8596 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8597 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8598 [ALC888_LENOVO_SKY] = "lenovo-sky",
8599 [ALC883_HAIER_W66] = "haier-w66",
8600 [ALC888_3ST_HP] = "3stack-hp",
8601 [ALC888_6ST_DELL] = "6stack-dell",
8602 [ALC883_MITAC] = "mitac",
8603 [ALC883_CLEVO_M720] = "clevo-m720",
8604 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8605 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8606 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8607 [ALC1200_ASUS_P5Q] = "asus-p5q",
8608 [ALC883_AUTO] = "auto",
8611 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8612 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8613 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8614 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8615 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8616 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8617 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8618 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8619 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8620 ALC888_ACER_ASPIRE_4930G),
8621 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8622 ALC888_ACER_ASPIRE_4930G),
8623 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8624 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8625 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8626 ALC888_ACER_ASPIRE_4930G),
8627 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8628 ALC888_ACER_ASPIRE_4930G),
8629 /* default Acer -- disabled as it causes more problems.
8630 * model=auto should work fine now
8632 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8633 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8634 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8635 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8636 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8637 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8638 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8639 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8640 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8641 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8642 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8643 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8644 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8645 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8646 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8647 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8648 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8649 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8650 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8651 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8652 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8653 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8654 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8655 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8656 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8657 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8658 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8659 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8660 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8661 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8662 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8663 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8664 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8665 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8666 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8667 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8668 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8669 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8670 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8671 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8672 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8673 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8674 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8675 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8676 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8677 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8678 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8679 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8680 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8681 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8682 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8683 ALC883_FUJITSU_PI2515),
8684 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8685 ALC888_FUJITSU_XA3530),
8686 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8687 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8688 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8689 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8690 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8691 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8692 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8693 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8694 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8695 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8696 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8697 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8698 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8699 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8703 static hda_nid_t alc883_slave_dig_outs[] = {
8704 ALC1200_DIGOUT_NID, 0,
8707 static hda_nid_t alc1200_slave_dig_outs[] = {
8708 ALC883_DIGOUT_NID, 0,
8711 static struct alc_config_preset alc883_presets[] = {
8712 [ALC883_3ST_2ch_DIG] = {
8713 .mixers = { alc883_3ST_2ch_mixer },
8714 .init_verbs = { alc883_init_verbs },
8715 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8716 .dac_nids = alc883_dac_nids,
8717 .dig_out_nid = ALC883_DIGOUT_NID,
8718 .dig_in_nid = ALC883_DIGIN_NID,
8719 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8720 .channel_mode = alc883_3ST_2ch_modes,
8721 .input_mux = &alc883_capture_source,
8723 [ALC883_3ST_6ch_DIG] = {
8724 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8725 .init_verbs = { alc883_init_verbs },
8726 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8727 .dac_nids = alc883_dac_nids,
8728 .dig_out_nid = ALC883_DIGOUT_NID,
8729 .dig_in_nid = ALC883_DIGIN_NID,
8730 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8731 .channel_mode = alc883_3ST_6ch_modes,
8733 .input_mux = &alc883_capture_source,
8735 [ALC883_3ST_6ch] = {
8736 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8737 .init_verbs = { alc883_init_verbs },
8738 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8739 .dac_nids = alc883_dac_nids,
8740 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8741 .channel_mode = alc883_3ST_6ch_modes,
8743 .input_mux = &alc883_capture_source,
8745 [ALC883_3ST_6ch_INTEL] = {
8746 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8747 .init_verbs = { alc883_init_verbs },
8748 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8749 .dac_nids = alc883_dac_nids,
8750 .dig_out_nid = ALC883_DIGOUT_NID,
8751 .dig_in_nid = ALC883_DIGIN_NID,
8752 .slave_dig_outs = alc883_slave_dig_outs,
8753 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8754 .channel_mode = alc883_3ST_6ch_intel_modes,
8756 .input_mux = &alc883_3stack_6ch_intel,
8758 [ALC883_6ST_DIG] = {
8759 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8760 .init_verbs = { alc883_init_verbs },
8761 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8762 .dac_nids = alc883_dac_nids,
8763 .dig_out_nid = ALC883_DIGOUT_NID,
8764 .dig_in_nid = ALC883_DIGIN_NID,
8765 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8766 .channel_mode = alc883_sixstack_modes,
8767 .input_mux = &alc883_capture_source,
8769 [ALC883_TARGA_DIG] = {
8770 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8771 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8772 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8773 .dac_nids = alc883_dac_nids,
8774 .dig_out_nid = ALC883_DIGOUT_NID,
8775 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8776 .channel_mode = alc883_3ST_6ch_modes,
8778 .input_mux = &alc883_capture_source,
8779 .unsol_event = alc883_tagra_unsol_event,
8780 .init_hook = alc883_tagra_init_hook,
8782 [ALC883_TARGA_2ch_DIG] = {
8783 .mixers = { alc883_tagra_2ch_mixer},
8784 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8786 .dac_nids = alc883_dac_nids,
8787 .adc_nids = alc883_adc_nids_alt,
8788 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8789 .dig_out_nid = ALC883_DIGOUT_NID,
8790 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8791 .channel_mode = alc883_3ST_2ch_modes,
8792 .input_mux = &alc883_capture_source,
8793 .unsol_event = alc883_tagra_unsol_event,
8794 .init_hook = alc883_tagra_init_hook,
8797 .mixers = { alc883_base_mixer },
8798 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8799 * and the headphone jack. Turn this on and rely on the
8800 * standard mute methods whenever the user wants to turn
8801 * these outputs off.
8803 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8804 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8805 .dac_nids = alc883_dac_nids,
8806 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8807 .channel_mode = alc883_3ST_2ch_modes,
8808 .input_mux = &alc883_capture_source,
8810 [ALC883_ACER_ASPIRE] = {
8811 .mixers = { alc883_acer_aspire_mixer },
8812 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8813 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8814 .dac_nids = alc883_dac_nids,
8815 .dig_out_nid = ALC883_DIGOUT_NID,
8816 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8817 .channel_mode = alc883_3ST_2ch_modes,
8818 .input_mux = &alc883_capture_source,
8819 .unsol_event = alc_automute_amp_unsol_event,
8820 .init_hook = alc883_acer_aspire_init_hook,
8822 [ALC888_ACER_ASPIRE_4930G] = {
8823 .mixers = { alc888_base_mixer,
8824 alc883_chmode_mixer },
8825 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8826 alc888_acer_aspire_4930g_verbs },
8827 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8828 .dac_nids = alc883_dac_nids,
8829 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8830 .adc_nids = alc883_adc_nids_rev,
8831 .capsrc_nids = alc883_capsrc_nids_rev,
8832 .dig_out_nid = ALC883_DIGOUT_NID,
8833 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8834 .channel_mode = alc883_3ST_6ch_modes,
8837 ARRAY_SIZE(alc888_2_capture_sources),
8838 .input_mux = alc888_2_capture_sources,
8839 .unsol_event = alc_automute_amp_unsol_event,
8840 .init_hook = alc888_acer_aspire_4930g_init_hook,
8843 .mixers = { alc883_fivestack_mixer,
8844 alc883_chmode_mixer },
8845 .init_verbs = { alc883_init_verbs,
8846 alc883_medion_eapd_verbs },
8847 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8848 .dac_nids = alc883_dac_nids,
8849 .adc_nids = alc883_adc_nids_alt,
8850 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8851 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8852 .channel_mode = alc883_sixstack_modes,
8853 .input_mux = &alc883_capture_source,
8855 [ALC883_MEDION_MD2] = {
8856 .mixers = { alc883_medion_md2_mixer},
8857 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8859 .dac_nids = alc883_dac_nids,
8860 .dig_out_nid = ALC883_DIGOUT_NID,
8861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8862 .channel_mode = alc883_3ST_2ch_modes,
8863 .input_mux = &alc883_capture_source,
8864 .unsol_event = alc_automute_amp_unsol_event,
8865 .init_hook = alc883_medion_md2_init_hook,
8867 [ALC883_LAPTOP_EAPD] = {
8868 .mixers = { alc883_base_mixer },
8869 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8870 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8871 .dac_nids = alc883_dac_nids,
8872 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8873 .channel_mode = alc883_3ST_2ch_modes,
8874 .input_mux = &alc883_capture_source,
8876 [ALC883_CLEVO_M720] = {
8877 .mixers = { alc883_clevo_m720_mixer },
8878 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8879 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8880 .dac_nids = alc883_dac_nids,
8881 .dig_out_nid = ALC883_DIGOUT_NID,
8882 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8883 .channel_mode = alc883_3ST_2ch_modes,
8884 .input_mux = &alc883_capture_source,
8885 .unsol_event = alc883_clevo_m720_unsol_event,
8886 .init_hook = alc883_clevo_m720_init_hook,
8888 [ALC883_LENOVO_101E_2ch] = {
8889 .mixers = { alc883_lenovo_101e_2ch_mixer},
8890 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8891 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8892 .dac_nids = alc883_dac_nids,
8893 .adc_nids = alc883_adc_nids_alt,
8894 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8895 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8896 .channel_mode = alc883_3ST_2ch_modes,
8897 .input_mux = &alc883_lenovo_101e_capture_source,
8898 .unsol_event = alc883_lenovo_101e_unsol_event,
8899 .init_hook = alc883_lenovo_101e_all_automute,
8901 [ALC883_LENOVO_NB0763] = {
8902 .mixers = { alc883_lenovo_nb0763_mixer },
8903 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8904 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8905 .dac_nids = alc883_dac_nids,
8906 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8907 .channel_mode = alc883_3ST_2ch_modes,
8909 .input_mux = &alc883_lenovo_nb0763_capture_source,
8910 .unsol_event = alc_automute_amp_unsol_event,
8911 .init_hook = alc883_medion_md2_init_hook,
8913 [ALC888_LENOVO_MS7195_DIG] = {
8914 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8915 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8916 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8917 .dac_nids = alc883_dac_nids,
8918 .dig_out_nid = ALC883_DIGOUT_NID,
8919 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8920 .channel_mode = alc883_3ST_6ch_modes,
8922 .input_mux = &alc883_capture_source,
8923 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8924 .init_hook = alc888_lenovo_ms7195_front_automute,
8926 [ALC883_HAIER_W66] = {
8927 .mixers = { alc883_tagra_2ch_mixer},
8928 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8929 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8930 .dac_nids = alc883_dac_nids,
8931 .dig_out_nid = ALC883_DIGOUT_NID,
8932 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8933 .channel_mode = alc883_3ST_2ch_modes,
8934 .input_mux = &alc883_capture_source,
8935 .unsol_event = alc_automute_amp_unsol_event,
8936 .init_hook = alc883_haier_w66_init_hook,
8939 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8940 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8941 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8942 .dac_nids = alc883_dac_nids,
8943 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8944 .channel_mode = alc888_3st_hp_modes,
8946 .input_mux = &alc883_capture_source,
8947 .unsol_event = alc_automute_amp_unsol_event,
8948 .init_hook = alc888_3st_hp_init_hook,
8950 [ALC888_6ST_DELL] = {
8951 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8952 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8953 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8954 .dac_nids = alc883_dac_nids,
8955 .dig_out_nid = ALC883_DIGOUT_NID,
8956 .dig_in_nid = ALC883_DIGIN_NID,
8957 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8958 .channel_mode = alc883_sixstack_modes,
8959 .input_mux = &alc883_capture_source,
8960 .unsol_event = alc_automute_amp_unsol_event,
8961 .init_hook = alc888_6st_dell_init_hook,
8964 .mixers = { alc883_mitac_mixer },
8965 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8966 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8967 .dac_nids = alc883_dac_nids,
8968 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8969 .channel_mode = alc883_3ST_2ch_modes,
8970 .input_mux = &alc883_capture_source,
8971 .unsol_event = alc_automute_amp_unsol_event,
8972 .init_hook = alc883_mitac_init_hook,
8974 [ALC883_FUJITSU_PI2515] = {
8975 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8976 .init_verbs = { alc883_init_verbs,
8977 alc883_2ch_fujitsu_pi2515_verbs},
8978 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8979 .dac_nids = alc883_dac_nids,
8980 .dig_out_nid = ALC883_DIGOUT_NID,
8981 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8982 .channel_mode = alc883_3ST_2ch_modes,
8983 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8984 .unsol_event = alc_automute_amp_unsol_event,
8985 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
8987 [ALC888_FUJITSU_XA3530] = {
8988 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8989 .init_verbs = { alc883_init_verbs,
8990 alc888_fujitsu_xa3530_verbs },
8991 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8992 .dac_nids = alc883_dac_nids,
8993 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8994 .adc_nids = alc883_adc_nids_rev,
8995 .capsrc_nids = alc883_capsrc_nids_rev,
8996 .dig_out_nid = ALC883_DIGOUT_NID,
8997 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8998 .channel_mode = alc888_4ST_8ch_intel_modes,
9000 ARRAY_SIZE(alc888_2_capture_sources),
9001 .input_mux = alc888_2_capture_sources,
9002 .unsol_event = alc_automute_amp_unsol_event,
9003 .init_hook = alc888_fujitsu_xa3530_init_hook,
9005 [ALC888_LENOVO_SKY] = {
9006 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9007 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9008 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9009 .dac_nids = alc883_dac_nids,
9010 .dig_out_nid = ALC883_DIGOUT_NID,
9011 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9012 .channel_mode = alc883_sixstack_modes,
9014 .input_mux = &alc883_lenovo_sky_capture_source,
9015 .unsol_event = alc_automute_amp_unsol_event,
9016 .init_hook = alc888_lenovo_sky_init_hook,
9018 [ALC888_ASUS_M90V] = {
9019 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9020 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9021 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9022 .dac_nids = alc883_dac_nids,
9023 .dig_out_nid = ALC883_DIGOUT_NID,
9024 .dig_in_nid = ALC883_DIGIN_NID,
9025 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9026 .channel_mode = alc883_3ST_6ch_modes,
9028 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9029 .unsol_event = alc883_mode2_unsol_event,
9030 .init_hook = alc883_mode2_inithook,
9032 [ALC888_ASUS_EEE1601] = {
9033 .mixers = { alc883_asus_eee1601_mixer },
9034 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9035 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9037 .dac_nids = alc883_dac_nids,
9038 .dig_out_nid = ALC883_DIGOUT_NID,
9039 .dig_in_nid = ALC883_DIGIN_NID,
9040 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9041 .channel_mode = alc883_3ST_2ch_modes,
9043 .input_mux = &alc883_asus_eee1601_capture_source,
9044 .unsol_event = alc_sku_unsol_event,
9045 .init_hook = alc883_eee1601_inithook,
9047 [ALC1200_ASUS_P5Q] = {
9048 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9049 .init_verbs = { alc883_init_verbs },
9050 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9051 .dac_nids = alc883_dac_nids,
9052 .dig_out_nid = ALC1200_DIGOUT_NID,
9053 .dig_in_nid = ALC883_DIGIN_NID,
9054 .slave_dig_outs = alc1200_slave_dig_outs,
9055 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9056 .channel_mode = alc883_sixstack_modes,
9057 .input_mux = &alc883_capture_source,
9063 * BIOS auto configuration
9065 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9066 hda_nid_t nid, int pin_type,
9070 struct alc_spec *spec = codec->spec;
9073 alc_set_pin_output(codec, nid, pin_type);
9074 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9077 idx = spec->multiout.dac_nids[dac_idx] - 2;
9078 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9082 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9084 struct alc_spec *spec = codec->spec;
9087 for (i = 0; i <= HDA_SIDE; i++) {
9088 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9089 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9091 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9096 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9098 struct alc_spec *spec = codec->spec;
9101 pin = spec->autocfg.hp_pins[0];
9102 if (pin) /* connect to front */
9104 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9105 pin = spec->autocfg.speaker_pins[0];
9107 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9110 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9111 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9113 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9115 struct alc_spec *spec = codec->spec;
9118 for (i = 0; i < AUTO_PIN_LAST; i++) {
9119 hda_nid_t nid = spec->autocfg.input_pins[i];
9120 if (alc883_is_input_pin(nid)) {
9121 alc_set_input_pin(codec, nid, i);
9122 if (nid != ALC883_PIN_CD_NID &&
9123 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9124 snd_hda_codec_write(codec, nid, 0,
9125 AC_VERB_SET_AMP_GAIN_MUTE,
9131 #define alc883_auto_init_input_src alc882_auto_init_input_src
9133 /* almost identical with ALC880 parser... */
9134 static int alc883_parse_auto_config(struct hda_codec *codec)
9136 struct alc_spec *spec = codec->spec;
9137 int err = alc880_parse_auto_config(codec);
9138 struct auto_pin_cfg *cfg = &spec->autocfg;
9144 return 0; /* no config found */
9146 err = alc_auto_add_mic_boost(codec);
9150 /* hack - override the init verbs */
9151 spec->init_verbs[0] = alc883_auto_init_verbs;
9153 /* setup input_mux for ALC889 */
9154 if (codec->vendor_id == 0x10ec0889) {
9155 /* digital-mic input pin is excluded in alc880_auto_create..()
9156 * because it's under 0x18
9158 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9159 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9160 struct hda_input_mux *imux = &spec->private_imux[0];
9161 for (i = 1; i < 3; i++)
9162 memcpy(&spec->private_imux[i],
9163 &spec->private_imux[0],
9164 sizeof(spec->private_imux[0]));
9165 imux->items[imux->num_items].label = "Int DMic";
9166 imux->items[imux->num_items].index = 0x0b;
9168 spec->num_mux_defs = 3;
9169 spec->input_mux = spec->private_imux;
9173 return 1; /* config found */
9176 /* additional initialization for auto-configuration model */
9177 static void alc883_auto_init(struct hda_codec *codec)
9179 struct alc_spec *spec = codec->spec;
9180 alc883_auto_init_multi_out(codec);
9181 alc883_auto_init_hp_out(codec);
9182 alc883_auto_init_analog_input(codec);
9183 alc883_auto_init_input_src(codec);
9184 if (spec->unsol_event)
9185 alc_inithook(codec);
9188 static int patch_alc883(struct hda_codec *codec)
9190 struct alc_spec *spec;
9191 int err, board_config;
9193 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9199 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9201 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9204 if (board_config < 0) {
9205 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9206 "trying auto-probe from BIOS...\n");
9207 board_config = ALC883_AUTO;
9210 if (board_config == ALC883_AUTO) {
9211 /* automatic parse from the BIOS config */
9212 err = alc883_parse_auto_config(codec);
9218 "hda_codec: Cannot set up configuration "
9219 "from BIOS. Using base mode...\n");
9220 board_config = ALC883_3ST_2ch_DIG;
9224 err = snd_hda_attach_beep_device(codec, 0x1);
9230 if (board_config != ALC883_AUTO)
9231 setup_preset(spec, &alc883_presets[board_config]);
9233 switch (codec->vendor_id) {
9235 if (codec->revision_id == 0x100101) {
9236 spec->stream_name_analog = "ALC1200 Analog";
9237 spec->stream_name_digital = "ALC1200 Digital";
9239 spec->stream_name_analog = "ALC888 Analog";
9240 spec->stream_name_digital = "ALC888 Digital";
9242 if (!spec->num_adc_nids) {
9243 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9244 spec->adc_nids = alc883_adc_nids;
9246 if (!spec->capsrc_nids)
9247 spec->capsrc_nids = alc883_capsrc_nids;
9248 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9249 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9252 spec->stream_name_analog = "ALC889 Analog";
9253 spec->stream_name_digital = "ALC889 Digital";
9254 if (!spec->num_adc_nids) {
9255 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9256 spec->adc_nids = alc889_adc_nids;
9258 if (!spec->capsrc_nids)
9259 spec->capsrc_nids = alc889_capsrc_nids;
9260 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9264 spec->stream_name_analog = "ALC883 Analog";
9265 spec->stream_name_digital = "ALC883 Digital";
9266 if (!spec->num_adc_nids) {
9267 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9268 spec->adc_nids = alc883_adc_nids;
9270 if (!spec->capsrc_nids)
9271 spec->capsrc_nids = alc883_capsrc_nids;
9272 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9276 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9277 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9278 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9280 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9281 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9283 if (!spec->cap_mixer)
9284 set_capture_mixer(spec);
9285 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9287 spec->vmaster_nid = 0x0c;
9289 codec->patch_ops = alc_patch_ops;
9290 if (board_config == ALC883_AUTO)
9291 spec->init_hook = alc883_auto_init;
9293 #ifdef CONFIG_SND_HDA_POWER_SAVE
9294 if (!spec->loopback.amplist)
9295 spec->loopback.amplist = alc883_loopbacks;
9297 codec->proc_widget_hook = print_realtek_coef;
9306 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9307 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9309 #define alc262_dac_nids alc260_dac_nids
9310 #define alc262_adc_nids alc882_adc_nids
9311 #define alc262_adc_nids_alt alc882_adc_nids_alt
9312 #define alc262_capsrc_nids alc882_capsrc_nids
9313 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9315 #define alc262_modes alc260_modes
9316 #define alc262_capture_source alc882_capture_source
9318 static hda_nid_t alc262_dmic_adc_nids[1] = {
9323 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9325 static struct snd_kcontrol_new alc262_base_mixer[] = {
9326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9330 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9331 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9334 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9335 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9336 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9337 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9338 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9339 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9340 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9341 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9345 /* update HP, line and mono-out pins according to the master switch */
9346 static void alc262_hp_master_update(struct hda_codec *codec)
9348 struct alc_spec *spec = codec->spec;
9349 int val = spec->master_sw;
9352 snd_hda_codec_write_cache(codec, 0x1b, 0,
9353 AC_VERB_SET_PIN_WIDGET_CONTROL,
9355 snd_hda_codec_write_cache(codec, 0x15, 0,
9356 AC_VERB_SET_PIN_WIDGET_CONTROL,
9358 /* mono (speaker) depending on the HP jack sense */
9359 val = val && !spec->jack_present;
9360 snd_hda_codec_write_cache(codec, 0x16, 0,
9361 AC_VERB_SET_PIN_WIDGET_CONTROL,
9365 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9367 struct alc_spec *spec = codec->spec;
9368 unsigned int presence;
9369 presence = snd_hda_codec_read(codec, 0x1b, 0,
9370 AC_VERB_GET_PIN_SENSE, 0);
9371 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9372 alc262_hp_master_update(codec);
9375 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9377 if ((res >> 26) != ALC880_HP_EVENT)
9379 alc262_hp_bpc_automute(codec);
9382 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9384 struct alc_spec *spec = codec->spec;
9385 unsigned int presence;
9386 presence = snd_hda_codec_read(codec, 0x15, 0,
9387 AC_VERB_GET_PIN_SENSE, 0);
9388 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9389 alc262_hp_master_update(codec);
9392 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9395 if ((res >> 26) != ALC880_HP_EVENT)
9397 alc262_hp_wildwest_automute(codec);
9400 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9402 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9403 struct snd_ctl_elem_value *ucontrol)
9405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9406 struct alc_spec *spec = codec->spec;
9407 int val = !!*ucontrol->value.integer.value;
9409 if (val == spec->master_sw)
9411 spec->master_sw = val;
9412 alc262_hp_master_update(codec);
9416 #define ALC262_HP_MASTER_SWITCH \
9418 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9419 .name = "Master Playback Switch", \
9420 .info = snd_ctl_boolean_mono_info, \
9421 .get = alc262_hp_master_sw_get, \
9422 .put = alc262_hp_master_sw_put, \
9425 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9426 ALC262_HP_MASTER_SWITCH,
9427 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9428 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9430 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9432 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9436 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9438 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9439 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9441 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9444 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9445 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9449 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9450 ALC262_HP_MASTER_SWITCH,
9451 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9452 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9455 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9457 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9459 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9460 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9461 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9469 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9470 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9471 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9472 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9476 /* mute/unmute internal speaker according to the hp jack and mute state */
9477 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9479 struct alc_spec *spec = codec->spec;
9481 spec->autocfg.hp_pins[0] = 0x15;
9482 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9483 alc_automute_amp(codec);
9486 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9487 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9488 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9489 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9490 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9493 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9497 static struct hda_verb alc262_hp_t5735_verbs[] = {
9498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9501 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9505 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9506 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9508 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9509 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9510 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9511 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9515 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9516 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9517 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9518 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9520 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9521 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9529 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9536 /* bind hp and internal speaker mute (with plug check) as master switch */
9537 static void alc262_hippo_master_update(struct hda_codec *codec)
9539 struct alc_spec *spec = codec->spec;
9540 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9541 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9542 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9546 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9547 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9548 HDA_AMP_MUTE, mute);
9549 /* mute internal speaker per jack sense */
9550 if (spec->jack_present)
9551 mute = HDA_AMP_MUTE;
9553 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9554 HDA_AMP_MUTE, mute);
9555 if (speaker_nid && speaker_nid != line_nid)
9556 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9557 HDA_AMP_MUTE, mute);
9560 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9562 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9563 struct snd_ctl_elem_value *ucontrol)
9565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9566 struct alc_spec *spec = codec->spec;
9567 int val = !!*ucontrol->value.integer.value;
9569 if (val == spec->master_sw)
9571 spec->master_sw = val;
9572 alc262_hippo_master_update(codec);
9576 #define ALC262_HIPPO_MASTER_SWITCH \
9578 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9579 .name = "Master Playback Switch", \
9580 .info = snd_ctl_boolean_mono_info, \
9581 .get = alc262_hippo_master_sw_get, \
9582 .put = alc262_hippo_master_sw_put, \
9585 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9586 ALC262_HIPPO_MASTER_SWITCH,
9587 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9588 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9589 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9594 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9595 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9596 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9597 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9598 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9602 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9603 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9604 ALC262_HIPPO_MASTER_SWITCH,
9605 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9606 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9607 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9608 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9611 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9612 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9613 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9614 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9618 /* mute/unmute internal speaker according to the hp jack and mute state */
9619 static void alc262_hippo_automute(struct hda_codec *codec)
9621 struct alc_spec *spec = codec->spec;
9622 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9623 unsigned int present;
9625 /* need to execute and sync at first */
9626 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9627 present = snd_hda_codec_read(codec, hp_nid, 0,
9628 AC_VERB_GET_PIN_SENSE, 0);
9629 spec->jack_present = (present & 0x80000000) != 0;
9630 alc262_hippo_master_update(codec);
9633 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9635 if ((res >> 26) != ALC880_HP_EVENT)
9637 alc262_hippo_automute(codec);
9640 static void alc262_hippo_init_hook(struct hda_codec *codec)
9642 struct alc_spec *spec = codec->spec;
9644 spec->autocfg.hp_pins[0] = 0x15;
9645 spec->autocfg.speaker_pins[0] = 0x14;
9646 alc262_hippo_automute(codec);
9649 static void alc262_hippo1_init_hook(struct hda_codec *codec)
9651 struct alc_spec *spec = codec->spec;
9653 spec->autocfg.hp_pins[0] = 0x1b;
9654 spec->autocfg.speaker_pins[0] = 0x14;
9655 alc262_hippo_automute(codec);
9659 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9660 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9661 ALC262_HIPPO_MASTER_SWITCH,
9662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9664 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9665 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9669 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9670 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9671 ALC262_HIPPO_MASTER_SWITCH,
9672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9675 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9676 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9680 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9681 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9682 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9683 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9684 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9685 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9686 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9687 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9688 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9689 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9690 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9691 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9692 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9696 static struct hda_verb alc262_tyan_verbs[] = {
9697 /* Headphone automute */
9698 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9699 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9700 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9702 /* P11 AUX_IN, white 4-pin connector */
9703 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9704 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9705 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9706 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9711 /* unsolicited event for HP jack sensing */
9712 static void alc262_tyan_init_hook(struct hda_codec *codec)
9714 struct alc_spec *spec = codec->spec;
9716 spec->autocfg.hp_pins[0] = 0x1b;
9717 spec->autocfg.speaker_pins[0] = 0x15;
9718 alc_automute_amp(codec);
9722 #define alc262_capture_mixer alc882_capture_mixer
9723 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9726 * generic initialization of ADC, input mixers and output mixers
9728 static struct hda_verb alc262_init_verbs[] = {
9730 * Unmute ADC0-2 and set the default input to mic-in
9732 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9734 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9735 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9736 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9737 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9739 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9741 * Note: PASD motherboards uses the Line In 2 as the input for
9742 * front panel mic (mic 2)
9744 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9745 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9746 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9752 * Set up output mixers (0x0c - 0x0e)
9754 /* set vol=0 to output mixers */
9755 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9758 /* set up input amps for analog loopback */
9759 /* Amp Indices: DAC = 0, mixer = 1 */
9760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9762 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9763 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9764 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9765 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9767 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9768 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9769 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9771 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9772 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9774 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9776 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9777 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9778 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9780 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9783 /* FIXME: use matrix-type input source selection */
9784 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9785 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9786 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9787 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9788 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9789 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9792 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9793 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9794 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9797 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9798 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9799 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9804 static struct hda_verb alc262_eapd_verbs[] = {
9805 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9806 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9810 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9811 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9816 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9819 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9821 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9822 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9826 static struct hda_verb alc262_sony_unsol_verbs[] = {
9827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9831 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9836 static struct hda_input_mux alc262_dmic_capture_source = {
9839 { "Int DMic", 0x9 },
9844 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9845 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9846 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9847 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9853 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9854 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9856 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9857 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9858 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9859 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9860 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9865 static void alc262_dmic_automute(struct hda_codec *codec)
9867 unsigned int present;
9869 present = snd_hda_codec_read(codec, 0x18, 0,
9870 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9871 snd_hda_codec_write(codec, 0x22, 0,
9872 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9876 /* unsolicited event for HP jack sensing */
9877 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9880 if ((res >> 26) == ALC880_MIC_EVENT)
9881 alc262_dmic_automute(codec);
9883 alc_sku_unsol_event(codec, res);
9886 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9888 struct alc_spec *spec = codec->spec;
9890 spec->autocfg.hp_pins[0] = 0x15;
9891 spec->autocfg.speaker_pins[0] = 0x14;
9892 alc_automute_pin(codec);
9893 alc262_dmic_automute(codec);
9899 * 0x16 = internal speaker
9900 * 0x18 = external mic
9903 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9904 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9905 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9908 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9909 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9911 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9916 static struct hda_verb alc262_nec_verbs[] = {
9917 /* Unmute Speaker */
9918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9922 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9924 /* External mic to headphone */
9925 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9926 /* External mic to speaker */
9927 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9933 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9934 * 0x1b = port replicator headphone out
9937 #define ALC_HP_EVENT 0x37
9939 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9940 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9941 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9942 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9943 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9947 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9948 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9949 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9953 static struct hda_input_mux alc262_fujitsu_capture_source = {
9962 static struct hda_input_mux alc262_HP_capture_source = {
9966 { "Front Mic", 0x1 },
9973 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9977 { "Front Mic", 0x2 },
9983 /* mute/unmute internal speaker according to the hp jacks and mute state */
9984 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9986 struct alc_spec *spec = codec->spec;
9989 if (force || !spec->sense_updated) {
9990 unsigned int present;
9991 /* need to execute and sync at first */
9992 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9993 /* check laptop HP jack */
9994 present = snd_hda_codec_read(codec, 0x14, 0,
9995 AC_VERB_GET_PIN_SENSE, 0);
9996 /* need to execute and sync at first */
9997 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9998 /* check docking HP jack */
9999 present |= snd_hda_codec_read(codec, 0x1b, 0,
10000 AC_VERB_GET_PIN_SENSE, 0);
10001 if (present & AC_PINSENSE_PRESENCE)
10002 spec->jack_present = 1;
10004 spec->jack_present = 0;
10005 spec->sense_updated = 1;
10007 /* unmute internal speaker only if both HPs are unplugged and
10008 * master switch is on
10010 if (spec->jack_present)
10011 mute = HDA_AMP_MUTE;
10013 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10014 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10015 HDA_AMP_MUTE, mute);
10018 /* unsolicited event for HP jack sensing */
10019 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10022 if ((res >> 26) != ALC_HP_EVENT)
10024 alc262_fujitsu_automute(codec, 1);
10027 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10029 alc262_fujitsu_automute(codec, 1);
10032 /* bind volumes of both NID 0x0c and 0x0d */
10033 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10034 .ops = &snd_hda_bind_vol,
10036 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10037 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10042 /* mute/unmute internal speaker according to the hp jack and mute state */
10043 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10045 struct alc_spec *spec = codec->spec;
10048 if (force || !spec->sense_updated) {
10049 unsigned int present_int_hp;
10050 /* need to execute and sync at first */
10051 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10052 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10053 AC_VERB_GET_PIN_SENSE, 0);
10054 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10055 spec->sense_updated = 1;
10057 if (spec->jack_present) {
10058 /* mute internal speaker */
10059 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10060 HDA_AMP_MUTE, HDA_AMP_MUTE);
10061 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10062 HDA_AMP_MUTE, HDA_AMP_MUTE);
10064 /* unmute internal speaker if necessary */
10065 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10066 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10067 HDA_AMP_MUTE, mute);
10068 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10069 HDA_AMP_MUTE, mute);
10073 /* unsolicited event for HP jack sensing */
10074 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10077 if ((res >> 26) != ALC_HP_EVENT)
10079 alc262_lenovo_3000_automute(codec, 1);
10082 /* bind hp and internal speaker mute (with plug check) */
10083 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10084 struct snd_ctl_elem_value *ucontrol)
10086 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10087 long *valp = ucontrol->value.integer.value;
10090 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10092 valp ? 0 : HDA_AMP_MUTE);
10093 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10095 valp ? 0 : HDA_AMP_MUTE);
10098 alc262_fujitsu_automute(codec, 0);
10102 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10103 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10106 .name = "Master Playback Switch",
10107 .info = snd_hda_mixer_amp_switch_info,
10108 .get = snd_hda_mixer_amp_switch_get,
10109 .put = alc262_fujitsu_master_sw_put,
10110 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10112 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10113 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10117 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10118 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10119 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10123 /* bind hp and internal speaker mute (with plug check) */
10124 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10125 struct snd_ctl_elem_value *ucontrol)
10127 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10128 long *valp = ucontrol->value.integer.value;
10131 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10133 valp ? 0 : HDA_AMP_MUTE);
10136 alc262_lenovo_3000_automute(codec, 0);
10140 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10141 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10143 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10144 .name = "Master Playback Switch",
10145 .info = snd_hda_mixer_amp_switch_info,
10146 .get = snd_hda_mixer_amp_switch_get,
10147 .put = alc262_lenovo_3000_master_sw_put,
10148 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10150 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10151 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10152 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10154 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10155 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10156 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10157 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10161 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10162 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10163 ALC262_HIPPO_MASTER_SWITCH,
10164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10166 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10167 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10168 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10169 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10173 /* additional init verbs for Benq laptops */
10174 static struct hda_verb alc262_EAPD_verbs[] = {
10175 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10176 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10180 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10181 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10182 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10184 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10185 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10189 /* Samsung Q1 Ultra Vista model setup */
10190 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10191 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10192 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10193 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10195 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10196 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10200 static struct hda_verb alc262_ultra_verbs[] = {
10202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10203 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10204 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10209 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10212 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10213 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10214 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10217 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10218 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10219 /* ADC, choose mic */
10220 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10223 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10224 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10225 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10226 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10228 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10233 /* mute/unmute internal speaker according to the hp jack and mute state */
10234 static void alc262_ultra_automute(struct hda_codec *codec)
10236 struct alc_spec *spec = codec->spec;
10240 /* auto-mute only when HP is used as HP */
10241 if (!spec->cur_mux[0]) {
10242 unsigned int present;
10243 /* need to execute and sync at first */
10244 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10245 present = snd_hda_codec_read(codec, 0x15, 0,
10246 AC_VERB_GET_PIN_SENSE, 0);
10247 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10248 if (spec->jack_present)
10249 mute = HDA_AMP_MUTE;
10251 /* mute/unmute internal speaker */
10252 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10253 HDA_AMP_MUTE, mute);
10254 /* mute/unmute HP */
10255 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10256 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10259 /* unsolicited event for HP jack sensing */
10260 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10263 if ((res >> 26) != ALC880_HP_EVENT)
10265 alc262_ultra_automute(codec);
10268 static struct hda_input_mux alc262_ultra_capture_source = {
10272 { "Headphone", 0x7 },
10276 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10277 struct snd_ctl_elem_value *ucontrol)
10279 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10280 struct alc_spec *spec = codec->spec;
10283 ret = alc_mux_enum_put(kcontrol, ucontrol);
10286 /* reprogram the HP pin as mic or HP according to the input source */
10287 snd_hda_codec_write_cache(codec, 0x15, 0,
10288 AC_VERB_SET_PIN_WIDGET_CONTROL,
10289 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10290 alc262_ultra_automute(codec); /* mute/unmute HP */
10294 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10295 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10296 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10298 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10299 .name = "Capture Source",
10300 .info = alc_mux_enum_info,
10301 .get = alc_mux_enum_get,
10302 .put = alc262_ultra_mux_enum_put,
10307 /* add playback controls from the parsed DAC table */
10308 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10309 const struct auto_pin_cfg *cfg)
10314 spec->multiout.num_dacs = 1; /* only use one dac */
10315 spec->multiout.dac_nids = spec->private_dac_nids;
10316 spec->multiout.dac_nids[0] = 2;
10318 nid = cfg->line_out_pins[0];
10320 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10321 "Front Playback Volume",
10322 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10325 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10326 "Front Playback Switch",
10327 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10332 nid = cfg->speaker_pins[0];
10335 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10336 "Speaker Playback Volume",
10337 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10341 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10342 "Speaker Playback Switch",
10343 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10348 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10349 "Speaker Playback Switch",
10350 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10356 nid = cfg->hp_pins[0];
10358 /* spec->multiout.hp_nid = 2; */
10360 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10361 "Headphone Playback Volume",
10362 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10366 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10367 "Headphone Playback Switch",
10368 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10373 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10374 "Headphone Playback Switch",
10375 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10384 /* identical with ALC880 */
10385 #define alc262_auto_create_analog_input_ctls \
10386 alc880_auto_create_analog_input_ctls
10389 * generic initialization of ADC, input mixers and output mixers
10391 static struct hda_verb alc262_volume_init_verbs[] = {
10393 * Unmute ADC0-2 and set the default input to mic-in
10395 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10397 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10398 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10399 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10400 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10402 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10404 * Note: PASD motherboards uses the Line In 2 as the input for
10405 * front panel mic (mic 2)
10407 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10412 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10415 * Set up output mixers (0x0c - 0x0f)
10417 /* set vol=0 to output mixers */
10418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10422 /* set up input amps for analog loopback */
10423 /* Amp Indices: DAC = 0, mixer = 1 */
10424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10426 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10427 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10428 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10429 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10431 /* FIXME: use matrix-type input source selection */
10432 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10433 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10436 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10439 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10440 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10441 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10442 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10444 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10446 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10447 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10452 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10454 * Unmute ADC0-2 and set the default input to mic-in
10456 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10458 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10460 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10461 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10463 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10465 * Note: PASD motherboards uses the Line In 2 as the input for
10466 * front panel mic (mic 2)
10468 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10469 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10470 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10471 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10472 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10478 * Set up output mixers (0x0c - 0x0e)
10480 /* set vol=0 to output mixers */
10481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10485 /* set up input amps for analog loopback */
10486 /* Amp Indices: DAC = 0, mixer = 1 */
10487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10494 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10496 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10498 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10501 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10502 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10506 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10508 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10510 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10511 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10514 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10515 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10518 /* FIXME: use matrix-type input source selection */
10519 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10520 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10536 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10541 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10543 * Unmute ADC0-2 and set the default input to mic-in
10545 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10547 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10549 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10552 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10554 * Note: PASD motherboards uses the Line In 2 as the input for front
10555 * panel mic (mic 2)
10557 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10567 * Set up output mixers (0x0c - 0x0e)
10569 /* set vol=0 to output mixers */
10570 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10571 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10572 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10574 /* set up input amps for analog loopback */
10575 /* Amp Indices: DAC = 0, mixer = 1 */
10576 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10580 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10585 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10590 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10595 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10598 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10600 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10602 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10603 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10605 /* FIXME: use matrix-type input source selection */
10606 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10613 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10617 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10619 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10620 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10621 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10622 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10627 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10629 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10637 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10640 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10641 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10644 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10645 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10646 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10650 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10655 #ifdef CONFIG_SND_HDA_POWER_SAVE
10656 #define alc262_loopbacks alc880_loopbacks
10659 /* pcm configuration: identiacal with ALC880 */
10660 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10661 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10662 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10663 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10666 * BIOS auto configuration
10668 static int alc262_parse_auto_config(struct hda_codec *codec)
10670 struct alc_spec *spec = codec->spec;
10672 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10674 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10678 if (!spec->autocfg.line_outs) {
10679 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10680 spec->multiout.max_channels = 2;
10681 spec->no_analog = 1;
10684 return 0; /* can't find valid BIOS pin config */
10686 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10689 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10693 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10696 if (spec->autocfg.dig_outs) {
10697 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10698 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10700 if (spec->autocfg.dig_in_pin)
10701 spec->dig_in_nid = ALC262_DIGIN_NID;
10703 if (spec->kctls.list)
10704 add_mixer(spec, spec->kctls.list);
10706 add_verb(spec, alc262_volume_init_verbs);
10707 spec->num_mux_defs = 1;
10708 spec->input_mux = &spec->private_imux[0];
10710 err = alc_auto_add_mic_boost(codec);
10714 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10719 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10720 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10721 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10722 #define alc262_auto_init_input_src alc882_auto_init_input_src
10725 /* init callback for auto-configuration model -- overriding the default init */
10726 static void alc262_auto_init(struct hda_codec *codec)
10728 struct alc_spec *spec = codec->spec;
10729 alc262_auto_init_multi_out(codec);
10730 alc262_auto_init_hp_out(codec);
10731 alc262_auto_init_analog_input(codec);
10732 alc262_auto_init_input_src(codec);
10733 if (spec->unsol_event)
10734 alc_inithook(codec);
10738 * configuration and preset
10740 static const char *alc262_models[ALC262_MODEL_LAST] = {
10741 [ALC262_BASIC] = "basic",
10742 [ALC262_HIPPO] = "hippo",
10743 [ALC262_HIPPO_1] = "hippo_1",
10744 [ALC262_FUJITSU] = "fujitsu",
10745 [ALC262_HP_BPC] = "hp-bpc",
10746 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10747 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10748 [ALC262_HP_RP5700] = "hp-rp5700",
10749 [ALC262_BENQ_ED8] = "benq",
10750 [ALC262_BENQ_T31] = "benq-t31",
10751 [ALC262_SONY_ASSAMD] = "sony-assamd",
10752 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10753 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10754 [ALC262_ULTRA] = "ultra",
10755 [ALC262_LENOVO_3000] = "lenovo-3000",
10756 [ALC262_NEC] = "nec",
10757 [ALC262_TYAN] = "tyan",
10758 [ALC262_AUTO] = "auto",
10761 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10762 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10763 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10764 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10766 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10768 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10770 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10771 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10772 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10773 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10774 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10775 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10776 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10777 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10778 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10779 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10780 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10781 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10782 ALC262_HP_TC_T5735),
10783 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10784 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10785 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10786 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10787 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10788 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10789 ALC262_SONY_ASSAMD),
10790 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10791 ALC262_TOSHIBA_RX1),
10792 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10793 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10794 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10795 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10796 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10798 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10799 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10800 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10801 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10802 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10806 static struct alc_config_preset alc262_presets[] = {
10808 .mixers = { alc262_base_mixer },
10809 .init_verbs = { alc262_init_verbs },
10810 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10811 .dac_nids = alc262_dac_nids,
10813 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10814 .channel_mode = alc262_modes,
10815 .input_mux = &alc262_capture_source,
10818 .mixers = { alc262_hippo_mixer },
10819 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10820 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10821 .dac_nids = alc262_dac_nids,
10823 .dig_out_nid = ALC262_DIGOUT_NID,
10824 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10825 .channel_mode = alc262_modes,
10826 .input_mux = &alc262_capture_source,
10827 .unsol_event = alc262_hippo_unsol_event,
10828 .init_hook = alc262_hippo_init_hook,
10830 [ALC262_HIPPO_1] = {
10831 .mixers = { alc262_hippo1_mixer },
10832 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10833 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10834 .dac_nids = alc262_dac_nids,
10836 .dig_out_nid = ALC262_DIGOUT_NID,
10837 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10838 .channel_mode = alc262_modes,
10839 .input_mux = &alc262_capture_source,
10840 .unsol_event = alc262_hippo_unsol_event,
10841 .init_hook = alc262_hippo1_init_hook,
10843 [ALC262_FUJITSU] = {
10844 .mixers = { alc262_fujitsu_mixer },
10845 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10846 alc262_fujitsu_unsol_verbs },
10847 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10848 .dac_nids = alc262_dac_nids,
10850 .dig_out_nid = ALC262_DIGOUT_NID,
10851 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10852 .channel_mode = alc262_modes,
10853 .input_mux = &alc262_fujitsu_capture_source,
10854 .unsol_event = alc262_fujitsu_unsol_event,
10855 .init_hook = alc262_fujitsu_init_hook,
10857 [ALC262_HP_BPC] = {
10858 .mixers = { alc262_HP_BPC_mixer },
10859 .init_verbs = { alc262_HP_BPC_init_verbs },
10860 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10861 .dac_nids = alc262_dac_nids,
10863 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10864 .channel_mode = alc262_modes,
10865 .input_mux = &alc262_HP_capture_source,
10866 .unsol_event = alc262_hp_bpc_unsol_event,
10867 .init_hook = alc262_hp_bpc_automute,
10869 [ALC262_HP_BPC_D7000_WF] = {
10870 .mixers = { alc262_HP_BPC_WildWest_mixer },
10871 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10872 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10873 .dac_nids = alc262_dac_nids,
10875 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10876 .channel_mode = alc262_modes,
10877 .input_mux = &alc262_HP_D7000_capture_source,
10878 .unsol_event = alc262_hp_wildwest_unsol_event,
10879 .init_hook = alc262_hp_wildwest_automute,
10881 [ALC262_HP_BPC_D7000_WL] = {
10882 .mixers = { alc262_HP_BPC_WildWest_mixer,
10883 alc262_HP_BPC_WildWest_option_mixer },
10884 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10885 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10886 .dac_nids = alc262_dac_nids,
10888 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10889 .channel_mode = alc262_modes,
10890 .input_mux = &alc262_HP_D7000_capture_source,
10891 .unsol_event = alc262_hp_wildwest_unsol_event,
10892 .init_hook = alc262_hp_wildwest_automute,
10894 [ALC262_HP_TC_T5735] = {
10895 .mixers = { alc262_hp_t5735_mixer },
10896 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10897 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10898 .dac_nids = alc262_dac_nids,
10900 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10901 .channel_mode = alc262_modes,
10902 .input_mux = &alc262_capture_source,
10903 .unsol_event = alc_automute_amp_unsol_event,
10904 .init_hook = alc262_hp_t5735_init_hook,
10906 [ALC262_HP_RP5700] = {
10907 .mixers = { alc262_hp_rp5700_mixer },
10908 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10909 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10910 .dac_nids = alc262_dac_nids,
10911 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10912 .channel_mode = alc262_modes,
10913 .input_mux = &alc262_hp_rp5700_capture_source,
10915 [ALC262_BENQ_ED8] = {
10916 .mixers = { alc262_base_mixer },
10917 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10918 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10919 .dac_nids = alc262_dac_nids,
10921 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10922 .channel_mode = alc262_modes,
10923 .input_mux = &alc262_capture_source,
10925 [ALC262_SONY_ASSAMD] = {
10926 .mixers = { alc262_sony_mixer },
10927 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10928 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10929 .dac_nids = alc262_dac_nids,
10931 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10932 .channel_mode = alc262_modes,
10933 .input_mux = &alc262_capture_source,
10934 .unsol_event = alc262_hippo_unsol_event,
10935 .init_hook = alc262_hippo_init_hook,
10937 [ALC262_BENQ_T31] = {
10938 .mixers = { alc262_benq_t31_mixer },
10939 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10940 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10941 .dac_nids = alc262_dac_nids,
10943 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10944 .channel_mode = alc262_modes,
10945 .input_mux = &alc262_capture_source,
10946 .unsol_event = alc262_hippo_unsol_event,
10947 .init_hook = alc262_hippo_init_hook,
10950 .mixers = { alc262_ultra_mixer },
10951 .cap_mixer = alc262_ultra_capture_mixer,
10952 .init_verbs = { alc262_ultra_verbs },
10953 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10954 .dac_nids = alc262_dac_nids,
10955 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10956 .channel_mode = alc262_modes,
10957 .input_mux = &alc262_ultra_capture_source,
10958 .adc_nids = alc262_adc_nids, /* ADC0 */
10959 .capsrc_nids = alc262_capsrc_nids,
10960 .num_adc_nids = 1, /* single ADC */
10961 .unsol_event = alc262_ultra_unsol_event,
10962 .init_hook = alc262_ultra_automute,
10964 [ALC262_LENOVO_3000] = {
10965 .mixers = { alc262_lenovo_3000_mixer },
10966 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10967 alc262_lenovo_3000_unsol_verbs },
10968 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10969 .dac_nids = alc262_dac_nids,
10971 .dig_out_nid = ALC262_DIGOUT_NID,
10972 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10973 .channel_mode = alc262_modes,
10974 .input_mux = &alc262_fujitsu_capture_source,
10975 .unsol_event = alc262_lenovo_3000_unsol_event,
10978 .mixers = { alc262_nec_mixer },
10979 .init_verbs = { alc262_nec_verbs },
10980 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10981 .dac_nids = alc262_dac_nids,
10983 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10984 .channel_mode = alc262_modes,
10985 .input_mux = &alc262_capture_source,
10987 [ALC262_TOSHIBA_S06] = {
10988 .mixers = { alc262_toshiba_s06_mixer },
10989 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10990 alc262_eapd_verbs },
10991 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10992 .capsrc_nids = alc262_dmic_capsrc_nids,
10993 .dac_nids = alc262_dac_nids,
10994 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10995 .dig_out_nid = ALC262_DIGOUT_NID,
10996 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10997 .channel_mode = alc262_modes,
10998 .input_mux = &alc262_dmic_capture_source,
10999 .unsol_event = alc262_toshiba_s06_unsol_event,
11000 .init_hook = alc262_toshiba_s06_init_hook,
11002 [ALC262_TOSHIBA_RX1] = {
11003 .mixers = { alc262_toshiba_rx1_mixer },
11004 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11005 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11006 .dac_nids = alc262_dac_nids,
11008 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11009 .channel_mode = alc262_modes,
11010 .input_mux = &alc262_capture_source,
11011 .unsol_event = alc262_hippo_unsol_event,
11012 .init_hook = alc262_hippo_init_hook,
11015 .mixers = { alc262_tyan_mixer },
11016 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11017 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11018 .dac_nids = alc262_dac_nids,
11020 .dig_out_nid = ALC262_DIGOUT_NID,
11021 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11022 .channel_mode = alc262_modes,
11023 .input_mux = &alc262_capture_source,
11024 .unsol_event = alc_automute_amp_unsol_event,
11025 .init_hook = alc262_tyan_init_hook,
11029 static int patch_alc262(struct hda_codec *codec)
11031 struct alc_spec *spec;
11035 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11039 codec->spec = spec;
11041 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11046 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11047 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11048 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11049 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11053 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11055 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11059 if (board_config < 0) {
11060 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11061 "trying auto-probe from BIOS...\n");
11062 board_config = ALC262_AUTO;
11065 if (board_config == ALC262_AUTO) {
11066 /* automatic parse from the BIOS config */
11067 err = alc262_parse_auto_config(codec);
11073 "hda_codec: Cannot set up configuration "
11074 "from BIOS. Using base mode...\n");
11075 board_config = ALC262_BASIC;
11079 if (!spec->no_analog) {
11080 err = snd_hda_attach_beep_device(codec, 0x1);
11087 if (board_config != ALC262_AUTO)
11088 setup_preset(spec, &alc262_presets[board_config]);
11090 spec->stream_name_analog = "ALC262 Analog";
11091 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11092 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11094 spec->stream_name_digital = "ALC262 Digital";
11095 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11096 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11098 spec->capture_style = CAPT_MIX;
11099 if (!spec->adc_nids && spec->input_mux) {
11100 /* check whether NID 0x07 is valid */
11101 unsigned int wcap = get_wcaps(codec, 0x07);
11104 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11105 if (wcap != AC_WID_AUD_IN) {
11106 spec->adc_nids = alc262_adc_nids_alt;
11107 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11108 spec->capsrc_nids = alc262_capsrc_nids_alt;
11110 spec->adc_nids = alc262_adc_nids;
11111 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11112 spec->capsrc_nids = alc262_capsrc_nids;
11115 if (!spec->cap_mixer && !spec->no_analog)
11116 set_capture_mixer(spec);
11117 if (!spec->no_analog)
11118 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11120 spec->vmaster_nid = 0x0c;
11122 codec->patch_ops = alc_patch_ops;
11123 if (board_config == ALC262_AUTO)
11124 spec->init_hook = alc262_auto_init;
11125 #ifdef CONFIG_SND_HDA_POWER_SAVE
11126 if (!spec->loopback.amplist)
11127 spec->loopback.amplist = alc262_loopbacks;
11129 codec->proc_widget_hook = print_realtek_coef;
11135 * ALC268 channel source setting (2 channel)
11137 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11138 #define alc268_modes alc260_modes
11140 static hda_nid_t alc268_dac_nids[2] = {
11145 static hda_nid_t alc268_adc_nids[2] = {
11150 static hda_nid_t alc268_adc_nids_alt[1] = {
11155 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11157 static struct snd_kcontrol_new alc268_base_mixer[] = {
11158 /* output mixer control */
11159 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11160 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11161 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11162 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11163 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11164 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11165 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11169 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11170 /* output mixer control */
11171 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11172 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11173 ALC262_HIPPO_MASTER_SWITCH,
11174 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11175 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11176 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11180 /* bind Beep switches of both NID 0x0f and 0x10 */
11181 static struct hda_bind_ctls alc268_bind_beep_sw = {
11182 .ops = &snd_hda_bind_sw,
11184 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11185 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11190 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11191 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11192 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11196 static struct hda_verb alc268_eapd_verbs[] = {
11197 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11198 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11202 /* Toshiba specific */
11203 static struct hda_verb alc268_toshiba_verbs[] = {
11204 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11208 static struct hda_input_mux alc268_acer_lc_capture_source = {
11216 /* Acer specific */
11217 /* bind volumes of both NID 0x02 and 0x03 */
11218 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11219 .ops = &snd_hda_bind_vol,
11221 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11222 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11227 /* mute/unmute internal speaker according to the hp jack and mute state */
11228 static void alc268_acer_automute(struct hda_codec *codec, int force)
11230 struct alc_spec *spec = codec->spec;
11233 if (force || !spec->sense_updated) {
11234 unsigned int present;
11235 present = snd_hda_codec_read(codec, 0x14, 0,
11236 AC_VERB_GET_PIN_SENSE, 0);
11237 spec->jack_present = (present & 0x80000000) != 0;
11238 spec->sense_updated = 1;
11240 if (spec->jack_present)
11241 mute = HDA_AMP_MUTE; /* mute internal speaker */
11242 else /* unmute internal speaker if necessary */
11243 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11244 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11245 HDA_AMP_MUTE, mute);
11249 /* bind hp and internal speaker mute (with plug check) */
11250 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11251 struct snd_ctl_elem_value *ucontrol)
11253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11254 long *valp = ucontrol->value.integer.value;
11257 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11259 valp[0] ? 0 : HDA_AMP_MUTE);
11260 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11262 valp[1] ? 0 : HDA_AMP_MUTE);
11264 alc268_acer_automute(codec, 0);
11268 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11269 /* output mixer control */
11270 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11273 .name = "Master Playback Switch",
11274 .info = snd_hda_mixer_amp_switch_info,
11275 .get = snd_hda_mixer_amp_switch_get,
11276 .put = alc268_acer_master_sw_put,
11277 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11279 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11283 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11284 /* output mixer control */
11285 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11288 .name = "Master Playback Switch",
11289 .info = snd_hda_mixer_amp_switch_info,
11290 .get = snd_hda_mixer_amp_switch_get,
11291 .put = alc268_acer_master_sw_put,
11292 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11294 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11295 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11296 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11300 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11301 /* output mixer control */
11302 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11304 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11305 .name = "Master Playback Switch",
11306 .info = snd_hda_mixer_amp_switch_info,
11307 .get = snd_hda_mixer_amp_switch_get,
11308 .put = alc268_acer_master_sw_put,
11309 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11311 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11312 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11316 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11317 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11318 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11320 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11321 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11326 static struct hda_verb alc268_acer_verbs[] = {
11327 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11328 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11331 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11333 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11337 /* unsolicited event for HP jack sensing */
11338 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11339 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11341 static void alc268_acer_unsol_event(struct hda_codec *codec,
11344 if ((res >> 26) != ALC880_HP_EVENT)
11346 alc268_acer_automute(codec, 1);
11349 static void alc268_acer_init_hook(struct hda_codec *codec)
11351 alc268_acer_automute(codec, 1);
11354 /* toggle speaker-output according to the hp-jack state */
11355 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11357 unsigned int present;
11358 unsigned char bits;
11360 present = snd_hda_codec_read(codec, 0x15, 0,
11361 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11362 bits = present ? AMP_IN_MUTE(0) : 0;
11363 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11364 AMP_IN_MUTE(0), bits);
11365 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11366 AMP_IN_MUTE(0), bits);
11370 static void alc268_acer_mic_automute(struct hda_codec *codec)
11372 unsigned int present;
11374 present = snd_hda_codec_read(codec, 0x18, 0,
11375 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11376 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11377 present ? 0x0 : 0x6);
11380 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11383 if ((res >> 26) == ALC880_HP_EVENT)
11384 alc268_aspire_one_speaker_automute(codec);
11385 if ((res >> 26) == ALC880_MIC_EVENT)
11386 alc268_acer_mic_automute(codec);
11389 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11391 alc268_aspire_one_speaker_automute(codec);
11392 alc268_acer_mic_automute(codec);
11395 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11396 /* output mixer control */
11397 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11398 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11401 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11402 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11406 static struct hda_verb alc268_dell_verbs[] = {
11407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11408 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11409 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11413 /* mute/unmute internal speaker according to the hp jack and mute state */
11414 static void alc268_dell_init_hook(struct hda_codec *codec)
11416 struct alc_spec *spec = codec->spec;
11418 spec->autocfg.hp_pins[0] = 0x15;
11419 spec->autocfg.speaker_pins[0] = 0x14;
11420 alc_automute_pin(codec);
11423 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11424 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11425 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11426 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11428 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11429 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11430 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11431 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11435 static struct hda_verb alc267_quanta_il1_verbs[] = {
11436 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11437 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11441 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11443 unsigned int present;
11445 present = snd_hda_codec_read(codec, 0x18, 0,
11446 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11447 snd_hda_codec_write(codec, 0x23, 0,
11448 AC_VERB_SET_CONNECT_SEL,
11449 present ? 0x00 : 0x01);
11452 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11454 struct alc_spec *spec = codec->spec;
11456 spec->autocfg.hp_pins[0] = 0x15;
11457 spec->autocfg.speaker_pins[0] = 0x14;
11458 alc_automute_pin(codec);
11459 alc267_quanta_il1_mic_automute(codec);
11462 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11465 switch (res >> 26) {
11466 case ALC880_MIC_EVENT:
11467 alc267_quanta_il1_mic_automute(codec);
11470 alc_sku_unsol_event(codec, res);
11476 * generic initialization of ADC, input mixers and output mixers
11478 static struct hda_verb alc268_base_init_verbs[] = {
11479 /* Unmute DAC0-1 and set vol = 0 */
11480 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11481 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11484 * Set up output mixers (0x0c - 0x0e)
11486 /* set vol=0 to output mixers */
11487 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11488 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11491 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11495 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11496 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11498 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11499 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11500 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11505 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11508 /* set PCBEEP vol = 0, mute connections */
11509 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11511 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11513 /* Unmute Selector 23h,24h and set the default input to mic-in */
11515 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11517 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11524 * generic initialization of ADC, input mixers and output mixers
11526 static struct hda_verb alc268_volume_init_verbs[] = {
11527 /* set output DAC */
11528 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11529 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11531 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11532 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11533 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11534 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11535 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11538 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11539 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11542 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11544 /* set PCBEEP vol = 0, mute connections */
11545 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11546 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11547 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11552 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11553 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11554 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11557 /* The multiple "Capture Source" controls confuse alsamixer
11558 * So call somewhat different..
11560 /* .name = "Capture Source", */
11561 .name = "Input Source",
11563 .info = alc_mux_enum_info,
11564 .get = alc_mux_enum_get,
11565 .put = alc_mux_enum_put,
11570 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11571 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11572 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11573 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11574 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11576 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11577 /* The multiple "Capture Source" controls confuse alsamixer
11578 * So call somewhat different..
11580 /* .name = "Capture Source", */
11581 .name = "Input Source",
11583 .info = alc_mux_enum_info,
11584 .get = alc_mux_enum_get,
11585 .put = alc_mux_enum_put,
11590 static struct hda_input_mux alc268_capture_source = {
11594 { "Front Mic", 0x1 },
11600 static struct hda_input_mux alc268_acer_capture_source = {
11604 { "Internal Mic", 0x1 },
11609 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11613 { "Internal Mic", 0x6 },
11618 #ifdef CONFIG_SND_DEBUG
11619 static struct snd_kcontrol_new alc268_test_mixer[] = {
11620 /* Volume widgets */
11621 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11622 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11623 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11624 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11625 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11626 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11627 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11628 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11629 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11630 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11631 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11632 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11633 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11634 /* The below appears problematic on some hardwares */
11635 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11636 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11637 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11638 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11639 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11641 /* Modes for retasking pin widgets */
11642 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11643 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11644 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11645 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11647 /* Controls for GPIO pins, assuming they are configured as outputs */
11648 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11649 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11650 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11651 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11653 /* Switches to allow the digital SPDIF output pin to be enabled.
11654 * The ALC268 does not have an SPDIF input.
11656 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11658 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11659 * this output to turn on an external amplifier.
11661 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11662 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11668 /* create input playback/capture controls for the given pin */
11669 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11670 const char *ctlname, int idx)
11675 sprintf(name, "%s Playback Volume", ctlname);
11677 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11678 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11682 } else if (nid == 0x15) {
11683 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11684 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11690 sprintf(name, "%s Playback Switch", ctlname);
11691 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11692 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11698 /* add playback controls from the parsed DAC table */
11699 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11700 const struct auto_pin_cfg *cfg)
11705 spec->multiout.num_dacs = 2; /* only use one dac */
11706 spec->multiout.dac_nids = spec->private_dac_nids;
11707 spec->multiout.dac_nids[0] = 2;
11708 spec->multiout.dac_nids[1] = 3;
11710 nid = cfg->line_out_pins[0];
11712 alc268_new_analog_output(spec, nid, "Front", 0);
11714 nid = cfg->speaker_pins[0];
11716 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11717 "Speaker Playback Volume",
11718 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11722 nid = cfg->hp_pins[0];
11724 alc268_new_analog_output(spec, nid, "Headphone", 0);
11726 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11728 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11729 "Mono Playback Switch",
11730 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11737 /* create playback/capture controls for input pins */
11738 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11739 const struct auto_pin_cfg *cfg)
11741 struct hda_input_mux *imux = &spec->private_imux[0];
11744 for (i = 0; i < AUTO_PIN_LAST; i++) {
11745 switch(cfg->input_pins[i]) {
11747 idx1 = 0; /* Mic 1 */
11750 idx1 = 1; /* Mic 2 */
11753 idx1 = 2; /* Line In */
11760 idx1 = 6; /* digital mics */
11765 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11766 imux->items[imux->num_items].index = idx1;
11772 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11774 struct alc_spec *spec = codec->spec;
11775 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11776 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11777 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11778 unsigned int dac_vol1, dac_vol2;
11781 snd_hda_codec_write(codec, speaker_nid, 0,
11782 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11783 snd_hda_codec_write(codec, 0x0f, 0,
11784 AC_VERB_SET_AMP_GAIN_MUTE,
11786 snd_hda_codec_write(codec, 0x10, 0,
11787 AC_VERB_SET_AMP_GAIN_MUTE,
11790 snd_hda_codec_write(codec, 0x0f, 0,
11791 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11792 snd_hda_codec_write(codec, 0x10, 0,
11793 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11796 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11797 if (line_nid == 0x14)
11798 dac_vol2 = AMP_OUT_ZERO;
11799 else if (line_nid == 0x15)
11800 dac_vol1 = AMP_OUT_ZERO;
11801 if (hp_nid == 0x14)
11802 dac_vol2 = AMP_OUT_ZERO;
11803 else if (hp_nid == 0x15)
11804 dac_vol1 = AMP_OUT_ZERO;
11805 if (line_nid != 0x16 || hp_nid != 0x16 ||
11806 spec->autocfg.line_out_pins[1] != 0x16 ||
11807 spec->autocfg.line_out_pins[2] != 0x16)
11808 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11810 snd_hda_codec_write(codec, 0x02, 0,
11811 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11812 snd_hda_codec_write(codec, 0x03, 0,
11813 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11816 /* pcm configuration: identiacal with ALC880 */
11817 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11818 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11819 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11820 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11823 * BIOS auto configuration
11825 static int alc268_parse_auto_config(struct hda_codec *codec)
11827 struct alc_spec *spec = codec->spec;
11829 static hda_nid_t alc268_ignore[] = { 0 };
11831 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11835 if (!spec->autocfg.line_outs) {
11836 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11837 spec->multiout.max_channels = 2;
11838 spec->no_analog = 1;
11841 return 0; /* can't find valid BIOS pin config */
11843 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11846 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11850 spec->multiout.max_channels = 2;
11853 /* digital only support output */
11854 if (spec->autocfg.dig_outs) {
11855 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11856 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11858 if (spec->kctls.list)
11859 add_mixer(spec, spec->kctls.list);
11861 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
11862 add_mixer(spec, alc268_beep_mixer);
11864 add_verb(spec, alc268_volume_init_verbs);
11865 spec->num_mux_defs = 1;
11866 spec->input_mux = &spec->private_imux[0];
11868 err = alc_auto_add_mic_boost(codec);
11875 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11876 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11877 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11879 /* init callback for auto-configuration model -- overriding the default init */
11880 static void alc268_auto_init(struct hda_codec *codec)
11882 struct alc_spec *spec = codec->spec;
11883 alc268_auto_init_multi_out(codec);
11884 alc268_auto_init_hp_out(codec);
11885 alc268_auto_init_mono_speaker_out(codec);
11886 alc268_auto_init_analog_input(codec);
11887 if (spec->unsol_event)
11888 alc_inithook(codec);
11892 * configuration and preset
11894 static const char *alc268_models[ALC268_MODEL_LAST] = {
11895 [ALC267_QUANTA_IL1] = "quanta-il1",
11896 [ALC268_3ST] = "3stack",
11897 [ALC268_TOSHIBA] = "toshiba",
11898 [ALC268_ACER] = "acer",
11899 [ALC268_ACER_DMIC] = "acer-dmic",
11900 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11901 [ALC268_DELL] = "dell",
11902 [ALC268_ZEPTO] = "zepto",
11903 #ifdef CONFIG_SND_DEBUG
11904 [ALC268_TEST] = "test",
11906 [ALC268_AUTO] = "auto",
11909 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11910 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11911 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11912 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11913 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11914 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11915 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11916 ALC268_ACER_ASPIRE_ONE),
11917 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11918 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
11919 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11920 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11921 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11922 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11923 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11924 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11925 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11926 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11927 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11931 static struct alc_config_preset alc268_presets[] = {
11932 [ALC267_QUANTA_IL1] = {
11933 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
11934 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11935 alc267_quanta_il1_verbs },
11936 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11937 .dac_nids = alc268_dac_nids,
11938 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11939 .adc_nids = alc268_adc_nids_alt,
11941 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11942 .channel_mode = alc268_modes,
11943 .input_mux = &alc268_capture_source,
11944 .unsol_event = alc267_quanta_il1_unsol_event,
11945 .init_hook = alc267_quanta_il1_init_hook,
11948 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11949 alc268_beep_mixer },
11950 .init_verbs = { alc268_base_init_verbs },
11951 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11952 .dac_nids = alc268_dac_nids,
11953 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11954 .adc_nids = alc268_adc_nids_alt,
11955 .capsrc_nids = alc268_capsrc_nids,
11957 .dig_out_nid = ALC268_DIGOUT_NID,
11958 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11959 .channel_mode = alc268_modes,
11960 .input_mux = &alc268_capture_source,
11962 [ALC268_TOSHIBA] = {
11963 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
11964 alc268_beep_mixer },
11965 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11966 alc268_toshiba_verbs },
11967 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11968 .dac_nids = alc268_dac_nids,
11969 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11970 .adc_nids = alc268_adc_nids_alt,
11971 .capsrc_nids = alc268_capsrc_nids,
11973 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11974 .channel_mode = alc268_modes,
11975 .input_mux = &alc268_capture_source,
11976 .unsol_event = alc268_toshiba_unsol_event,
11977 .init_hook = alc268_toshiba_init_hook,
11980 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11981 alc268_beep_mixer },
11982 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11983 alc268_acer_verbs },
11984 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11985 .dac_nids = alc268_dac_nids,
11986 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11987 .adc_nids = alc268_adc_nids_alt,
11988 .capsrc_nids = alc268_capsrc_nids,
11990 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11991 .channel_mode = alc268_modes,
11992 .input_mux = &alc268_acer_capture_source,
11993 .unsol_event = alc268_acer_unsol_event,
11994 .init_hook = alc268_acer_init_hook,
11996 [ALC268_ACER_DMIC] = {
11997 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11998 alc268_beep_mixer },
11999 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12000 alc268_acer_verbs },
12001 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12002 .dac_nids = alc268_dac_nids,
12003 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12004 .adc_nids = alc268_adc_nids_alt,
12005 .capsrc_nids = alc268_capsrc_nids,
12007 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12008 .channel_mode = alc268_modes,
12009 .input_mux = &alc268_acer_dmic_capture_source,
12010 .unsol_event = alc268_acer_unsol_event,
12011 .init_hook = alc268_acer_init_hook,
12013 [ALC268_ACER_ASPIRE_ONE] = {
12014 .mixers = { alc268_acer_aspire_one_mixer,
12016 alc268_capture_alt_mixer },
12017 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12018 alc268_acer_aspire_one_verbs },
12019 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12020 .dac_nids = alc268_dac_nids,
12021 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12022 .adc_nids = alc268_adc_nids_alt,
12023 .capsrc_nids = alc268_capsrc_nids,
12025 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12026 .channel_mode = alc268_modes,
12027 .input_mux = &alc268_acer_lc_capture_source,
12028 .unsol_event = alc268_acer_lc_unsol_event,
12029 .init_hook = alc268_acer_lc_init_hook,
12032 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12033 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12034 alc268_dell_verbs },
12035 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12036 .dac_nids = alc268_dac_nids,
12038 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12039 .channel_mode = alc268_modes,
12040 .unsol_event = alc_sku_unsol_event,
12041 .init_hook = alc268_dell_init_hook,
12042 .input_mux = &alc268_capture_source,
12045 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12046 alc268_beep_mixer },
12047 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12048 alc268_toshiba_verbs },
12049 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12050 .dac_nids = alc268_dac_nids,
12051 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12052 .adc_nids = alc268_adc_nids_alt,
12053 .capsrc_nids = alc268_capsrc_nids,
12055 .dig_out_nid = ALC268_DIGOUT_NID,
12056 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12057 .channel_mode = alc268_modes,
12058 .input_mux = &alc268_capture_source,
12059 .unsol_event = alc268_toshiba_unsol_event,
12060 .init_hook = alc268_toshiba_init_hook
12062 #ifdef CONFIG_SND_DEBUG
12064 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12065 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12066 alc268_volume_init_verbs },
12067 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12068 .dac_nids = alc268_dac_nids,
12069 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12070 .adc_nids = alc268_adc_nids_alt,
12071 .capsrc_nids = alc268_capsrc_nids,
12073 .dig_out_nid = ALC268_DIGOUT_NID,
12074 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12075 .channel_mode = alc268_modes,
12076 .input_mux = &alc268_capture_source,
12081 static int patch_alc268(struct hda_codec *codec)
12083 struct alc_spec *spec;
12085 int i, has_beep, err;
12087 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12091 codec->spec = spec;
12093 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12097 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12098 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12099 "trying auto-probe from BIOS...\n");
12100 board_config = ALC268_AUTO;
12103 if (board_config == ALC268_AUTO) {
12104 /* automatic parse from the BIOS config */
12105 err = alc268_parse_auto_config(codec);
12111 "hda_codec: Cannot set up configuration "
12112 "from BIOS. Using base mode...\n");
12113 board_config = ALC268_3ST;
12117 if (board_config != ALC268_AUTO)
12118 setup_preset(spec, &alc268_presets[board_config]);
12120 if (codec->vendor_id == 0x10ec0267) {
12121 spec->stream_name_analog = "ALC267 Analog";
12122 spec->stream_name_digital = "ALC267 Digital";
12124 spec->stream_name_analog = "ALC268 Analog";
12125 spec->stream_name_digital = "ALC268 Digital";
12128 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12129 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12130 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12132 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12135 for (i = 0; i < spec->num_mixers; i++) {
12136 if (spec->mixers[i] == alc268_beep_mixer) {
12143 err = snd_hda_attach_beep_device(codec, 0x1);
12148 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12149 /* override the amp caps for beep generator */
12150 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12151 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12152 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12153 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12154 (0 << AC_AMPCAP_MUTE_SHIFT));
12157 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12158 /* check whether NID 0x07 is valid */
12159 unsigned int wcap = get_wcaps(codec, 0x07);
12163 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12164 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12165 spec->adc_nids = alc268_adc_nids_alt;
12166 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12167 add_mixer(spec, alc268_capture_alt_mixer);
12169 spec->adc_nids = alc268_adc_nids;
12170 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12171 add_mixer(spec, alc268_capture_mixer);
12173 spec->capsrc_nids = alc268_capsrc_nids;
12174 /* set default input source */
12175 for (i = 0; i < spec->num_adc_nids; i++)
12176 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12177 0, AC_VERB_SET_CONNECT_SEL,
12178 spec->input_mux->items[0].index);
12181 spec->vmaster_nid = 0x02;
12183 codec->patch_ops = alc_patch_ops;
12184 if (board_config == ALC268_AUTO)
12185 spec->init_hook = alc268_auto_init;
12187 codec->proc_widget_hook = print_realtek_coef;
12193 * ALC269 channel source setting (2 channel)
12195 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12197 #define alc269_dac_nids alc260_dac_nids
12199 static hda_nid_t alc269_adc_nids[1] = {
12204 static hda_nid_t alc269_capsrc_nids[1] = {
12208 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12212 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12220 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12228 #define alc269_modes alc260_modes
12229 #define alc269_capture_source alc880_lg_lw_capture_source
12231 static struct snd_kcontrol_new alc269_base_mixer[] = {
12232 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12233 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12235 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12236 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12238 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12239 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12241 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12243 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12247 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12248 /* output mixer control */
12249 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12252 .name = "Master Playback Switch",
12253 .info = snd_hda_mixer_amp_switch_info,
12254 .get = snd_hda_mixer_amp_switch_get,
12255 .put = alc268_acer_master_sw_put,
12256 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12258 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12259 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12260 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12261 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12262 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12263 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12267 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12268 /* output mixer control */
12269 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12272 .name = "Master Playback Switch",
12273 .info = snd_hda_mixer_amp_switch_info,
12274 .get = snd_hda_mixer_amp_switch_get,
12275 .put = alc268_acer_master_sw_put,
12276 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12279 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12280 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12281 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12282 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12283 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12284 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12285 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12286 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12290 /* bind volumes of both NID 0x0c and 0x0d */
12291 static struct hda_bind_ctls alc269_epc_bind_vol = {
12292 .ops = &snd_hda_bind_vol,
12294 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12295 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12300 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12301 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12302 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12303 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12307 /* capture mixer elements */
12308 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12309 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12310 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12311 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12316 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12317 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12318 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12319 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12323 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12324 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12325 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12327 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12328 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12329 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12333 static struct hda_verb alc269_lifebook_verbs[] = {
12334 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12335 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12336 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12341 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12343 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12347 /* toggle speaker-output according to the hp-jack state */
12348 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12350 unsigned int present;
12351 unsigned char bits;
12353 present = snd_hda_codec_read(codec, 0x15, 0,
12354 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12355 bits = present ? AMP_IN_MUTE(0) : 0;
12356 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12357 AMP_IN_MUTE(0), bits);
12358 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12359 AMP_IN_MUTE(0), bits);
12361 snd_hda_codec_write(codec, 0x20, 0,
12362 AC_VERB_SET_COEF_INDEX, 0x0c);
12363 snd_hda_codec_write(codec, 0x20, 0,
12364 AC_VERB_SET_PROC_COEF, 0x680);
12366 snd_hda_codec_write(codec, 0x20, 0,
12367 AC_VERB_SET_COEF_INDEX, 0x0c);
12368 snd_hda_codec_write(codec, 0x20, 0,
12369 AC_VERB_SET_PROC_COEF, 0x480);
12372 /* toggle speaker-output according to the hp-jacks state */
12373 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12375 unsigned int present;
12376 unsigned char bits;
12378 /* Check laptop headphone socket */
12379 present = snd_hda_codec_read(codec, 0x15, 0,
12380 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12382 /* Check port replicator headphone socket */
12383 present |= snd_hda_codec_read(codec, 0x1a, 0,
12384 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12386 bits = present ? AMP_IN_MUTE(0) : 0;
12387 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12388 AMP_IN_MUTE(0), bits);
12389 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12390 AMP_IN_MUTE(0), bits);
12392 snd_hda_codec_write(codec, 0x20, 0,
12393 AC_VERB_SET_COEF_INDEX, 0x0c);
12394 snd_hda_codec_write(codec, 0x20, 0,
12395 AC_VERB_SET_PROC_COEF, 0x680);
12397 snd_hda_codec_write(codec, 0x20, 0,
12398 AC_VERB_SET_COEF_INDEX, 0x0c);
12399 snd_hda_codec_write(codec, 0x20, 0,
12400 AC_VERB_SET_PROC_COEF, 0x480);
12403 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12405 unsigned int present;
12407 present = snd_hda_codec_read(codec, 0x18, 0,
12408 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12409 snd_hda_codec_write(codec, 0x23, 0,
12410 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12413 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12415 unsigned int present_laptop;
12416 unsigned int present_dock;
12418 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12419 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12421 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12422 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12424 /* Laptop mic port overrides dock mic port, design decision */
12426 snd_hda_codec_write(codec, 0x23, 0,
12427 AC_VERB_SET_CONNECT_SEL, 0x3);
12428 if (present_laptop)
12429 snd_hda_codec_write(codec, 0x23, 0,
12430 AC_VERB_SET_CONNECT_SEL, 0x0);
12431 if (!present_dock && !present_laptop)
12432 snd_hda_codec_write(codec, 0x23, 0,
12433 AC_VERB_SET_CONNECT_SEL, 0x1);
12436 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12439 if ((res >> 26) == ALC880_HP_EVENT)
12440 alc269_quanta_fl1_speaker_automute(codec);
12441 if ((res >> 26) == ALC880_MIC_EVENT)
12442 alc269_quanta_fl1_mic_automute(codec);
12445 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12448 if ((res >> 26) == ALC880_HP_EVENT)
12449 alc269_lifebook_speaker_automute(codec);
12450 if ((res >> 26) == ALC880_MIC_EVENT)
12451 alc269_lifebook_mic_autoswitch(codec);
12454 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12456 alc269_quanta_fl1_speaker_automute(codec);
12457 alc269_quanta_fl1_mic_automute(codec);
12460 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12462 alc269_lifebook_speaker_automute(codec);
12463 alc269_lifebook_mic_autoswitch(codec);
12466 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12468 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12469 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12470 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12471 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12472 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12477 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12479 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12480 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12481 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12482 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12483 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12487 /* toggle speaker-output according to the hp-jack state */
12488 static void alc269_speaker_automute(struct hda_codec *codec)
12490 unsigned int present;
12491 unsigned char bits;
12493 present = snd_hda_codec_read(codec, 0x15, 0,
12494 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12495 bits = present ? AMP_IN_MUTE(0) : 0;
12496 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12497 AMP_IN_MUTE(0), bits);
12498 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12499 AMP_IN_MUTE(0), bits);
12502 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12504 unsigned int present;
12506 present = snd_hda_codec_read(codec, 0x18, 0,
12507 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12508 snd_hda_codec_write(codec, 0x23, 0,
12509 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12512 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12514 unsigned int present;
12516 present = snd_hda_codec_read(codec, 0x18, 0,
12517 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12518 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12519 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12520 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12521 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12524 /* unsolicited event for HP jack sensing */
12525 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12528 if ((res >> 26) == ALC880_HP_EVENT)
12529 alc269_speaker_automute(codec);
12531 if ((res >> 26) == ALC880_MIC_EVENT)
12532 alc269_eeepc_dmic_automute(codec);
12535 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12537 alc269_speaker_automute(codec);
12538 alc269_eeepc_dmic_automute(codec);
12541 /* unsolicited event for HP jack sensing */
12542 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12545 if ((res >> 26) == ALC880_HP_EVENT)
12546 alc269_speaker_automute(codec);
12548 if ((res >> 26) == ALC880_MIC_EVENT)
12549 alc269_eeepc_amic_automute(codec);
12552 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12554 alc269_speaker_automute(codec);
12555 alc269_eeepc_amic_automute(codec);
12559 * generic initialization of ADC, input mixers and output mixers
12561 static struct hda_verb alc269_init_verbs[] = {
12563 * Unmute ADC0 and set the default input to mic-in
12565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12567 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12568 * analog-loopback mixer widget
12569 * Note: PASD motherboards uses the Line In 2 as the input for
12570 * front panel mic (mic 2)
12572 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12580 * Set up output mixers (0x0c - 0x0e)
12582 /* set vol=0 to output mixers */
12583 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12584 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12586 /* set up input amps for analog loopback */
12587 /* Amp Indices: DAC = 0, mixer = 1 */
12588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12592 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12596 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12597 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12598 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12599 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12601 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12603 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12605 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12606 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12607 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12608 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12609 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12611 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12612 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12614 /* FIXME: use matrix-type input source selection */
12615 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12616 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12617 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12618 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12619 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12623 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12624 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12628 /* add playback controls from the parsed DAC table */
12629 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12630 const struct auto_pin_cfg *cfg)
12635 spec->multiout.num_dacs = 1; /* only use one dac */
12636 spec->multiout.dac_nids = spec->private_dac_nids;
12637 spec->multiout.dac_nids[0] = 2;
12639 nid = cfg->line_out_pins[0];
12641 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12642 "Front Playback Volume",
12643 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12646 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12647 "Front Playback Switch",
12648 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12653 nid = cfg->speaker_pins[0];
12655 if (!cfg->line_out_pins[0]) {
12656 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12657 "Speaker Playback Volume",
12658 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12664 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12665 "Speaker Playback Switch",
12666 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12671 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12672 "Speaker Playback Switch",
12673 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12679 nid = cfg->hp_pins[0];
12681 /* spec->multiout.hp_nid = 2; */
12682 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12683 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12684 "Headphone Playback Volume",
12685 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12691 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12692 "Headphone Playback Switch",
12693 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12698 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12699 "Headphone Playback Switch",
12700 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12709 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12710 const struct auto_pin_cfg *cfg)
12714 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12717 /* digital-mic input pin is excluded in alc880_auto_create..()
12718 * because it's under 0x18
12720 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12721 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12722 struct hda_input_mux *imux = &spec->private_imux[0];
12723 imux->items[imux->num_items].label = "Int Mic";
12724 imux->items[imux->num_items].index = 0x05;
12730 #ifdef CONFIG_SND_HDA_POWER_SAVE
12731 #define alc269_loopbacks alc880_loopbacks
12734 /* pcm configuration: identiacal with ALC880 */
12735 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12736 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12737 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12738 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12740 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12744 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12745 /* NID is set in alc_build_pcms */
12747 .open = alc880_playback_pcm_open,
12748 .prepare = alc880_playback_pcm_prepare,
12749 .cleanup = alc880_playback_pcm_cleanup
12753 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12757 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12758 /* NID is set in alc_build_pcms */
12762 * BIOS auto configuration
12764 static int alc269_parse_auto_config(struct hda_codec *codec)
12766 struct alc_spec *spec = codec->spec;
12768 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12770 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12775 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12778 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12782 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12784 if (spec->autocfg.dig_outs)
12785 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12787 if (spec->kctls.list)
12788 add_mixer(spec, spec->kctls.list);
12790 add_verb(spec, alc269_init_verbs);
12791 spec->num_mux_defs = 1;
12792 spec->input_mux = &spec->private_imux[0];
12793 /* set default input source */
12794 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12795 0, AC_VERB_SET_CONNECT_SEL,
12796 spec->input_mux->items[0].index);
12798 err = alc_auto_add_mic_boost(codec);
12802 if (!spec->cap_mixer && !spec->no_analog)
12803 set_capture_mixer(spec);
12808 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12809 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12810 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12813 /* init callback for auto-configuration model -- overriding the default init */
12814 static void alc269_auto_init(struct hda_codec *codec)
12816 struct alc_spec *spec = codec->spec;
12817 alc269_auto_init_multi_out(codec);
12818 alc269_auto_init_hp_out(codec);
12819 alc269_auto_init_analog_input(codec);
12820 if (spec->unsol_event)
12821 alc_inithook(codec);
12825 * configuration and preset
12827 static const char *alc269_models[ALC269_MODEL_LAST] = {
12828 [ALC269_BASIC] = "basic",
12829 [ALC269_QUANTA_FL1] = "quanta",
12830 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12831 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12832 [ALC269_FUJITSU] = "fujitsu",
12833 [ALC269_LIFEBOOK] = "lifebook"
12836 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12837 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12838 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12839 ALC269_ASUS_EEEPC_P703),
12840 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12841 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12842 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12843 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12844 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12845 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12846 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12847 ALC269_ASUS_EEEPC_P901),
12848 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12849 ALC269_ASUS_EEEPC_P901),
12850 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12851 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12852 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12856 static struct alc_config_preset alc269_presets[] = {
12858 .mixers = { alc269_base_mixer },
12859 .init_verbs = { alc269_init_verbs },
12860 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12861 .dac_nids = alc269_dac_nids,
12863 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12864 .channel_mode = alc269_modes,
12865 .input_mux = &alc269_capture_source,
12867 [ALC269_QUANTA_FL1] = {
12868 .mixers = { alc269_quanta_fl1_mixer },
12869 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12870 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12871 .dac_nids = alc269_dac_nids,
12873 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12874 .channel_mode = alc269_modes,
12875 .input_mux = &alc269_capture_source,
12876 .unsol_event = alc269_quanta_fl1_unsol_event,
12877 .init_hook = alc269_quanta_fl1_init_hook,
12879 [ALC269_ASUS_EEEPC_P703] = {
12880 .mixers = { alc269_eeepc_mixer },
12881 .cap_mixer = alc269_epc_capture_mixer,
12882 .init_verbs = { alc269_init_verbs,
12883 alc269_eeepc_amic_init_verbs },
12884 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12885 .dac_nids = alc269_dac_nids,
12887 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12888 .channel_mode = alc269_modes,
12889 .input_mux = &alc269_eeepc_amic_capture_source,
12890 .unsol_event = alc269_eeepc_amic_unsol_event,
12891 .init_hook = alc269_eeepc_amic_inithook,
12893 [ALC269_ASUS_EEEPC_P901] = {
12894 .mixers = { alc269_eeepc_mixer },
12895 .cap_mixer = alc269_epc_capture_mixer,
12896 .init_verbs = { alc269_init_verbs,
12897 alc269_eeepc_dmic_init_verbs },
12898 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12899 .dac_nids = alc269_dac_nids,
12901 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12902 .channel_mode = alc269_modes,
12903 .input_mux = &alc269_eeepc_dmic_capture_source,
12904 .unsol_event = alc269_eeepc_dmic_unsol_event,
12905 .init_hook = alc269_eeepc_dmic_inithook,
12907 [ALC269_FUJITSU] = {
12908 .mixers = { alc269_fujitsu_mixer },
12909 .cap_mixer = alc269_epc_capture_mixer,
12910 .init_verbs = { alc269_init_verbs,
12911 alc269_eeepc_dmic_init_verbs },
12912 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12913 .dac_nids = alc269_dac_nids,
12915 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12916 .channel_mode = alc269_modes,
12917 .input_mux = &alc269_eeepc_dmic_capture_source,
12918 .unsol_event = alc269_eeepc_dmic_unsol_event,
12919 .init_hook = alc269_eeepc_dmic_inithook,
12921 [ALC269_LIFEBOOK] = {
12922 .mixers = { alc269_lifebook_mixer },
12923 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12924 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12925 .dac_nids = alc269_dac_nids,
12927 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12928 .channel_mode = alc269_modes,
12929 .input_mux = &alc269_capture_source,
12930 .unsol_event = alc269_lifebook_unsol_event,
12931 .init_hook = alc269_lifebook_init_hook,
12935 static int patch_alc269(struct hda_codec *codec)
12937 struct alc_spec *spec;
12941 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12945 codec->spec = spec;
12947 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12949 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12953 if (board_config < 0) {
12954 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12955 "trying auto-probe from BIOS...\n");
12956 board_config = ALC269_AUTO;
12959 if (board_config == ALC269_AUTO) {
12960 /* automatic parse from the BIOS config */
12961 err = alc269_parse_auto_config(codec);
12967 "hda_codec: Cannot set up configuration "
12968 "from BIOS. Using base mode...\n");
12969 board_config = ALC269_BASIC;
12973 err = snd_hda_attach_beep_device(codec, 0x1);
12979 if (board_config != ALC269_AUTO)
12980 setup_preset(spec, &alc269_presets[board_config]);
12982 spec->stream_name_analog = "ALC269 Analog";
12983 if (codec->subsystem_id == 0x17aa3bf8) {
12984 /* Due to a hardware problem on Lenovo Ideadpad, we need to
12985 * fix the sample rate of analog I/O to 44.1kHz
12987 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
12988 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
12990 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12991 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12993 spec->stream_name_digital = "ALC269 Digital";
12994 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12995 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12997 spec->adc_nids = alc269_adc_nids;
12998 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12999 spec->capsrc_nids = alc269_capsrc_nids;
13000 if (!spec->cap_mixer)
13001 set_capture_mixer(spec);
13002 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13004 codec->patch_ops = alc_patch_ops;
13005 if (board_config == ALC269_AUTO)
13006 spec->init_hook = alc269_auto_init;
13007 #ifdef CONFIG_SND_HDA_POWER_SAVE
13008 if (!spec->loopback.amplist)
13009 spec->loopback.amplist = alc269_loopbacks;
13011 codec->proc_widget_hook = print_realtek_coef;
13017 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13021 * set the path ways for 2 channel output
13022 * need to set the codec line out and mic 1 pin widgets to inputs
13024 static struct hda_verb alc861_threestack_ch2_init[] = {
13025 /* set pin widget 1Ah (line in) for input */
13026 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13027 /* set pin widget 18h (mic1/2) for input, for mic also enable
13030 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13032 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13034 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13035 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13041 * need to set the codec line out and mic 1 pin widgets to outputs
13043 static struct hda_verb alc861_threestack_ch6_init[] = {
13044 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13045 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13046 /* set pin widget 18h (mic1) for output (CLFE)*/
13047 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13049 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13050 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13052 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13054 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13055 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13060 static struct hda_channel_mode alc861_threestack_modes[2] = {
13061 { 2, alc861_threestack_ch2_init },
13062 { 6, alc861_threestack_ch6_init },
13064 /* Set mic1 as input and unmute the mixer */
13065 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13066 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13067 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13070 /* Set mic1 as output and mute mixer */
13071 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13072 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13073 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13077 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13078 { 2, alc861_uniwill_m31_ch2_init },
13079 { 4, alc861_uniwill_m31_ch4_init },
13082 /* Set mic1 and line-in as input and unmute the mixer */
13083 static struct hda_verb alc861_asus_ch2_init[] = {
13084 /* set pin widget 1Ah (line in) for input */
13085 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13086 /* set pin widget 18h (mic1/2) for input, for mic also enable
13089 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13091 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13093 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13094 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13098 /* Set mic1 nad line-in as output and mute mixer */
13099 static struct hda_verb alc861_asus_ch6_init[] = {
13100 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13101 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13102 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13103 /* set pin widget 18h (mic1) for output (CLFE)*/
13104 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13105 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13106 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13107 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13109 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13111 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13112 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13117 static struct hda_channel_mode alc861_asus_modes[2] = {
13118 { 2, alc861_asus_ch2_init },
13119 { 6, alc861_asus_ch6_init },
13124 static struct snd_kcontrol_new alc861_base_mixer[] = {
13125 /* output mixer control */
13126 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13127 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13128 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13129 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13130 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13132 /*Input mixer control */
13133 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13134 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13135 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13136 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13137 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13138 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13140 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13141 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13147 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13148 /* output mixer control */
13149 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13150 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13151 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13152 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13153 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13155 /* Input mixer control */
13156 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13157 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13158 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13159 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13160 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13161 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13163 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13169 .name = "Channel Mode",
13170 .info = alc_ch_mode_info,
13171 .get = alc_ch_mode_get,
13172 .put = alc_ch_mode_put,
13173 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13178 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13179 /* output mixer control */
13180 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13182 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13187 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13188 /* output mixer control */
13189 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13190 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13191 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13192 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13193 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13195 /* Input mixer control */
13196 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13197 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13198 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13199 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13200 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13201 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13203 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13204 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13209 .name = "Channel Mode",
13210 .info = alc_ch_mode_info,
13211 .get = alc_ch_mode_get,
13212 .put = alc_ch_mode_put,
13213 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13218 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13219 /* output mixer control */
13220 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13221 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13222 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13223 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13224 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13226 /* Input mixer control */
13227 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13228 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13229 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13230 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13231 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13232 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13234 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13235 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13240 .name = "Channel Mode",
13241 .info = alc_ch_mode_info,
13242 .get = alc_ch_mode_get,
13243 .put = alc_ch_mode_put,
13244 .private_value = ARRAY_SIZE(alc861_asus_modes),
13249 /* additional mixer */
13250 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13251 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13252 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13257 * generic initialization of ADC, input mixers and output mixers
13259 static struct hda_verb alc861_base_init_verbs[] = {
13261 * Unmute ADC0 and set the default input to mic-in
13263 /* port-A for surround (rear panel) */
13264 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13265 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13266 /* port-B for mic-in (rear panel) with vref */
13267 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13268 /* port-C for line-in (rear panel) */
13269 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13270 /* port-D for Front */
13271 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13272 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13273 /* port-E for HP out (front panel) */
13274 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13275 /* route front PCM to HP */
13276 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13277 /* port-F for mic-in (front panel) with vref */
13278 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13279 /* port-G for CLFE (rear panel) */
13280 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13281 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13282 /* port-H for side (rear panel) */
13283 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13284 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13286 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13287 /* route front mic to ADC1*/
13288 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13289 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13291 /* Unmute DAC0~3 & spdif out*/
13292 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13293 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13294 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13295 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13298 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13299 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13300 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13301 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13302 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13304 /* Unmute Stereo Mixer 15 */
13305 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13310 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13312 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13314 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13316 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13318 /* hp used DAC 3 (Front) */
13319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13325 static struct hda_verb alc861_threestack_init_verbs[] = {
13327 * Unmute ADC0 and set the default input to mic-in
13329 /* port-A for surround (rear panel) */
13330 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13331 /* port-B for mic-in (rear panel) with vref */
13332 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13333 /* port-C for line-in (rear panel) */
13334 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13335 /* port-D for Front */
13336 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13337 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13338 /* port-E for HP out (front panel) */
13339 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13340 /* route front PCM to HP */
13341 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13342 /* port-F for mic-in (front panel) with vref */
13343 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13344 /* port-G for CLFE (rear panel) */
13345 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13346 /* port-H for side (rear panel) */
13347 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13349 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13350 /* route front mic to ADC1*/
13351 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13352 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13353 /* Unmute DAC0~3 & spdif out*/
13354 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13355 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13356 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13357 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13360 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13361 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13362 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13363 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13364 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13366 /* Unmute Stereo Mixer 15 */
13367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13370 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13372 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13373 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13374 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13375 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13377 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13378 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13379 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13380 /* hp used DAC 3 (Front) */
13381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13382 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13386 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13388 * Unmute ADC0 and set the default input to mic-in
13390 /* port-A for surround (rear panel) */
13391 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13392 /* port-B for mic-in (rear panel) with vref */
13393 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13394 /* port-C for line-in (rear panel) */
13395 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13396 /* port-D for Front */
13397 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13398 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13399 /* port-E for HP out (front panel) */
13400 /* this has to be set to VREF80 */
13401 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13402 /* route front PCM to HP */
13403 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13404 /* port-F for mic-in (front panel) with vref */
13405 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13406 /* port-G for CLFE (rear panel) */
13407 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13408 /* port-H for side (rear panel) */
13409 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13411 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13412 /* route front mic to ADC1*/
13413 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13415 /* Unmute DAC0~3 & spdif out*/
13416 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13417 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13418 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13419 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13422 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13423 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13424 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13425 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13426 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13428 /* Unmute Stereo Mixer 15 */
13429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13432 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13434 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13435 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13436 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13437 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13438 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13439 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13440 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13441 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13442 /* hp used DAC 3 (Front) */
13443 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13444 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13448 static struct hda_verb alc861_asus_init_verbs[] = {
13450 * Unmute ADC0 and set the default input to mic-in
13452 /* port-A for surround (rear panel)
13453 * according to codec#0 this is the HP jack
13455 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13456 /* route front PCM to HP */
13457 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13458 /* port-B for mic-in (rear panel) with vref */
13459 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13460 /* port-C for line-in (rear panel) */
13461 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13462 /* port-D for Front */
13463 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13464 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13465 /* port-E for HP out (front panel) */
13466 /* this has to be set to VREF80 */
13467 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13468 /* route front PCM to HP */
13469 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13470 /* port-F for mic-in (front panel) with vref */
13471 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13472 /* port-G for CLFE (rear panel) */
13473 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13474 /* port-H for side (rear panel) */
13475 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13477 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13478 /* route front mic to ADC1*/
13479 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13480 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13481 /* Unmute DAC0~3 & spdif out*/
13482 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13483 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13484 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13485 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13487 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13488 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13490 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13491 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13493 /* Unmute Stereo Mixer 15 */
13494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13499 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13501 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13502 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13503 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13504 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13507 /* hp used DAC 3 (Front) */
13508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13513 /* additional init verbs for ASUS laptops */
13514 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13515 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13516 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13521 * generic initialization of ADC, input mixers and output mixers
13523 static struct hda_verb alc861_auto_init_verbs[] = {
13525 * Unmute ADC0 and set the default input to mic-in
13527 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13528 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13530 /* Unmute DAC0~3 & spdif out*/
13531 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13532 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13533 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13534 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13537 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13538 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13539 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13540 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13541 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13543 /* Unmute Stereo Mixer 15 */
13544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13552 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13559 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13560 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13561 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13562 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13563 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13564 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13565 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13567 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13572 static struct hda_verb alc861_toshiba_init_verbs[] = {
13573 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13578 /* toggle speaker-output according to the hp-jack state */
13579 static void alc861_toshiba_automute(struct hda_codec *codec)
13581 unsigned int present;
13583 present = snd_hda_codec_read(codec, 0x0f, 0,
13584 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13585 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13586 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13587 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13588 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13591 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13594 if ((res >> 26) == ALC880_HP_EVENT)
13595 alc861_toshiba_automute(codec);
13598 /* pcm configuration: identiacal with ALC880 */
13599 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13600 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13601 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13602 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13605 #define ALC861_DIGOUT_NID 0x07
13607 static struct hda_channel_mode alc861_8ch_modes[1] = {
13611 static hda_nid_t alc861_dac_nids[4] = {
13612 /* front, surround, clfe, side */
13613 0x03, 0x06, 0x05, 0x04
13616 static hda_nid_t alc660_dac_nids[3] = {
13617 /* front, clfe, surround */
13621 static hda_nid_t alc861_adc_nids[1] = {
13626 static struct hda_input_mux alc861_capture_source = {
13630 { "Front Mic", 0x3 },
13637 /* fill in the dac_nids table from the parsed pin configuration */
13638 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13639 const struct auto_pin_cfg *cfg)
13644 spec->multiout.dac_nids = spec->private_dac_nids;
13645 for (i = 0; i < cfg->line_outs; i++) {
13646 nid = cfg->line_out_pins[i];
13648 if (i >= ARRAY_SIZE(alc861_dac_nids))
13650 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13653 spec->multiout.num_dacs = cfg->line_outs;
13657 /* add playback controls from the parsed DAC table */
13658 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13659 const struct auto_pin_cfg *cfg)
13662 static const char *chname[4] = {
13663 "Front", "Surround", NULL /*CLFE*/, "Side"
13668 for (i = 0; i < cfg->line_outs; i++) {
13669 nid = spec->multiout.dac_nids[i];
13674 err = add_control(spec, ALC_CTL_BIND_MUTE,
13675 "Center Playback Switch",
13676 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13680 err = add_control(spec, ALC_CTL_BIND_MUTE,
13681 "LFE Playback Switch",
13682 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13687 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13689 if (nid == alc861_dac_nids[idx])
13691 sprintf(name, "%s Playback Switch", chname[idx]);
13692 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13693 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13702 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13710 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13712 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13713 "Headphone Playback Switch",
13714 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13717 spec->multiout.hp_nid = nid;
13722 /* create playback/capture controls for input pins */
13723 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13724 const struct auto_pin_cfg *cfg)
13726 struct hda_input_mux *imux = &spec->private_imux[0];
13727 int i, err, idx, idx1;
13729 for (i = 0; i < AUTO_PIN_LAST; i++) {
13730 switch (cfg->input_pins[i]) {
13733 idx = 2; /* Line In */
13737 idx = 2; /* Line In */
13741 idx = 1; /* Mic In */
13745 idx = 1; /* Mic In */
13755 err = new_analog_input(spec, cfg->input_pins[i],
13756 auto_pin_cfg_labels[i], idx, 0x15);
13760 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13761 imux->items[imux->num_items].index = idx1;
13767 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13769 int pin_type, int dac_idx)
13771 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13773 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13777 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13779 struct alc_spec *spec = codec->spec;
13782 for (i = 0; i < spec->autocfg.line_outs; i++) {
13783 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13784 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13786 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13787 spec->multiout.dac_nids[i]);
13791 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13793 struct alc_spec *spec = codec->spec;
13796 pin = spec->autocfg.hp_pins[0];
13797 if (pin) /* connect to front */
13798 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13799 spec->multiout.dac_nids[0]);
13800 pin = spec->autocfg.speaker_pins[0];
13802 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13805 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13807 struct alc_spec *spec = codec->spec;
13810 for (i = 0; i < AUTO_PIN_LAST; i++) {
13811 hda_nid_t nid = spec->autocfg.input_pins[i];
13812 if (nid >= 0x0c && nid <= 0x11)
13813 alc_set_input_pin(codec, nid, i);
13817 /* parse the BIOS configuration and set up the alc_spec */
13818 /* return 1 if successful, 0 if the proper config is not found,
13819 * or a negative error code
13821 static int alc861_parse_auto_config(struct hda_codec *codec)
13823 struct alc_spec *spec = codec->spec;
13825 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13827 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13831 if (!spec->autocfg.line_outs)
13832 return 0; /* can't find valid BIOS pin config */
13834 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13837 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13840 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13843 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13847 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13849 if (spec->autocfg.dig_outs)
13850 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13852 if (spec->kctls.list)
13853 add_mixer(spec, spec->kctls.list);
13855 add_verb(spec, alc861_auto_init_verbs);
13857 spec->num_mux_defs = 1;
13858 spec->input_mux = &spec->private_imux[0];
13860 spec->adc_nids = alc861_adc_nids;
13861 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13862 set_capture_mixer(spec);
13864 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13869 /* additional initialization for auto-configuration model */
13870 static void alc861_auto_init(struct hda_codec *codec)
13872 struct alc_spec *spec = codec->spec;
13873 alc861_auto_init_multi_out(codec);
13874 alc861_auto_init_hp_out(codec);
13875 alc861_auto_init_analog_input(codec);
13876 if (spec->unsol_event)
13877 alc_inithook(codec);
13880 #ifdef CONFIG_SND_HDA_POWER_SAVE
13881 static struct hda_amp_list alc861_loopbacks[] = {
13882 { 0x15, HDA_INPUT, 0 },
13883 { 0x15, HDA_INPUT, 1 },
13884 { 0x15, HDA_INPUT, 2 },
13885 { 0x15, HDA_INPUT, 3 },
13892 * configuration and preset
13894 static const char *alc861_models[ALC861_MODEL_LAST] = {
13895 [ALC861_3ST] = "3stack",
13896 [ALC660_3ST] = "3stack-660",
13897 [ALC861_3ST_DIG] = "3stack-dig",
13898 [ALC861_6ST_DIG] = "6stack-dig",
13899 [ALC861_UNIWILL_M31] = "uniwill-m31",
13900 [ALC861_TOSHIBA] = "toshiba",
13901 [ALC861_ASUS] = "asus",
13902 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13903 [ALC861_AUTO] = "auto",
13906 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13907 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13908 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13909 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13910 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13911 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13912 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13913 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13914 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13915 * Any other models that need this preset?
13917 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13918 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13919 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13920 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13921 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13922 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13923 /* FIXME: the below seems conflict */
13924 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13925 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13926 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13930 static struct alc_config_preset alc861_presets[] = {
13932 .mixers = { alc861_3ST_mixer },
13933 .init_verbs = { alc861_threestack_init_verbs },
13934 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13935 .dac_nids = alc861_dac_nids,
13936 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13937 .channel_mode = alc861_threestack_modes,
13939 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13940 .adc_nids = alc861_adc_nids,
13941 .input_mux = &alc861_capture_source,
13943 [ALC861_3ST_DIG] = {
13944 .mixers = { alc861_base_mixer },
13945 .init_verbs = { alc861_threestack_init_verbs },
13946 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13947 .dac_nids = alc861_dac_nids,
13948 .dig_out_nid = ALC861_DIGOUT_NID,
13949 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13950 .channel_mode = alc861_threestack_modes,
13952 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13953 .adc_nids = alc861_adc_nids,
13954 .input_mux = &alc861_capture_source,
13956 [ALC861_6ST_DIG] = {
13957 .mixers = { alc861_base_mixer },
13958 .init_verbs = { alc861_base_init_verbs },
13959 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13960 .dac_nids = alc861_dac_nids,
13961 .dig_out_nid = ALC861_DIGOUT_NID,
13962 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13963 .channel_mode = alc861_8ch_modes,
13964 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13965 .adc_nids = alc861_adc_nids,
13966 .input_mux = &alc861_capture_source,
13969 .mixers = { alc861_3ST_mixer },
13970 .init_verbs = { alc861_threestack_init_verbs },
13971 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13972 .dac_nids = alc660_dac_nids,
13973 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13974 .channel_mode = alc861_threestack_modes,
13976 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13977 .adc_nids = alc861_adc_nids,
13978 .input_mux = &alc861_capture_source,
13980 [ALC861_UNIWILL_M31] = {
13981 .mixers = { alc861_uniwill_m31_mixer },
13982 .init_verbs = { alc861_uniwill_m31_init_verbs },
13983 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13984 .dac_nids = alc861_dac_nids,
13985 .dig_out_nid = ALC861_DIGOUT_NID,
13986 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13987 .channel_mode = alc861_uniwill_m31_modes,
13989 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13990 .adc_nids = alc861_adc_nids,
13991 .input_mux = &alc861_capture_source,
13993 [ALC861_TOSHIBA] = {
13994 .mixers = { alc861_toshiba_mixer },
13995 .init_verbs = { alc861_base_init_verbs,
13996 alc861_toshiba_init_verbs },
13997 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13998 .dac_nids = alc861_dac_nids,
13999 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14000 .channel_mode = alc883_3ST_2ch_modes,
14001 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14002 .adc_nids = alc861_adc_nids,
14003 .input_mux = &alc861_capture_source,
14004 .unsol_event = alc861_toshiba_unsol_event,
14005 .init_hook = alc861_toshiba_automute,
14008 .mixers = { alc861_asus_mixer },
14009 .init_verbs = { alc861_asus_init_verbs },
14010 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14011 .dac_nids = alc861_dac_nids,
14012 .dig_out_nid = ALC861_DIGOUT_NID,
14013 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14014 .channel_mode = alc861_asus_modes,
14017 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14018 .adc_nids = alc861_adc_nids,
14019 .input_mux = &alc861_capture_source,
14021 [ALC861_ASUS_LAPTOP] = {
14022 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14023 .init_verbs = { alc861_asus_init_verbs,
14024 alc861_asus_laptop_init_verbs },
14025 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14026 .dac_nids = alc861_dac_nids,
14027 .dig_out_nid = ALC861_DIGOUT_NID,
14028 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14029 .channel_mode = alc883_3ST_2ch_modes,
14031 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14032 .adc_nids = alc861_adc_nids,
14033 .input_mux = &alc861_capture_source,
14038 static int patch_alc861(struct hda_codec *codec)
14040 struct alc_spec *spec;
14044 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14048 codec->spec = spec;
14050 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14054 if (board_config < 0) {
14055 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14056 "trying auto-probe from BIOS...\n");
14057 board_config = ALC861_AUTO;
14060 if (board_config == ALC861_AUTO) {
14061 /* automatic parse from the BIOS config */
14062 err = alc861_parse_auto_config(codec);
14068 "hda_codec: Cannot set up configuration "
14069 "from BIOS. Using base mode...\n");
14070 board_config = ALC861_3ST_DIG;
14074 err = snd_hda_attach_beep_device(codec, 0x23);
14080 if (board_config != ALC861_AUTO)
14081 setup_preset(spec, &alc861_presets[board_config]);
14083 spec->stream_name_analog = "ALC861 Analog";
14084 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14085 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14087 spec->stream_name_digital = "ALC861 Digital";
14088 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14089 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14091 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14093 spec->vmaster_nid = 0x03;
14095 codec->patch_ops = alc_patch_ops;
14096 if (board_config == ALC861_AUTO)
14097 spec->init_hook = alc861_auto_init;
14098 #ifdef CONFIG_SND_HDA_POWER_SAVE
14099 if (!spec->loopback.amplist)
14100 spec->loopback.amplist = alc861_loopbacks;
14102 codec->proc_widget_hook = print_realtek_coef;
14108 * ALC861-VD support
14112 * In addition, an independent DAC
14114 #define ALC861VD_DIGOUT_NID 0x06
14116 static hda_nid_t alc861vd_dac_nids[4] = {
14117 /* front, surr, clfe, side surr */
14118 0x02, 0x03, 0x04, 0x05
14121 /* dac_nids for ALC660vd are in a different order - according to
14122 * Realtek's driver.
14123 * This should probably tesult in a different mixer for 6stack models
14124 * of ALC660vd codecs, but for now there is only 3stack mixer
14125 * - and it is the same as in 861vd.
14126 * adc_nids in ALC660vd are (is) the same as in 861vd
14128 static hda_nid_t alc660vd_dac_nids[3] = {
14129 /* front, rear, clfe, rear_surr */
14133 static hda_nid_t alc861vd_adc_nids[1] = {
14138 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14141 /* FIXME: should be a matrix-type input source selection */
14142 static struct hda_input_mux alc861vd_capture_source = {
14146 { "Front Mic", 0x1 },
14152 static struct hda_input_mux alc861vd_dallas_capture_source = {
14155 { "Ext Mic", 0x0 },
14156 { "Int Mic", 0x1 },
14160 static struct hda_input_mux alc861vd_hp_capture_source = {
14163 { "Front Mic", 0x0 },
14164 { "ATAPI Mic", 0x1 },
14171 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14178 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14179 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14180 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14181 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14182 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14189 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14190 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14191 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14192 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14193 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14197 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14198 { 6, alc861vd_6stack_ch6_init },
14199 { 8, alc861vd_6stack_ch8_init },
14202 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14205 .name = "Channel Mode",
14206 .info = alc_ch_mode_info,
14207 .get = alc_ch_mode_get,
14208 .put = alc_ch_mode_put,
14213 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14214 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14216 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14217 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14218 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14220 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14221 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14230 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14231 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14233 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14235 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14236 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14239 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14240 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14241 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14243 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14244 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14246 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14247 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14252 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14253 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14254 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14258 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14262 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14263 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14264 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14266 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14267 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14269 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14270 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14275 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14276 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14277 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14278 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14280 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14282 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14283 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14284 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14286 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14287 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14288 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14290 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14291 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14296 /* Pin assignment: Speaker=0x14, HP = 0x15,
14297 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14299 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14300 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14301 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14302 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14303 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14304 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14305 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14306 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14307 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14308 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14309 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14313 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14314 * Front Mic=0x18, ATAPI Mic = 0x19,
14316 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14317 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14318 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14319 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14320 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14321 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14322 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14323 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14324 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14330 * generic initialization of ADC, input mixers and output mixers
14332 static struct hda_verb alc861vd_volume_init_verbs[] = {
14334 * Unmute ADC0 and set the default input to mic-in
14336 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14337 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14339 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14340 * the analog-loopback mixer widget
14342 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14346 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14347 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14349 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14351 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14353 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14356 * Set up output mixers (0x02 - 0x05)
14358 /* set vol=0 to output mixers */
14359 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14360 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14361 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14362 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14364 /* set up input amps for analog loopback */
14365 /* Amp Indices: DAC = 0, mixer = 1 */
14366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14379 * 3-stack pin configuration:
14380 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14382 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14384 * Set pin mode and muting
14386 /* set front pin widgets 0x14 for output */
14387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14388 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14389 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14391 /* Mic (rear) pin: input vref at 80% */
14392 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14393 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14394 /* Front Mic pin: input vref at 80% */
14395 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14396 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14397 /* Line In pin: input */
14398 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14399 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14400 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14403 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14404 /* CD pin widget for input */
14405 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14411 * 6-stack pin configuration:
14413 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14415 * Set pin mode and muting
14417 /* set front pin widgets 0x14 for output */
14418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14420 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14422 /* Rear Pin: output 1 (0x0d) */
14423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14425 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14426 /* CLFE Pin: output 2 (0x0e) */
14427 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14428 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14429 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14430 /* Side Pin: output 3 (0x0f) */
14431 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14432 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14433 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14435 /* Mic (rear) pin: input vref at 80% */
14436 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14437 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14438 /* Front Mic pin: input vref at 80% */
14439 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14440 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14441 /* Line In pin: input */
14442 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14443 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14444 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14445 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14446 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14447 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14448 /* CD pin widget for input */
14449 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14454 static struct hda_verb alc861vd_eapd_verbs[] = {
14455 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14459 static struct hda_verb alc660vd_eapd_verbs[] = {
14460 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14461 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14465 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14468 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14469 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14470 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14474 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14476 unsigned int present;
14477 unsigned char bits;
14479 present = snd_hda_codec_read(codec, 0x18, 0,
14480 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14481 bits = present ? HDA_AMP_MUTE : 0;
14482 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14483 HDA_AMP_MUTE, bits);
14486 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14488 struct alc_spec *spec = codec->spec;
14490 spec->autocfg.hp_pins[0] = 0x1b;
14491 spec->autocfg.speaker_pins[0] = 0x14;
14492 alc_automute_amp(codec);
14493 alc861vd_lenovo_mic_automute(codec);
14496 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14499 switch (res >> 26) {
14500 case ALC880_MIC_EVENT:
14501 alc861vd_lenovo_mic_automute(codec);
14504 alc_automute_amp_unsol_event(codec, res);
14509 static struct hda_verb alc861vd_dallas_verbs[] = {
14510 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14511 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14512 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14513 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14515 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14522 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14529 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14530 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14531 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14533 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14534 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14535 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14536 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14537 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14539 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14540 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14545 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14547 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14548 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14549 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14554 /* toggle speaker-output according to the hp-jack state */
14555 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14557 struct alc_spec *spec = codec->spec;
14559 spec->autocfg.hp_pins[0] = 0x15;
14560 spec->autocfg.speaker_pins[0] = 0x14;
14561 alc_automute_amp(codec);
14564 #ifdef CONFIG_SND_HDA_POWER_SAVE
14565 #define alc861vd_loopbacks alc880_loopbacks
14568 /* pcm configuration: identiacal with ALC880 */
14569 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14570 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14571 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14572 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14575 * configuration and preset
14577 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14578 [ALC660VD_3ST] = "3stack-660",
14579 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14580 [ALC660VD_ASUS_V1S] = "asus-v1s",
14581 [ALC861VD_3ST] = "3stack",
14582 [ALC861VD_3ST_DIG] = "3stack-digout",
14583 [ALC861VD_6ST_DIG] = "6stack-digout",
14584 [ALC861VD_LENOVO] = "lenovo",
14585 [ALC861VD_DALLAS] = "dallas",
14586 [ALC861VD_HP] = "hp",
14587 [ALC861VD_AUTO] = "auto",
14590 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14591 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14592 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14593 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14594 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14595 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14596 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14597 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14598 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14599 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14600 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14601 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14602 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14603 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14604 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14605 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14609 static struct alc_config_preset alc861vd_presets[] = {
14611 .mixers = { alc861vd_3st_mixer },
14612 .init_verbs = { alc861vd_volume_init_verbs,
14613 alc861vd_3stack_init_verbs },
14614 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14615 .dac_nids = alc660vd_dac_nids,
14616 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14617 .channel_mode = alc861vd_3stack_2ch_modes,
14618 .input_mux = &alc861vd_capture_source,
14620 [ALC660VD_3ST_DIG] = {
14621 .mixers = { alc861vd_3st_mixer },
14622 .init_verbs = { alc861vd_volume_init_verbs,
14623 alc861vd_3stack_init_verbs },
14624 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14625 .dac_nids = alc660vd_dac_nids,
14626 .dig_out_nid = ALC861VD_DIGOUT_NID,
14627 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14628 .channel_mode = alc861vd_3stack_2ch_modes,
14629 .input_mux = &alc861vd_capture_source,
14632 .mixers = { alc861vd_3st_mixer },
14633 .init_verbs = { alc861vd_volume_init_verbs,
14634 alc861vd_3stack_init_verbs },
14635 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14636 .dac_nids = alc861vd_dac_nids,
14637 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14638 .channel_mode = alc861vd_3stack_2ch_modes,
14639 .input_mux = &alc861vd_capture_source,
14641 [ALC861VD_3ST_DIG] = {
14642 .mixers = { alc861vd_3st_mixer },
14643 .init_verbs = { alc861vd_volume_init_verbs,
14644 alc861vd_3stack_init_verbs },
14645 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14646 .dac_nids = alc861vd_dac_nids,
14647 .dig_out_nid = ALC861VD_DIGOUT_NID,
14648 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14649 .channel_mode = alc861vd_3stack_2ch_modes,
14650 .input_mux = &alc861vd_capture_source,
14652 [ALC861VD_6ST_DIG] = {
14653 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14654 .init_verbs = { alc861vd_volume_init_verbs,
14655 alc861vd_6stack_init_verbs },
14656 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14657 .dac_nids = alc861vd_dac_nids,
14658 .dig_out_nid = ALC861VD_DIGOUT_NID,
14659 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14660 .channel_mode = alc861vd_6stack_modes,
14661 .input_mux = &alc861vd_capture_source,
14663 [ALC861VD_LENOVO] = {
14664 .mixers = { alc861vd_lenovo_mixer },
14665 .init_verbs = { alc861vd_volume_init_verbs,
14666 alc861vd_3stack_init_verbs,
14667 alc861vd_eapd_verbs,
14668 alc861vd_lenovo_unsol_verbs },
14669 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14670 .dac_nids = alc660vd_dac_nids,
14671 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14672 .channel_mode = alc861vd_3stack_2ch_modes,
14673 .input_mux = &alc861vd_capture_source,
14674 .unsol_event = alc861vd_lenovo_unsol_event,
14675 .init_hook = alc861vd_lenovo_init_hook,
14677 [ALC861VD_DALLAS] = {
14678 .mixers = { alc861vd_dallas_mixer },
14679 .init_verbs = { alc861vd_dallas_verbs },
14680 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14681 .dac_nids = alc861vd_dac_nids,
14682 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14683 .channel_mode = alc861vd_3stack_2ch_modes,
14684 .input_mux = &alc861vd_dallas_capture_source,
14685 .unsol_event = alc_automute_amp_unsol_event,
14686 .init_hook = alc861vd_dallas_init_hook,
14689 .mixers = { alc861vd_hp_mixer },
14690 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14691 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14692 .dac_nids = alc861vd_dac_nids,
14693 .dig_out_nid = ALC861VD_DIGOUT_NID,
14694 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14695 .channel_mode = alc861vd_3stack_2ch_modes,
14696 .input_mux = &alc861vd_hp_capture_source,
14697 .unsol_event = alc_automute_amp_unsol_event,
14698 .init_hook = alc861vd_dallas_init_hook,
14700 [ALC660VD_ASUS_V1S] = {
14701 .mixers = { alc861vd_lenovo_mixer },
14702 .init_verbs = { alc861vd_volume_init_verbs,
14703 alc861vd_3stack_init_verbs,
14704 alc861vd_eapd_verbs,
14705 alc861vd_lenovo_unsol_verbs },
14706 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14707 .dac_nids = alc660vd_dac_nids,
14708 .dig_out_nid = ALC861VD_DIGOUT_NID,
14709 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14710 .channel_mode = alc861vd_3stack_2ch_modes,
14711 .input_mux = &alc861vd_capture_source,
14712 .unsol_event = alc861vd_lenovo_unsol_event,
14713 .init_hook = alc861vd_lenovo_init_hook,
14718 * BIOS auto configuration
14720 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14721 hda_nid_t nid, int pin_type, int dac_idx)
14723 alc_set_pin_output(codec, nid, pin_type);
14726 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14728 struct alc_spec *spec = codec->spec;
14731 for (i = 0; i <= HDA_SIDE; i++) {
14732 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14733 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14735 alc861vd_auto_set_output_and_unmute(codec, nid,
14741 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14743 struct alc_spec *spec = codec->spec;
14746 pin = spec->autocfg.hp_pins[0];
14747 if (pin) /* connect to front and use dac 0 */
14748 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14749 pin = spec->autocfg.speaker_pins[0];
14751 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14754 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14755 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14757 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14759 struct alc_spec *spec = codec->spec;
14762 for (i = 0; i < AUTO_PIN_LAST; i++) {
14763 hda_nid_t nid = spec->autocfg.input_pins[i];
14764 if (alc861vd_is_input_pin(nid)) {
14765 alc_set_input_pin(codec, nid, i);
14766 if (nid != ALC861VD_PIN_CD_NID &&
14767 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14768 snd_hda_codec_write(codec, nid, 0,
14769 AC_VERB_SET_AMP_GAIN_MUTE,
14775 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14777 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14778 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14780 /* add playback controls from the parsed DAC table */
14781 /* Based on ALC880 version. But ALC861VD has separate,
14782 * different NIDs for mute/unmute switch and volume control */
14783 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14784 const struct auto_pin_cfg *cfg)
14787 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14788 hda_nid_t nid_v, nid_s;
14791 for (i = 0; i < cfg->line_outs; i++) {
14792 if (!spec->multiout.dac_nids[i])
14794 nid_v = alc861vd_idx_to_mixer_vol(
14796 spec->multiout.dac_nids[i]));
14797 nid_s = alc861vd_idx_to_mixer_switch(
14799 spec->multiout.dac_nids[i]));
14803 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14804 "Center Playback Volume",
14805 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14809 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14810 "LFE Playback Volume",
14811 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14815 err = add_control(spec, ALC_CTL_BIND_MUTE,
14816 "Center Playback Switch",
14817 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14821 err = add_control(spec, ALC_CTL_BIND_MUTE,
14822 "LFE Playback Switch",
14823 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14828 sprintf(name, "%s Playback Volume", chname[i]);
14829 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14830 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14834 sprintf(name, "%s Playback Switch", chname[i]);
14835 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14836 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14845 /* add playback controls for speaker and HP outputs */
14846 /* Based on ALC880 version. But ALC861VD has separate,
14847 * different NIDs for mute/unmute switch and volume control */
14848 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14849 hda_nid_t pin, const char *pfx)
14851 hda_nid_t nid_v, nid_s;
14858 if (alc880_is_fixed_pin(pin)) {
14859 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14860 /* specify the DAC as the extra output */
14861 if (!spec->multiout.hp_nid)
14862 spec->multiout.hp_nid = nid_v;
14864 spec->multiout.extra_out_nid[0] = nid_v;
14865 /* control HP volume/switch on the output mixer amp */
14866 nid_v = alc861vd_idx_to_mixer_vol(
14867 alc880_fixed_pin_idx(pin));
14868 nid_s = alc861vd_idx_to_mixer_switch(
14869 alc880_fixed_pin_idx(pin));
14871 sprintf(name, "%s Playback Volume", pfx);
14872 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14873 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14876 sprintf(name, "%s Playback Switch", pfx);
14877 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14878 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14881 } else if (alc880_is_multi_pin(pin)) {
14882 /* set manual connection */
14883 /* we have only a switch on HP-out PIN */
14884 sprintf(name, "%s Playback Switch", pfx);
14885 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14886 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14893 /* parse the BIOS configuration and set up the alc_spec
14894 * return 1 if successful, 0 if the proper config is not found,
14895 * or a negative error code
14896 * Based on ALC880 version - had to change it to override
14897 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14898 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14900 struct alc_spec *spec = codec->spec;
14902 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14904 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14908 if (!spec->autocfg.line_outs)
14909 return 0; /* can't find valid BIOS pin config */
14911 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14914 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14917 err = alc861vd_auto_create_extra_out(spec,
14918 spec->autocfg.speaker_pins[0],
14922 err = alc861vd_auto_create_extra_out(spec,
14923 spec->autocfg.hp_pins[0],
14927 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14931 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14933 if (spec->autocfg.dig_outs)
14934 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14936 if (spec->kctls.list)
14937 add_mixer(spec, spec->kctls.list);
14939 add_verb(spec, alc861vd_volume_init_verbs);
14941 spec->num_mux_defs = 1;
14942 spec->input_mux = &spec->private_imux[0];
14944 err = alc_auto_add_mic_boost(codec);
14948 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
14953 /* additional initialization for auto-configuration model */
14954 static void alc861vd_auto_init(struct hda_codec *codec)
14956 struct alc_spec *spec = codec->spec;
14957 alc861vd_auto_init_multi_out(codec);
14958 alc861vd_auto_init_hp_out(codec);
14959 alc861vd_auto_init_analog_input(codec);
14960 alc861vd_auto_init_input_src(codec);
14961 if (spec->unsol_event)
14962 alc_inithook(codec);
14965 static int patch_alc861vd(struct hda_codec *codec)
14967 struct alc_spec *spec;
14968 int err, board_config;
14970 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14974 codec->spec = spec;
14976 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14980 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14981 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14982 "ALC861VD, trying auto-probe from BIOS...\n");
14983 board_config = ALC861VD_AUTO;
14986 if (board_config == ALC861VD_AUTO) {
14987 /* automatic parse from the BIOS config */
14988 err = alc861vd_parse_auto_config(codec);
14994 "hda_codec: Cannot set up configuration "
14995 "from BIOS. Using base mode...\n");
14996 board_config = ALC861VD_3ST;
15000 err = snd_hda_attach_beep_device(codec, 0x23);
15006 if (board_config != ALC861VD_AUTO)
15007 setup_preset(spec, &alc861vd_presets[board_config]);
15009 if (codec->vendor_id == 0x10ec0660) {
15010 spec->stream_name_analog = "ALC660-VD Analog";
15011 spec->stream_name_digital = "ALC660-VD Digital";
15012 /* always turn on EAPD */
15013 add_verb(spec, alc660vd_eapd_verbs);
15015 spec->stream_name_analog = "ALC861VD Analog";
15016 spec->stream_name_digital = "ALC861VD Digital";
15019 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15020 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15022 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15023 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15025 spec->adc_nids = alc861vd_adc_nids;
15026 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15027 spec->capsrc_nids = alc861vd_capsrc_nids;
15028 spec->capture_style = CAPT_MIX;
15030 set_capture_mixer(spec);
15031 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15033 spec->vmaster_nid = 0x02;
15035 codec->patch_ops = alc_patch_ops;
15037 if (board_config == ALC861VD_AUTO)
15038 spec->init_hook = alc861vd_auto_init;
15039 #ifdef CONFIG_SND_HDA_POWER_SAVE
15040 if (!spec->loopback.amplist)
15041 spec->loopback.amplist = alc861vd_loopbacks;
15043 codec->proc_widget_hook = print_realtek_coef;
15051 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15052 * configuration. Each pin widget can choose any input DACs and a mixer.
15053 * Each ADC is connected from a mixer of all inputs. This makes possible
15054 * 6-channel independent captures.
15056 * In addition, an independent DAC for the multi-playback (not used in this
15059 #define ALC662_DIGOUT_NID 0x06
15060 #define ALC662_DIGIN_NID 0x0a
15062 static hda_nid_t alc662_dac_nids[4] = {
15063 /* front, rear, clfe, rear_surr */
15067 static hda_nid_t alc272_dac_nids[2] = {
15071 static hda_nid_t alc662_adc_nids[1] = {
15076 static hda_nid_t alc272_adc_nids[1] = {
15081 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15082 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15086 /* FIXME: should be a matrix-type input source selection */
15087 static struct hda_input_mux alc662_capture_source = {
15091 { "Front Mic", 0x1 },
15097 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15105 static struct hda_input_mux alc662_eeepc_capture_source = {
15113 static struct hda_input_mux alc663_capture_source = {
15117 { "Front Mic", 0x1 },
15122 static struct hda_input_mux alc663_m51va_capture_source = {
15125 { "Ext-Mic", 0x0 },
15130 #if 1 /* set to 0 for testing other input sources below */
15131 static struct hda_input_mux alc272_nc10_capture_source = {
15134 { "Autoselect Mic", 0x0 },
15135 { "Internal Mic", 0x1 },
15139 static struct hda_input_mux alc272_nc10_capture_source = {
15142 { "Autoselect Mic", 0x0 },
15143 { "Internal Mic", 0x1 },
15144 { "In-0x02", 0x2 },
15145 { "In-0x03", 0x3 },
15146 { "In-0x04", 0x4 },
15147 { "In-0x05", 0x5 },
15148 { "In-0x06", 0x6 },
15149 { "In-0x07", 0x7 },
15150 { "In-0x08", 0x8 },
15151 { "In-0x09", 0x9 },
15152 { "In-0x0a", 0x0a },
15153 { "In-0x0b", 0x0b },
15154 { "In-0x0c", 0x0c },
15155 { "In-0x0d", 0x0d },
15156 { "In-0x0e", 0x0e },
15157 { "In-0x0f", 0x0f },
15165 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15172 static struct hda_verb alc662_3ST_ch2_init[] = {
15173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15175 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15176 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15183 static struct hda_verb alc662_3ST_ch6_init[] = {
15184 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15185 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15186 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15187 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15188 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15189 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15193 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15194 { 2, alc662_3ST_ch2_init },
15195 { 6, alc662_3ST_ch6_init },
15201 static struct hda_verb alc662_sixstack_ch6_init[] = {
15202 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15203 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15204 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15211 static struct hda_verb alc662_sixstack_ch8_init[] = {
15212 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15213 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15214 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15218 static struct hda_channel_mode alc662_5stack_modes[2] = {
15219 { 2, alc662_sixstack_ch6_init },
15220 { 6, alc662_sixstack_ch8_init },
15223 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15224 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15227 static struct snd_kcontrol_new alc662_base_mixer[] = {
15228 /* output mixer control */
15229 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15230 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15232 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15233 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15234 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15235 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15236 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15239 /*Input mixer control */
15240 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15241 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15242 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15243 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15244 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15245 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15246 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15247 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15251 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15252 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15253 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15255 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15256 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15257 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15258 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15261 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15266 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15267 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15268 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15270 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15273 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15274 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15287 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15288 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15289 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15290 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15291 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15293 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15294 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15300 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15301 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15302 ALC262_HIPPO_MASTER_SWITCH,
15304 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15305 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15306 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15308 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15309 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15310 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15314 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15315 ALC262_HIPPO_MASTER_SWITCH,
15316 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15317 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15318 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15319 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15320 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15321 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15322 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15328 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15329 .ops = &snd_hda_bind_vol,
15331 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15332 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15337 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15338 .ops = &snd_hda_bind_sw,
15340 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15341 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15346 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15347 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15348 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15354 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15355 .ops = &snd_hda_bind_sw,
15357 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15358 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15359 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15364 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15365 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15366 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15369 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15370 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15375 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15376 .ops = &snd_hda_bind_sw,
15378 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15379 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15380 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15385 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15386 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15387 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15390 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15391 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15395 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15396 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15397 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15398 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15399 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15401 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15402 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15406 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15407 .ops = &snd_hda_bind_vol,
15409 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15410 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15415 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15416 .ops = &snd_hda_bind_sw,
15418 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15419 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15424 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15425 HDA_BIND_VOL("Master Playback Volume",
15426 &alc663_asus_two_bind_master_vol),
15427 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15428 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15435 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15436 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15437 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15439 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15445 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15446 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15449 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15454 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15455 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15459 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15460 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15466 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15467 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15468 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15469 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15473 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15475 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15476 .name = "Channel Mode",
15477 .info = alc_ch_mode_info,
15478 .get = alc_ch_mode_get,
15479 .put = alc_ch_mode_put,
15484 static struct hda_verb alc662_init_verbs[] = {
15485 /* ADC: mute amp left and right */
15486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15487 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15488 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15496 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15499 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15500 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15501 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15503 /* Front Pin: output 0 (0x0c) */
15504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15507 /* Rear Pin: output 1 (0x0d) */
15508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15511 /* CLFE Pin: output 2 (0x0e) */
15512 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15513 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15515 /* Mic (rear) pin: input vref at 80% */
15516 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15517 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15518 /* Front Mic pin: input vref at 80% */
15519 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15520 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15521 /* Line In pin: input */
15522 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15523 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15524 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15526 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15527 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15528 /* CD pin widget for input */
15529 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15531 /* FIXME: use matrix-type input source selection */
15532 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15537 /* always trun on EAPD */
15538 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15539 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15544 static struct hda_verb alc662_sue_init_verbs[] = {
15545 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15550 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15551 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15552 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15556 /* Set Unsolicited Event*/
15557 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15559 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15564 * generic initialization of ADC, input mixers and output mixers
15566 static struct hda_verb alc662_auto_init_verbs[] = {
15568 * Unmute ADC and set the default input to mic-in
15570 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15571 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15573 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15575 * Note: PASD motherboards uses the Line In 2 as the input for front
15576 * panel mic (mic 2)
15578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15586 * Set up output mixers (0x0c - 0x0f)
15588 /* set vol=0 to output mixers */
15589 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15590 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15591 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15593 /* set up input amps for analog loopback */
15594 /* Amp Indices: DAC = 0, mixer = 1 */
15595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15596 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15603 /* FIXME: use matrix-type input source selection */
15604 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15607 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15611 /* additional verbs for ALC663 */
15612 static struct hda_verb alc663_auto_init_verbs[] = {
15613 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15614 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15618 static struct hda_verb alc663_m51va_init_verbs[] = {
15619 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15620 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15621 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15622 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15623 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15626 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15627 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15631 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15632 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15633 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15634 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15635 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15636 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15637 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15638 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15642 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15643 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15644 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15645 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15646 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15647 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15648 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15649 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15650 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15654 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15655 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15657 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15660 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15661 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15665 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15666 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15667 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15668 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15669 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15670 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15675 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15676 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15677 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15681 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15683 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15684 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15685 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15686 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15690 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15691 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15692 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15693 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15697 static struct hda_verb alc663_g71v_init_verbs[] = {
15698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15699 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15700 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15702 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15703 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15704 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15706 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15707 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15708 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15712 static struct hda_verb alc663_g50v_init_verbs[] = {
15713 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15714 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15715 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15717 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15718 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15722 static struct hda_verb alc662_ecs_init_verbs[] = {
15723 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15725 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15730 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15731 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15732 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15734 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15735 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15736 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15737 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15738 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15739 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15740 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15741 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15745 static struct hda_verb alc272_dell_init_verbs[] = {
15746 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15747 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15750 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15751 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15755 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15756 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15760 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15761 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15762 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15766 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15767 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15768 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15772 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15774 unsigned int present;
15775 unsigned char bits;
15777 present = snd_hda_codec_read(codec, 0x14, 0,
15778 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15779 bits = present ? HDA_AMP_MUTE : 0;
15780 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15781 HDA_AMP_MUTE, bits);
15784 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15786 unsigned int present;
15787 unsigned char bits;
15789 present = snd_hda_codec_read(codec, 0x1b, 0,
15790 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15791 bits = present ? HDA_AMP_MUTE : 0;
15792 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15793 HDA_AMP_MUTE, bits);
15794 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15795 HDA_AMP_MUTE, bits);
15798 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15801 if ((res >> 26) == ALC880_HP_EVENT)
15802 alc662_lenovo_101e_all_automute(codec);
15803 if ((res >> 26) == ALC880_FRONT_EVENT)
15804 alc662_lenovo_101e_ispeaker_automute(codec);
15807 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15809 unsigned int present;
15811 present = snd_hda_codec_read(codec, 0x18, 0,
15812 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15813 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15814 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15815 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15816 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15817 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15818 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15819 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15820 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15823 /* unsolicited event for HP jack sensing */
15824 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15827 if ((res >> 26) == ALC880_MIC_EVENT)
15828 alc662_eeepc_mic_automute(codec);
15830 alc262_hippo_unsol_event(codec, res);
15833 static void alc662_eeepc_inithook(struct hda_codec *codec)
15835 alc262_hippo1_init_hook(codec);
15836 alc662_eeepc_mic_automute(codec);
15839 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15841 struct alc_spec *spec = codec->spec;
15843 spec->autocfg.hp_pins[0] = 0x14;
15844 spec->autocfg.speaker_pins[0] = 0x1b;
15845 alc262_hippo_master_update(codec);
15848 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15850 unsigned int present;
15851 unsigned char bits;
15853 present = snd_hda_codec_read(codec, 0x21, 0,
15854 AC_VERB_GET_PIN_SENSE, 0)
15855 & AC_PINSENSE_PRESENCE;
15856 bits = present ? HDA_AMP_MUTE : 0;
15857 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15858 AMP_IN_MUTE(0), bits);
15859 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15860 AMP_IN_MUTE(0), bits);
15863 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15865 unsigned int present;
15866 unsigned char bits;
15868 present = snd_hda_codec_read(codec, 0x21, 0,
15869 AC_VERB_GET_PIN_SENSE, 0)
15870 & AC_PINSENSE_PRESENCE;
15871 bits = present ? HDA_AMP_MUTE : 0;
15872 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15873 AMP_IN_MUTE(0), bits);
15874 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15875 AMP_IN_MUTE(0), bits);
15876 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15877 AMP_IN_MUTE(0), bits);
15878 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15879 AMP_IN_MUTE(0), bits);
15882 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15884 unsigned int present;
15885 unsigned char bits;
15887 present = snd_hda_codec_read(codec, 0x15, 0,
15888 AC_VERB_GET_PIN_SENSE, 0)
15889 & AC_PINSENSE_PRESENCE;
15890 bits = present ? HDA_AMP_MUTE : 0;
15891 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15892 AMP_IN_MUTE(0), bits);
15893 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15894 AMP_IN_MUTE(0), bits);
15895 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15896 AMP_IN_MUTE(0), bits);
15897 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15898 AMP_IN_MUTE(0), bits);
15901 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15903 unsigned int present;
15904 unsigned char bits;
15906 present = snd_hda_codec_read(codec, 0x1b, 0,
15907 AC_VERB_GET_PIN_SENSE, 0)
15908 & AC_PINSENSE_PRESENCE;
15909 bits = present ? 0 : PIN_OUT;
15910 snd_hda_codec_write(codec, 0x14, 0,
15911 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15914 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15916 unsigned int present1, present2;
15918 present1 = snd_hda_codec_read(codec, 0x21, 0,
15919 AC_VERB_GET_PIN_SENSE, 0)
15920 & AC_PINSENSE_PRESENCE;
15921 present2 = snd_hda_codec_read(codec, 0x15, 0,
15922 AC_VERB_GET_PIN_SENSE, 0)
15923 & AC_PINSENSE_PRESENCE;
15925 if (present1 || present2) {
15926 snd_hda_codec_write_cache(codec, 0x14, 0,
15927 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15929 snd_hda_codec_write_cache(codec, 0x14, 0,
15930 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15934 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15936 unsigned int present1, present2;
15938 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15939 AC_VERB_GET_PIN_SENSE, 0)
15940 & AC_PINSENSE_PRESENCE;
15941 present2 = snd_hda_codec_read(codec, 0x15, 0,
15942 AC_VERB_GET_PIN_SENSE, 0)
15943 & AC_PINSENSE_PRESENCE;
15945 if (present1 || present2) {
15946 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15947 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15948 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15949 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15951 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15952 AMP_IN_MUTE(0), 0);
15953 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15954 AMP_IN_MUTE(0), 0);
15958 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15960 unsigned int present;
15962 present = snd_hda_codec_read(codec, 0x18, 0,
15963 AC_VERB_GET_PIN_SENSE, 0)
15964 & AC_PINSENSE_PRESENCE;
15965 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15966 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15967 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15968 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15969 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15970 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15971 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15972 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15975 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15978 switch (res >> 26) {
15979 case ALC880_HP_EVENT:
15980 alc663_m51va_speaker_automute(codec);
15982 case ALC880_MIC_EVENT:
15983 alc663_m51va_mic_automute(codec);
15988 static void alc663_m51va_inithook(struct hda_codec *codec)
15990 alc663_m51va_speaker_automute(codec);
15991 alc663_m51va_mic_automute(codec);
15994 /* ***************** Mode1 ******************************/
15995 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15998 switch (res >> 26) {
15999 case ALC880_HP_EVENT:
16000 alc663_m51va_speaker_automute(codec);
16002 case ALC880_MIC_EVENT:
16003 alc662_eeepc_mic_automute(codec);
16008 static void alc663_mode1_inithook(struct hda_codec *codec)
16010 alc663_m51va_speaker_automute(codec);
16011 alc662_eeepc_mic_automute(codec);
16013 /* ***************** Mode2 ******************************/
16014 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16017 switch (res >> 26) {
16018 case ALC880_HP_EVENT:
16019 alc662_f5z_speaker_automute(codec);
16021 case ALC880_MIC_EVENT:
16022 alc662_eeepc_mic_automute(codec);
16027 static void alc662_mode2_inithook(struct hda_codec *codec)
16029 alc662_f5z_speaker_automute(codec);
16030 alc662_eeepc_mic_automute(codec);
16032 /* ***************** Mode3 ******************************/
16033 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16036 switch (res >> 26) {
16037 case ALC880_HP_EVENT:
16038 alc663_two_hp_m1_speaker_automute(codec);
16040 case ALC880_MIC_EVENT:
16041 alc662_eeepc_mic_automute(codec);
16046 static void alc663_mode3_inithook(struct hda_codec *codec)
16048 alc663_two_hp_m1_speaker_automute(codec);
16049 alc662_eeepc_mic_automute(codec);
16051 /* ***************** Mode4 ******************************/
16052 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16055 switch (res >> 26) {
16056 case ALC880_HP_EVENT:
16057 alc663_21jd_two_speaker_automute(codec);
16059 case ALC880_MIC_EVENT:
16060 alc662_eeepc_mic_automute(codec);
16065 static void alc663_mode4_inithook(struct hda_codec *codec)
16067 alc663_21jd_two_speaker_automute(codec);
16068 alc662_eeepc_mic_automute(codec);
16070 /* ***************** Mode5 ******************************/
16071 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16074 switch (res >> 26) {
16075 case ALC880_HP_EVENT:
16076 alc663_15jd_two_speaker_automute(codec);
16078 case ALC880_MIC_EVENT:
16079 alc662_eeepc_mic_automute(codec);
16084 static void alc663_mode5_inithook(struct hda_codec *codec)
16086 alc663_15jd_two_speaker_automute(codec);
16087 alc662_eeepc_mic_automute(codec);
16089 /* ***************** Mode6 ******************************/
16090 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16093 switch (res >> 26) {
16094 case ALC880_HP_EVENT:
16095 alc663_two_hp_m2_speaker_automute(codec);
16097 case ALC880_MIC_EVENT:
16098 alc662_eeepc_mic_automute(codec);
16103 static void alc663_mode6_inithook(struct hda_codec *codec)
16105 alc663_two_hp_m2_speaker_automute(codec);
16106 alc662_eeepc_mic_automute(codec);
16109 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16111 unsigned int present;
16112 unsigned char bits;
16114 present = snd_hda_codec_read(codec, 0x21, 0,
16115 AC_VERB_GET_PIN_SENSE, 0)
16116 & AC_PINSENSE_PRESENCE;
16117 bits = present ? HDA_AMP_MUTE : 0;
16118 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16119 HDA_AMP_MUTE, bits);
16120 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16121 HDA_AMP_MUTE, bits);
16124 static void alc663_g71v_front_automute(struct hda_codec *codec)
16126 unsigned int present;
16127 unsigned char bits;
16129 present = snd_hda_codec_read(codec, 0x15, 0,
16130 AC_VERB_GET_PIN_SENSE, 0)
16131 & AC_PINSENSE_PRESENCE;
16132 bits = present ? HDA_AMP_MUTE : 0;
16133 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16134 HDA_AMP_MUTE, bits);
16137 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16140 switch (res >> 26) {
16141 case ALC880_HP_EVENT:
16142 alc663_g71v_hp_automute(codec);
16144 case ALC880_FRONT_EVENT:
16145 alc663_g71v_front_automute(codec);
16147 case ALC880_MIC_EVENT:
16148 alc662_eeepc_mic_automute(codec);
16153 static void alc663_g71v_inithook(struct hda_codec *codec)
16155 alc663_g71v_front_automute(codec);
16156 alc663_g71v_hp_automute(codec);
16157 alc662_eeepc_mic_automute(codec);
16160 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16163 switch (res >> 26) {
16164 case ALC880_HP_EVENT:
16165 alc663_m51va_speaker_automute(codec);
16167 case ALC880_MIC_EVENT:
16168 alc662_eeepc_mic_automute(codec);
16173 static void alc663_g50v_inithook(struct hda_codec *codec)
16175 alc663_m51va_speaker_automute(codec);
16176 alc662_eeepc_mic_automute(codec);
16179 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16180 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16181 ALC262_HIPPO_MASTER_SWITCH,
16183 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16184 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16185 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16187 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16188 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16189 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16193 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16194 /* Master Playback automatically created from Speaker and Headphone */
16195 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16196 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16197 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16200 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16201 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16202 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16204 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16205 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16206 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16210 #ifdef CONFIG_SND_HDA_POWER_SAVE
16211 #define alc662_loopbacks alc880_loopbacks
16215 /* pcm configuration: identiacal with ALC880 */
16216 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16217 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16218 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16219 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16222 * configuration and preset
16224 static const char *alc662_models[ALC662_MODEL_LAST] = {
16225 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16226 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16227 [ALC662_3ST_6ch] = "3stack-6ch",
16228 [ALC662_5ST_DIG] = "6stack-dig",
16229 [ALC662_LENOVO_101E] = "lenovo-101e",
16230 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16231 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16232 [ALC662_ECS] = "ecs",
16233 [ALC663_ASUS_M51VA] = "m51va",
16234 [ALC663_ASUS_G71V] = "g71v",
16235 [ALC663_ASUS_H13] = "h13",
16236 [ALC663_ASUS_G50V] = "g50v",
16237 [ALC663_ASUS_MODE1] = "asus-mode1",
16238 [ALC662_ASUS_MODE2] = "asus-mode2",
16239 [ALC663_ASUS_MODE3] = "asus-mode3",
16240 [ALC663_ASUS_MODE4] = "asus-mode4",
16241 [ALC663_ASUS_MODE5] = "asus-mode5",
16242 [ALC663_ASUS_MODE6] = "asus-mode6",
16243 [ALC272_DELL] = "dell",
16244 [ALC272_DELL_ZM1] = "dell-zm1",
16245 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16246 [ALC662_AUTO] = "auto",
16249 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16250 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16251 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16252 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16253 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16254 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16255 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16256 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16257 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16258 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16259 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16260 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16261 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16262 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16263 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16264 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16265 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16266 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16267 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16268 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16269 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16270 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16271 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16272 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16273 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16274 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16275 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16276 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16277 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16278 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16279 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16280 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16281 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16282 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16283 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16284 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16285 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16286 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16287 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16288 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16289 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16290 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16291 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16292 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16293 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16294 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16295 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16296 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16297 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16298 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16299 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16300 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16301 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16302 ALC662_3ST_6ch_DIG),
16303 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16304 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16305 ALC662_3ST_6ch_DIG),
16306 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16307 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16308 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16309 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16310 ALC662_3ST_6ch_DIG),
16311 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16316 static struct alc_config_preset alc662_presets[] = {
16317 [ALC662_3ST_2ch_DIG] = {
16318 .mixers = { alc662_3ST_2ch_mixer },
16319 .init_verbs = { alc662_init_verbs },
16320 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16321 .dac_nids = alc662_dac_nids,
16322 .dig_out_nid = ALC662_DIGOUT_NID,
16323 .dig_in_nid = ALC662_DIGIN_NID,
16324 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16325 .channel_mode = alc662_3ST_2ch_modes,
16326 .input_mux = &alc662_capture_source,
16328 [ALC662_3ST_6ch_DIG] = {
16329 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16330 .init_verbs = { alc662_init_verbs },
16331 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16332 .dac_nids = alc662_dac_nids,
16333 .dig_out_nid = ALC662_DIGOUT_NID,
16334 .dig_in_nid = ALC662_DIGIN_NID,
16335 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16336 .channel_mode = alc662_3ST_6ch_modes,
16338 .input_mux = &alc662_capture_source,
16340 [ALC662_3ST_6ch] = {
16341 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16342 .init_verbs = { alc662_init_verbs },
16343 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16344 .dac_nids = alc662_dac_nids,
16345 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16346 .channel_mode = alc662_3ST_6ch_modes,
16348 .input_mux = &alc662_capture_source,
16350 [ALC662_5ST_DIG] = {
16351 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16352 .init_verbs = { alc662_init_verbs },
16353 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16354 .dac_nids = alc662_dac_nids,
16355 .dig_out_nid = ALC662_DIGOUT_NID,
16356 .dig_in_nid = ALC662_DIGIN_NID,
16357 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16358 .channel_mode = alc662_5stack_modes,
16359 .input_mux = &alc662_capture_source,
16361 [ALC662_LENOVO_101E] = {
16362 .mixers = { alc662_lenovo_101e_mixer },
16363 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16364 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16365 .dac_nids = alc662_dac_nids,
16366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16367 .channel_mode = alc662_3ST_2ch_modes,
16368 .input_mux = &alc662_lenovo_101e_capture_source,
16369 .unsol_event = alc662_lenovo_101e_unsol_event,
16370 .init_hook = alc662_lenovo_101e_all_automute,
16372 [ALC662_ASUS_EEEPC_P701] = {
16373 .mixers = { alc662_eeepc_p701_mixer },
16374 .init_verbs = { alc662_init_verbs,
16375 alc662_eeepc_sue_init_verbs },
16376 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16377 .dac_nids = alc662_dac_nids,
16378 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16379 .channel_mode = alc662_3ST_2ch_modes,
16380 .input_mux = &alc662_eeepc_capture_source,
16381 .unsol_event = alc662_eeepc_unsol_event,
16382 .init_hook = alc662_eeepc_inithook,
16384 [ALC662_ASUS_EEEPC_EP20] = {
16385 .mixers = { alc662_eeepc_ep20_mixer,
16386 alc662_chmode_mixer },
16387 .init_verbs = { alc662_init_verbs,
16388 alc662_eeepc_ep20_sue_init_verbs },
16389 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16390 .dac_nids = alc662_dac_nids,
16391 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16392 .channel_mode = alc662_3ST_6ch_modes,
16393 .input_mux = &alc662_lenovo_101e_capture_source,
16394 .unsol_event = alc662_eeepc_unsol_event,
16395 .init_hook = alc662_eeepc_ep20_inithook,
16398 .mixers = { alc662_ecs_mixer },
16399 .init_verbs = { alc662_init_verbs,
16400 alc662_ecs_init_verbs },
16401 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16402 .dac_nids = alc662_dac_nids,
16403 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16404 .channel_mode = alc662_3ST_2ch_modes,
16405 .input_mux = &alc662_eeepc_capture_source,
16406 .unsol_event = alc662_eeepc_unsol_event,
16407 .init_hook = alc662_eeepc_inithook,
16409 [ALC663_ASUS_M51VA] = {
16410 .mixers = { alc663_m51va_mixer },
16411 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16412 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16413 .dac_nids = alc662_dac_nids,
16414 .dig_out_nid = ALC662_DIGOUT_NID,
16415 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16416 .channel_mode = alc662_3ST_2ch_modes,
16417 .input_mux = &alc663_m51va_capture_source,
16418 .unsol_event = alc663_m51va_unsol_event,
16419 .init_hook = alc663_m51va_inithook,
16421 [ALC663_ASUS_G71V] = {
16422 .mixers = { alc663_g71v_mixer },
16423 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16424 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16425 .dac_nids = alc662_dac_nids,
16426 .dig_out_nid = ALC662_DIGOUT_NID,
16427 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16428 .channel_mode = alc662_3ST_2ch_modes,
16429 .input_mux = &alc662_eeepc_capture_source,
16430 .unsol_event = alc663_g71v_unsol_event,
16431 .init_hook = alc663_g71v_inithook,
16433 [ALC663_ASUS_H13] = {
16434 .mixers = { alc663_m51va_mixer },
16435 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16436 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16437 .dac_nids = alc662_dac_nids,
16438 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16439 .channel_mode = alc662_3ST_2ch_modes,
16440 .input_mux = &alc663_m51va_capture_source,
16441 .unsol_event = alc663_m51va_unsol_event,
16442 .init_hook = alc663_m51va_inithook,
16444 [ALC663_ASUS_G50V] = {
16445 .mixers = { alc663_g50v_mixer },
16446 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16447 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16448 .dac_nids = alc662_dac_nids,
16449 .dig_out_nid = ALC662_DIGOUT_NID,
16450 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16451 .channel_mode = alc662_3ST_6ch_modes,
16452 .input_mux = &alc663_capture_source,
16453 .unsol_event = alc663_g50v_unsol_event,
16454 .init_hook = alc663_g50v_inithook,
16456 [ALC663_ASUS_MODE1] = {
16457 .mixers = { alc663_m51va_mixer },
16458 .cap_mixer = alc662_auto_capture_mixer,
16459 .init_verbs = { alc662_init_verbs,
16460 alc663_21jd_amic_init_verbs },
16461 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16463 .dac_nids = alc662_dac_nids,
16464 .dig_out_nid = ALC662_DIGOUT_NID,
16465 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16466 .channel_mode = alc662_3ST_2ch_modes,
16467 .input_mux = &alc662_eeepc_capture_source,
16468 .unsol_event = alc663_mode1_unsol_event,
16469 .init_hook = alc663_mode1_inithook,
16471 [ALC662_ASUS_MODE2] = {
16472 .mixers = { alc662_1bjd_mixer },
16473 .cap_mixer = alc662_auto_capture_mixer,
16474 .init_verbs = { alc662_init_verbs,
16475 alc662_1bjd_amic_init_verbs },
16476 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16477 .dac_nids = alc662_dac_nids,
16478 .dig_out_nid = ALC662_DIGOUT_NID,
16479 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16480 .channel_mode = alc662_3ST_2ch_modes,
16481 .input_mux = &alc662_eeepc_capture_source,
16482 .unsol_event = alc662_mode2_unsol_event,
16483 .init_hook = alc662_mode2_inithook,
16485 [ALC663_ASUS_MODE3] = {
16486 .mixers = { alc663_two_hp_m1_mixer },
16487 .cap_mixer = alc662_auto_capture_mixer,
16488 .init_verbs = { alc662_init_verbs,
16489 alc663_two_hp_amic_m1_init_verbs },
16490 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16492 .dac_nids = alc662_dac_nids,
16493 .dig_out_nid = ALC662_DIGOUT_NID,
16494 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16495 .channel_mode = alc662_3ST_2ch_modes,
16496 .input_mux = &alc662_eeepc_capture_source,
16497 .unsol_event = alc663_mode3_unsol_event,
16498 .init_hook = alc663_mode3_inithook,
16500 [ALC663_ASUS_MODE4] = {
16501 .mixers = { alc663_asus_21jd_clfe_mixer },
16502 .cap_mixer = alc662_auto_capture_mixer,
16503 .init_verbs = { alc662_init_verbs,
16504 alc663_21jd_amic_init_verbs},
16505 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16507 .dac_nids = alc662_dac_nids,
16508 .dig_out_nid = ALC662_DIGOUT_NID,
16509 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16510 .channel_mode = alc662_3ST_2ch_modes,
16511 .input_mux = &alc662_eeepc_capture_source,
16512 .unsol_event = alc663_mode4_unsol_event,
16513 .init_hook = alc663_mode4_inithook,
16515 [ALC663_ASUS_MODE5] = {
16516 .mixers = { alc663_asus_15jd_clfe_mixer },
16517 .cap_mixer = alc662_auto_capture_mixer,
16518 .init_verbs = { alc662_init_verbs,
16519 alc663_15jd_amic_init_verbs },
16520 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16522 .dac_nids = alc662_dac_nids,
16523 .dig_out_nid = ALC662_DIGOUT_NID,
16524 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16525 .channel_mode = alc662_3ST_2ch_modes,
16526 .input_mux = &alc662_eeepc_capture_source,
16527 .unsol_event = alc663_mode5_unsol_event,
16528 .init_hook = alc663_mode5_inithook,
16530 [ALC663_ASUS_MODE6] = {
16531 .mixers = { alc663_two_hp_m2_mixer },
16532 .cap_mixer = alc662_auto_capture_mixer,
16533 .init_verbs = { alc662_init_verbs,
16534 alc663_two_hp_amic_m2_init_verbs },
16535 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16537 .dac_nids = alc662_dac_nids,
16538 .dig_out_nid = ALC662_DIGOUT_NID,
16539 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16540 .channel_mode = alc662_3ST_2ch_modes,
16541 .input_mux = &alc662_eeepc_capture_source,
16542 .unsol_event = alc663_mode6_unsol_event,
16543 .init_hook = alc663_mode6_inithook,
16546 .mixers = { alc663_m51va_mixer },
16547 .cap_mixer = alc272_auto_capture_mixer,
16548 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16549 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16550 .dac_nids = alc662_dac_nids,
16551 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16552 .adc_nids = alc272_adc_nids,
16553 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16554 .capsrc_nids = alc272_capsrc_nids,
16555 .channel_mode = alc662_3ST_2ch_modes,
16556 .input_mux = &alc663_m51va_capture_source,
16557 .unsol_event = alc663_m51va_unsol_event,
16558 .init_hook = alc663_m51va_inithook,
16560 [ALC272_DELL_ZM1] = {
16561 .mixers = { alc663_m51va_mixer },
16562 .cap_mixer = alc662_auto_capture_mixer,
16563 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16564 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16565 .dac_nids = alc662_dac_nids,
16566 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16567 .adc_nids = alc662_adc_nids,
16568 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16569 .capsrc_nids = alc662_capsrc_nids,
16570 .channel_mode = alc662_3ST_2ch_modes,
16571 .input_mux = &alc663_m51va_capture_source,
16572 .unsol_event = alc663_m51va_unsol_event,
16573 .init_hook = alc663_m51va_inithook,
16575 [ALC272_SAMSUNG_NC10] = {
16576 .mixers = { alc272_nc10_mixer },
16577 .init_verbs = { alc662_init_verbs,
16578 alc663_21jd_amic_init_verbs },
16579 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16580 .dac_nids = alc272_dac_nids,
16581 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16582 .channel_mode = alc662_3ST_2ch_modes,
16583 .input_mux = &alc272_nc10_capture_source,
16584 .unsol_event = alc663_mode4_unsol_event,
16585 .init_hook = alc663_mode4_inithook,
16591 * BIOS auto configuration
16594 /* add playback controls from the parsed DAC table */
16595 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16596 const struct auto_pin_cfg *cfg)
16599 static const char *chname[4] = {
16600 "Front", "Surround", NULL /*CLFE*/, "Side"
16605 for (i = 0; i < cfg->line_outs; i++) {
16606 if (!spec->multiout.dac_nids[i])
16608 nid = alc880_idx_to_dac(i);
16611 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16612 "Center Playback Volume",
16613 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16617 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16618 "LFE Playback Volume",
16619 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16623 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16624 "Center Playback Switch",
16625 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16629 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16630 "LFE Playback Switch",
16631 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16636 sprintf(name, "%s Playback Volume", chname[i]);
16637 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16638 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16642 sprintf(name, "%s Playback Switch", chname[i]);
16643 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16644 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16653 /* add playback controls for speaker and HP outputs */
16654 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16665 /* ALC663 has a mono output pin on 0x17 */
16666 sprintf(name, "%s Playback Switch", pfx);
16667 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16668 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16672 if (alc880_is_fixed_pin(pin)) {
16673 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16674 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16675 /* specify the DAC as the extra output */
16676 if (!spec->multiout.hp_nid)
16677 spec->multiout.hp_nid = nid;
16679 spec->multiout.extra_out_nid[0] = nid;
16680 /* control HP volume/switch on the output mixer amp */
16681 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16682 sprintf(name, "%s Playback Volume", pfx);
16683 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16684 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16687 sprintf(name, "%s Playback Switch", pfx);
16688 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16689 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16692 } else if (alc880_is_multi_pin(pin)) {
16693 /* set manual connection */
16694 /* we have only a switch on HP-out PIN */
16695 sprintf(name, "%s Playback Switch", pfx);
16696 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16697 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16704 /* return the index of the src widget from the connection list of the nid.
16705 * return -1 if not found
16707 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16710 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16713 conns = snd_hda_get_connections(codec, nid, conn_list,
16714 ARRAY_SIZE(conn_list));
16717 for (i = 0; i < conns; i++)
16718 if (conn_list[i] == src)
16723 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16725 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16726 return (pincap & AC_PINCAP_IN) != 0;
16729 /* create playback/capture controls for input pins */
16730 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16731 const struct auto_pin_cfg *cfg)
16733 struct alc_spec *spec = codec->spec;
16734 struct hda_input_mux *imux = &spec->private_imux[0];
16737 for (i = 0; i < AUTO_PIN_LAST; i++) {
16738 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16739 idx = alc662_input_pin_idx(codec, 0x0b,
16740 cfg->input_pins[i]);
16742 err = new_analog_input(spec, cfg->input_pins[i],
16743 auto_pin_cfg_labels[i],
16748 idx = alc662_input_pin_idx(codec, 0x22,
16749 cfg->input_pins[i]);
16751 imux->items[imux->num_items].label =
16752 auto_pin_cfg_labels[i];
16753 imux->items[imux->num_items].index = idx;
16761 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16762 hda_nid_t nid, int pin_type,
16765 alc_set_pin_output(codec, nid, pin_type);
16766 /* need the manual connection? */
16767 if (alc880_is_multi_pin(nid)) {
16768 struct alc_spec *spec = codec->spec;
16769 int idx = alc880_multi_pin_idx(nid);
16770 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16771 AC_VERB_SET_CONNECT_SEL,
16772 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16776 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16778 struct alc_spec *spec = codec->spec;
16781 for (i = 0; i <= HDA_SIDE; i++) {
16782 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16783 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16785 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16790 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16792 struct alc_spec *spec = codec->spec;
16795 pin = spec->autocfg.hp_pins[0];
16796 if (pin) /* connect to front */
16798 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16799 pin = spec->autocfg.speaker_pins[0];
16801 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16804 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16806 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16808 struct alc_spec *spec = codec->spec;
16811 for (i = 0; i < AUTO_PIN_LAST; i++) {
16812 hda_nid_t nid = spec->autocfg.input_pins[i];
16813 if (alc662_is_input_pin(codec, nid)) {
16814 alc_set_input_pin(codec, nid, i);
16815 if (nid != ALC662_PIN_CD_NID &&
16816 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16817 snd_hda_codec_write(codec, nid, 0,
16818 AC_VERB_SET_AMP_GAIN_MUTE,
16824 #define alc662_auto_init_input_src alc882_auto_init_input_src
16826 static int alc662_parse_auto_config(struct hda_codec *codec)
16828 struct alc_spec *spec = codec->spec;
16830 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16832 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16836 if (!spec->autocfg.line_outs)
16837 return 0; /* can't find valid BIOS pin config */
16839 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16842 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16845 err = alc662_auto_create_extra_out(spec,
16846 spec->autocfg.speaker_pins[0],
16850 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16854 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
16858 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16860 if (spec->autocfg.dig_outs)
16861 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16863 if (spec->kctls.list)
16864 add_mixer(spec, spec->kctls.list);
16866 spec->num_mux_defs = 1;
16867 spec->input_mux = &spec->private_imux[0];
16869 add_verb(spec, alc662_auto_init_verbs);
16870 if (codec->vendor_id == 0x10ec0663)
16871 add_verb(spec, alc663_auto_init_verbs);
16873 err = alc_auto_add_mic_boost(codec);
16877 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16882 /* additional initialization for auto-configuration model */
16883 static void alc662_auto_init(struct hda_codec *codec)
16885 struct alc_spec *spec = codec->spec;
16886 alc662_auto_init_multi_out(codec);
16887 alc662_auto_init_hp_out(codec);
16888 alc662_auto_init_analog_input(codec);
16889 alc662_auto_init_input_src(codec);
16890 if (spec->unsol_event)
16891 alc_inithook(codec);
16894 static int patch_alc662(struct hda_codec *codec)
16896 struct alc_spec *spec;
16897 int err, board_config;
16899 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16903 codec->spec = spec;
16905 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16907 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16910 if (board_config < 0) {
16911 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16912 "trying auto-probe from BIOS...\n");
16913 board_config = ALC662_AUTO;
16916 if (board_config == ALC662_AUTO) {
16917 /* automatic parse from the BIOS config */
16918 err = alc662_parse_auto_config(codec);
16924 "hda_codec: Cannot set up configuration "
16925 "from BIOS. Using base mode...\n");
16926 board_config = ALC662_3ST_2ch_DIG;
16930 err = snd_hda_attach_beep_device(codec, 0x1);
16936 if (board_config != ALC662_AUTO)
16937 setup_preset(spec, &alc662_presets[board_config]);
16939 if (codec->vendor_id == 0x10ec0663) {
16940 spec->stream_name_analog = "ALC663 Analog";
16941 spec->stream_name_digital = "ALC663 Digital";
16942 } else if (codec->vendor_id == 0x10ec0272) {
16943 spec->stream_name_analog = "ALC272 Analog";
16944 spec->stream_name_digital = "ALC272 Digital";
16946 spec->stream_name_analog = "ALC662 Analog";
16947 spec->stream_name_digital = "ALC662 Digital";
16950 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16951 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16953 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16954 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16956 spec->adc_nids = alc662_adc_nids;
16957 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16958 spec->capsrc_nids = alc662_capsrc_nids;
16959 spec->capture_style = CAPT_MIX;
16961 if (!spec->cap_mixer)
16962 set_capture_mixer(spec);
16963 if (codec->vendor_id == 0x10ec0662)
16964 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16966 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
16968 spec->vmaster_nid = 0x02;
16970 codec->patch_ops = alc_patch_ops;
16971 if (board_config == ALC662_AUTO)
16972 spec->init_hook = alc662_auto_init;
16973 #ifdef CONFIG_SND_HDA_POWER_SAVE
16974 if (!spec->loopback.amplist)
16975 spec->loopback.amplist = alc662_loopbacks;
16977 codec->proc_widget_hook = print_realtek_coef;
16985 static struct hda_codec_preset snd_hda_preset_realtek[] = {
16986 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16987 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16988 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16989 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16990 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16991 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16992 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16993 .patch = patch_alc861 },
16994 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16995 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16996 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16997 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16998 .patch = patch_alc883 },
16999 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17000 .patch = patch_alc662 },
17001 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17002 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17003 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17004 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17005 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17006 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17007 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17008 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17009 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17010 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17011 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17012 .patch = patch_alc883 },
17013 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17014 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17015 {} /* terminator */
17018 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17020 MODULE_LICENSE("GPL");
17021 MODULE_DESCRIPTION("Realtek HD-audio codec");
17023 static struct hda_codec_preset_list realtek_list = {
17024 .preset = snd_hda_preset_realtek,
17025 .owner = THIS_MODULE,
17028 static int __init patch_realtek_init(void)
17030 return snd_hda_add_codec_preset(&realtek_list);
17033 static void __exit patch_realtek_exit(void)
17035 snd_hda_delete_codec_preset(&realtek_list);
17038 module_init(patch_realtek_init)
17039 module_exit(patch_realtek_exit)