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 */
81 #ifdef CONFIG_SND_DEBUG
85 ALC260_MODEL_LAST /* last tag */
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
109 ALC262_MODEL_LAST /* last tag */
119 ALC268_ACER_ASPIRE_ONE,
122 #ifdef CONFIG_SND_DEBUG
126 ALC268_MODEL_LAST /* last tag */
133 ALC269_ASUS_EEEPC_P703,
134 ALC269_ASUS_EEEPC_P901,
138 ALC269_MODEL_LAST /* last tag */
155 /* ALC861-VD models */
177 ALC662_ASUS_EEEPC_P701,
178 ALC662_ASUS_EEEPC_EP20,
217 ALC883_TARGA_2ch_DIG,
220 ALC888_ACER_ASPIRE_4930G,
224 ALC883_LENOVO_101E_2ch,
225 ALC883_LENOVO_NB0763,
226 ALC888_LENOVO_MS7195_DIG,
233 ALC883_FUJITSU_PI2515,
234 ALC888_FUJITSU_XA3530,
235 ALC883_3ST_6ch_INTEL,
243 /* styles of capture selection */
245 CAPT_MUX = 0, /* only mux based */
246 CAPT_MIX, /* only mixer based */
247 CAPT_1MUX_MIX, /* first mux and other mixers */
251 #define GPIO_MASK 0x03
254 /* codec parameterization */
255 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
256 unsigned int num_mixers;
257 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
259 const struct hda_verb *init_verbs[5]; /* initialization verbs
263 unsigned int num_init_verbs;
265 char *stream_name_analog; /* analog PCM stream */
266 struct hda_pcm_stream *stream_analog_playback;
267 struct hda_pcm_stream *stream_analog_capture;
268 struct hda_pcm_stream *stream_analog_alt_playback;
269 struct hda_pcm_stream *stream_analog_alt_capture;
271 char *stream_name_digital; /* digital PCM stream */
272 struct hda_pcm_stream *stream_digital_playback;
273 struct hda_pcm_stream *stream_digital_capture;
276 struct hda_multi_out multiout; /* playback set-up
277 * max_channels, dacs must be set
278 * dig_out_nid and hp_nid are optional
280 hda_nid_t alt_dac_nid;
284 unsigned int num_adc_nids;
286 hda_nid_t *capsrc_nids;
287 hda_nid_t dig_in_nid; /* digital-in NID; optional */
288 int capture_style; /* capture style (CAPT_*) */
291 unsigned int num_mux_defs;
292 const struct hda_input_mux *input_mux;
293 unsigned int cur_mux[3];
296 const struct hda_channel_mode *channel_mode;
297 int num_channel_mode;
300 /* PCM information */
301 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
303 /* dynamic controls, init_verbs and input_mux */
304 struct auto_pin_cfg autocfg;
305 struct snd_array kctls;
306 struct hda_input_mux private_imux[3];
307 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
310 void (*init_hook)(struct hda_codec *codec);
311 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
313 /* for pin sensing */
314 unsigned int sense_updated: 1;
315 unsigned int jack_present: 1;
316 unsigned int master_sw: 1;
319 unsigned int no_analog :1; /* digital I/O only */
321 /* for virtual master */
322 hda_nid_t vmaster_nid;
323 #ifdef CONFIG_SND_HDA_POWER_SAVE
324 struct hda_loopback_check loopback;
329 unsigned int pll_coef_idx, pll_coef_bit;
331 #ifdef SND_HDA_NEEDS_RESUME
332 #define ALC_MAX_PINS 16
333 unsigned int num_pins;
334 hda_nid_t pin_nids[ALC_MAX_PINS];
335 unsigned int pin_cfgs[ALC_MAX_PINS];
340 * configuration template - to be copied to the spec instance
342 struct alc_config_preset {
343 struct snd_kcontrol_new *mixers[5]; /* should be identical size
346 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
347 const struct hda_verb *init_verbs[5];
348 unsigned int num_dacs;
350 hda_nid_t dig_out_nid; /* optional */
351 hda_nid_t hp_nid; /* optional */
352 hda_nid_t *slave_dig_outs;
353 unsigned int num_adc_nids;
355 hda_nid_t *capsrc_nids;
356 hda_nid_t dig_in_nid;
357 unsigned int num_channel_mode;
358 const struct hda_channel_mode *channel_mode;
360 unsigned int num_mux_defs;
361 const struct hda_input_mux *input_mux;
362 void (*unsol_event)(struct hda_codec *, unsigned int);
363 void (*init_hook)(struct hda_codec *);
364 #ifdef CONFIG_SND_HDA_POWER_SAVE
365 struct hda_amp_list *loopbacks;
373 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
374 struct snd_ctl_elem_info *uinfo)
376 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
377 struct alc_spec *spec = codec->spec;
378 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
379 if (mux_idx >= spec->num_mux_defs)
381 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
384 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
385 struct snd_ctl_elem_value *ucontrol)
387 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
388 struct alc_spec *spec = codec->spec;
389 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
391 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
395 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol)
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct alc_spec *spec = codec->spec;
400 const struct hda_input_mux *imux;
401 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
402 unsigned int mux_idx;
403 hda_nid_t nid = spec->capsrc_nids ?
404 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
406 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
407 imux = &spec->input_mux[mux_idx];
409 if (spec->capture_style &&
410 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
411 /* Matrix-mixer style (e.g. ALC882) */
412 unsigned int *cur_val = &spec->cur_mux[adc_idx];
415 idx = ucontrol->value.enumerated.item[0];
416 if (idx >= imux->num_items)
417 idx = imux->num_items - 1;
420 for (i = 0; i < imux->num_items; i++) {
421 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
422 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
423 imux->items[i].index,
429 /* MUX style (e.g. ALC880) */
430 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
431 &spec->cur_mux[adc_idx]);
436 * channel mode setting
438 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
439 struct snd_ctl_elem_info *uinfo)
441 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
442 struct alc_spec *spec = codec->spec;
443 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
444 spec->num_channel_mode);
447 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
453 spec->num_channel_mode,
454 spec->multiout.max_channels);
457 static int alc_ch_mode_put(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 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
463 spec->num_channel_mode,
464 &spec->multiout.max_channels);
465 if (err >= 0 && spec->need_dac_fix)
466 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
471 * Control the mode of pin widget settings via the mixer. "pc" is used
472 * instead of "%" to avoid consequences of accidently treating the % as
473 * being part of a format specifier. Maximum allowed length of a value is
474 * 63 characters plus NULL terminator.
476 * Note: some retasking pin complexes seem to ignore requests for input
477 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
478 * are requested. Therefore order this list so that this behaviour will not
479 * cause problems when mixer clients move through the enum sequentially.
480 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
483 static char *alc_pin_mode_names[] = {
484 "Mic 50pc bias", "Mic 80pc bias",
485 "Line in", "Line out", "Headphone out",
487 static unsigned char alc_pin_mode_values[] = {
488 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
490 /* The control can present all 5 options, or it can limit the options based
491 * in the pin being assumed to be exclusively an input or an output pin. In
492 * addition, "input" pins may or may not process the mic bias option
493 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
494 * accept requests for bias as of chip versions up to March 2006) and/or
495 * wiring in the computer.
497 #define ALC_PIN_DIR_IN 0x00
498 #define ALC_PIN_DIR_OUT 0x01
499 #define ALC_PIN_DIR_INOUT 0x02
500 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
501 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
503 /* Info about the pin modes supported by the different pin direction modes.
504 * For each direction the minimum and maximum values are given.
506 static signed char alc_pin_mode_dir_info[5][2] = {
507 { 0, 2 }, /* ALC_PIN_DIR_IN */
508 { 3, 4 }, /* ALC_PIN_DIR_OUT */
509 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
510 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
511 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
513 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
514 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
515 #define alc_pin_mode_n_items(_dir) \
516 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
518 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
519 struct snd_ctl_elem_info *uinfo)
521 unsigned int item_num = uinfo->value.enumerated.item;
522 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
524 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
526 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
528 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
529 item_num = alc_pin_mode_min(dir);
530 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
534 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
535 struct snd_ctl_elem_value *ucontrol)
538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
539 hda_nid_t nid = kcontrol->private_value & 0xffff;
540 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
541 long *valp = ucontrol->value.integer.value;
542 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
543 AC_VERB_GET_PIN_WIDGET_CONTROL,
546 /* Find enumerated value for current pinctl setting */
547 i = alc_pin_mode_min(dir);
548 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
550 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
554 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
555 struct snd_ctl_elem_value *ucontrol)
558 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
559 hda_nid_t nid = kcontrol->private_value & 0xffff;
560 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
561 long val = *ucontrol->value.integer.value;
562 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
563 AC_VERB_GET_PIN_WIDGET_CONTROL,
566 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
567 val = alc_pin_mode_min(dir);
569 change = pinctl != alc_pin_mode_values[val];
571 /* Set pin mode to that requested */
572 snd_hda_codec_write_cache(codec, nid, 0,
573 AC_VERB_SET_PIN_WIDGET_CONTROL,
574 alc_pin_mode_values[val]);
576 /* Also enable the retasking pin's input/output as required
577 * for the requested pin mode. Enum values of 2 or less are
580 * Dynamically switching the input/output buffers probably
581 * reduces noise slightly (particularly on input) so we'll
582 * do it. However, having both input and output buffers
583 * enabled simultaneously doesn't seem to be problematic if
584 * this turns out to be necessary in the future.
587 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
588 HDA_AMP_MUTE, HDA_AMP_MUTE);
589 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
592 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
593 HDA_AMP_MUTE, HDA_AMP_MUTE);
594 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
601 #define ALC_PIN_MODE(xname, nid, dir) \
602 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
603 .info = alc_pin_mode_info, \
604 .get = alc_pin_mode_get, \
605 .put = alc_pin_mode_put, \
606 .private_value = nid | (dir<<16) }
608 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
609 * together using a mask with more than one bit set. This control is
610 * currently used only by the ALC260 test model. At this stage they are not
611 * needed for any "production" models.
613 #ifdef CONFIG_SND_DEBUG
614 #define alc_gpio_data_info snd_ctl_boolean_mono_info
616 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
617 struct snd_ctl_elem_value *ucontrol)
619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
620 hda_nid_t nid = kcontrol->private_value & 0xffff;
621 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
622 long *valp = ucontrol->value.integer.value;
623 unsigned int val = snd_hda_codec_read(codec, nid, 0,
624 AC_VERB_GET_GPIO_DATA, 0x00);
626 *valp = (val & mask) != 0;
629 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
630 struct snd_ctl_elem_value *ucontrol)
633 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
634 hda_nid_t nid = kcontrol->private_value & 0xffff;
635 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
636 long val = *ucontrol->value.integer.value;
637 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
638 AC_VERB_GET_GPIO_DATA,
641 /* Set/unset the masked GPIO bit(s) as needed */
642 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
647 snd_hda_codec_write_cache(codec, nid, 0,
648 AC_VERB_SET_GPIO_DATA, gpio_data);
652 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
653 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
654 .info = alc_gpio_data_info, \
655 .get = alc_gpio_data_get, \
656 .put = alc_gpio_data_put, \
657 .private_value = nid | (mask<<16) }
658 #endif /* CONFIG_SND_DEBUG */
660 /* A switch control to allow the enabling of the digital IO pins on the
661 * ALC260. This is incredibly simplistic; the intention of this control is
662 * to provide something in the test model allowing digital outputs to be
663 * identified if present. If models are found which can utilise these
664 * outputs a more complete mixer control can be devised for those models if
667 #ifdef CONFIG_SND_DEBUG
668 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
670 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
671 struct snd_ctl_elem_value *ucontrol)
673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
674 hda_nid_t nid = kcontrol->private_value & 0xffff;
675 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
676 long *valp = ucontrol->value.integer.value;
677 unsigned int val = snd_hda_codec_read(codec, nid, 0,
678 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
680 *valp = (val & mask) != 0;
683 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
684 struct snd_ctl_elem_value *ucontrol)
687 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
688 hda_nid_t nid = kcontrol->private_value & 0xffff;
689 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
690 long val = *ucontrol->value.integer.value;
691 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
692 AC_VERB_GET_DIGI_CONVERT_1,
695 /* Set/unset the masked control bit(s) as needed */
696 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
701 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
706 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
707 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
708 .info = alc_spdif_ctrl_info, \
709 .get = alc_spdif_ctrl_get, \
710 .put = alc_spdif_ctrl_put, \
711 .private_value = nid | (mask<<16) }
712 #endif /* CONFIG_SND_DEBUG */
714 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
715 * Again, this is only used in the ALC26x test models to help identify when
716 * the EAPD line must be asserted for features to work.
718 #ifdef CONFIG_SND_DEBUG
719 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
721 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
725 hda_nid_t nid = kcontrol->private_value & 0xffff;
726 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
727 long *valp = ucontrol->value.integer.value;
728 unsigned int val = snd_hda_codec_read(codec, nid, 0,
729 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
731 *valp = (val & mask) != 0;
735 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
736 struct snd_ctl_elem_value *ucontrol)
739 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
740 hda_nid_t nid = kcontrol->private_value & 0xffff;
741 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
742 long val = *ucontrol->value.integer.value;
743 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
744 AC_VERB_GET_EAPD_BTLENABLE,
747 /* Set/unset the masked control bit(s) as needed */
748 change = (!val ? 0 : mask) != (ctrl_data & mask);
753 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
759 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
760 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
761 .info = alc_eapd_ctrl_info, \
762 .get = alc_eapd_ctrl_get, \
763 .put = alc_eapd_ctrl_put, \
764 .private_value = nid | (mask<<16) }
765 #endif /* CONFIG_SND_DEBUG */
769 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
771 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
773 spec->mixers[spec->num_mixers++] = mix;
776 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
778 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
780 spec->init_verbs[spec->num_init_verbs++] = verb;
783 #ifdef CONFIG_PROC_FS
787 static void print_realtek_coef(struct snd_info_buffer *buffer,
788 struct hda_codec *codec, hda_nid_t nid)
794 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
795 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
796 coeff = snd_hda_codec_read(codec, nid, 0,
797 AC_VERB_GET_COEF_INDEX, 0);
798 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
801 #define print_realtek_coef NULL
805 * set up from the preset table
807 static void setup_preset(struct alc_spec *spec,
808 const struct alc_config_preset *preset)
812 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
813 add_mixer(spec, preset->mixers[i]);
814 spec->cap_mixer = preset->cap_mixer;
815 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
817 add_verb(spec, preset->init_verbs[i]);
819 spec->channel_mode = preset->channel_mode;
820 spec->num_channel_mode = preset->num_channel_mode;
821 spec->need_dac_fix = preset->need_dac_fix;
823 spec->multiout.max_channels = spec->channel_mode[0].channels;
825 spec->multiout.num_dacs = preset->num_dacs;
826 spec->multiout.dac_nids = preset->dac_nids;
827 spec->multiout.dig_out_nid = preset->dig_out_nid;
828 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
829 spec->multiout.hp_nid = preset->hp_nid;
831 spec->num_mux_defs = preset->num_mux_defs;
832 if (!spec->num_mux_defs)
833 spec->num_mux_defs = 1;
834 spec->input_mux = preset->input_mux;
836 spec->num_adc_nids = preset->num_adc_nids;
837 spec->adc_nids = preset->adc_nids;
838 spec->capsrc_nids = preset->capsrc_nids;
839 spec->dig_in_nid = preset->dig_in_nid;
841 spec->unsol_event = preset->unsol_event;
842 spec->init_hook = preset->init_hook;
843 #ifdef CONFIG_SND_HDA_POWER_SAVE
844 spec->loopback.amplist = preset->loopbacks;
848 /* Enable GPIO mask and set output */
849 static struct hda_verb alc_gpio1_init_verbs[] = {
850 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
851 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
852 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
856 static struct hda_verb alc_gpio2_init_verbs[] = {
857 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
858 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
859 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
863 static struct hda_verb alc_gpio3_init_verbs[] = {
864 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
865 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
866 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
871 * Fix hardware PLL issue
872 * On some codecs, the analog PLL gating control must be off while
873 * the default value is 1.
875 static void alc_fix_pll(struct hda_codec *codec)
877 struct alc_spec *spec = codec->spec;
882 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
884 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
885 AC_VERB_GET_PROC_COEF, 0);
886 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
888 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
889 val & ~(1 << spec->pll_coef_bit));
892 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
893 unsigned int coef_idx, unsigned int coef_bit)
895 struct alc_spec *spec = codec->spec;
897 spec->pll_coef_idx = coef_idx;
898 spec->pll_coef_bit = coef_bit;
902 static void alc_sku_automute(struct hda_codec *codec)
904 struct alc_spec *spec = codec->spec;
905 unsigned int present;
906 unsigned int hp_nid = spec->autocfg.hp_pins[0];
907 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
909 /* need to execute and sync at first */
910 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
911 present = snd_hda_codec_read(codec, hp_nid, 0,
912 AC_VERB_GET_PIN_SENSE, 0);
913 spec->jack_present = (present & 0x80000000) != 0;
914 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
915 spec->jack_present ? 0 : PIN_OUT);
918 #if 0 /* it's broken in some acses -- temporarily disabled */
919 static void alc_mic_automute(struct hda_codec *codec)
921 struct alc_spec *spec = codec->spec;
922 unsigned int present;
923 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
924 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
925 unsigned int mix_nid = spec->capsrc_nids[0];
926 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
928 capsrc_idx_mic = mic_nid - 0x18;
929 capsrc_idx_fmic = fmic_nid - 0x18;
930 present = snd_hda_codec_read(codec, mic_nid, 0,
931 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
932 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
933 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
934 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
935 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
936 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
937 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
940 #define alc_mic_automute(codec) /* NOP */
941 #endif /* disabled */
943 /* unsolicited event for HP jack sensing */
944 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
946 if (codec->vendor_id == 0x10ec0880)
950 if (res == ALC880_HP_EVENT)
951 alc_sku_automute(codec);
953 if (res == ALC880_MIC_EVENT)
954 alc_mic_automute(codec);
957 static void alc_inithook(struct hda_codec *codec)
959 alc_sku_automute(codec);
960 alc_mic_automute(codec);
963 /* additional initialization for ALC888 variants */
964 static void alc888_coef_init(struct hda_codec *codec)
968 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
969 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
970 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
971 if ((tmp & 0xf0) == 2)
973 snd_hda_codec_read(codec, 0x20, 0,
974 AC_VERB_SET_PROC_COEF, 0x830);
977 snd_hda_codec_read(codec, 0x20, 0,
978 AC_VERB_SET_PROC_COEF, 0x3030);
981 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
982 * 31 ~ 16 : Manufacture ID
984 * 7 ~ 0 : Assembly ID
985 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
987 static void alc_subsystem_id(struct hda_codec *codec,
988 unsigned int porta, unsigned int porte,
991 unsigned int ass, tmp, i;
993 struct alc_spec *spec = codec->spec;
995 ass = codec->subsystem_id & 0xffff;
996 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1000 * 31~30 : port conetcivity
1003 * 19~16 : Check sum (15:1)
1008 if (codec->vendor_id == 0x10ec0260)
1010 ass = snd_hda_codec_read(codec, nid, 0,
1011 AC_VERB_GET_CONFIG_DEFAULT, 0);
1012 if (!(ass & 1) && !(ass & 0x100000))
1014 if ((ass >> 30) != 1) /* no physical connection */
1019 for (i = 1; i < 16; i++) {
1023 if (((ass >> 16) & 0xf) != tmp)
1029 * 2 : 0 --> Desktop, 1 --> Laptop
1030 * 3~5 : External Amplifier control
1033 tmp = (ass & 0x38) >> 3; /* external Amp control */
1036 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1039 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1042 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1044 case 5: /* set EAPD output high */
1045 switch (codec->vendor_id) {
1047 snd_hda_codec_write(codec, 0x0f, 0,
1048 AC_VERB_SET_EAPD_BTLENABLE, 2);
1049 snd_hda_codec_write(codec, 0x10, 0,
1050 AC_VERB_SET_EAPD_BTLENABLE, 2);
1061 snd_hda_codec_write(codec, 0x14, 0,
1062 AC_VERB_SET_EAPD_BTLENABLE, 2);
1063 snd_hda_codec_write(codec, 0x15, 0,
1064 AC_VERB_SET_EAPD_BTLENABLE, 2);
1067 switch (codec->vendor_id) {
1069 snd_hda_codec_write(codec, 0x1a, 0,
1070 AC_VERB_SET_COEF_INDEX, 7);
1071 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1072 AC_VERB_GET_PROC_COEF, 0);
1073 snd_hda_codec_write(codec, 0x1a, 0,
1074 AC_VERB_SET_COEF_INDEX, 7);
1075 snd_hda_codec_write(codec, 0x1a, 0,
1076 AC_VERB_SET_PROC_COEF,
1085 snd_hda_codec_write(codec, 0x20, 0,
1086 AC_VERB_SET_COEF_INDEX, 7);
1087 tmp = snd_hda_codec_read(codec, 0x20, 0,
1088 AC_VERB_GET_PROC_COEF, 0);
1089 snd_hda_codec_write(codec, 0x20, 0,
1090 AC_VERB_SET_COEF_INDEX, 7);
1091 snd_hda_codec_write(codec, 0x20, 0,
1092 AC_VERB_SET_PROC_COEF,
1096 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1100 snd_hda_codec_write(codec, 0x20, 0,
1101 AC_VERB_SET_COEF_INDEX, 7);
1102 tmp = snd_hda_codec_read(codec, 0x20, 0,
1103 AC_VERB_GET_PROC_COEF, 0);
1104 snd_hda_codec_write(codec, 0x20, 0,
1105 AC_VERB_SET_COEF_INDEX, 7);
1106 snd_hda_codec_write(codec, 0x20, 0,
1107 AC_VERB_SET_PROC_COEF,
1115 /* is laptop or Desktop and enable the function "Mute internal speaker
1116 * when the external headphone out jack is plugged"
1118 if (!(ass & 0x8000))
1121 * 10~8 : Jack location
1122 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1124 * 15 : 1 --> enable the function "Mute internal speaker
1125 * when the external headphone out jack is plugged"
1127 if (!spec->autocfg.speaker_pins[0]) {
1128 if (spec->autocfg.line_out_pins[0])
1129 spec->autocfg.speaker_pins[0] =
1130 spec->autocfg.line_out_pins[0];
1135 if (!spec->autocfg.hp_pins[0]) {
1136 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1138 spec->autocfg.hp_pins[0] = porta;
1140 spec->autocfg.hp_pins[0] = porte;
1142 spec->autocfg.hp_pins[0] = portd;
1146 if (spec->autocfg.hp_pins[0])
1147 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1148 AC_VERB_SET_UNSOLICITED_ENABLE,
1149 AC_USRSP_EN | ALC880_HP_EVENT);
1151 #if 0 /* it's broken in some acses -- temporarily disabled */
1152 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1153 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1154 snd_hda_codec_write(codec,
1155 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1156 AC_VERB_SET_UNSOLICITED_ENABLE,
1157 AC_USRSP_EN | ALC880_MIC_EVENT);
1158 #endif /* disabled */
1160 spec->unsol_event = alc_sku_unsol_event;
1164 * Fix-up pin default configurations
1172 static void alc_fix_pincfg(struct hda_codec *codec,
1173 const struct snd_pci_quirk *quirk,
1174 const struct alc_pincfg **pinfix)
1176 const struct alc_pincfg *cfg;
1178 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1182 cfg = pinfix[quirk->value];
1183 for (; cfg->nid; cfg++) {
1186 for (i = 0; i < 4; i++) {
1187 snd_hda_codec_write(codec, cfg->nid, 0,
1188 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1202 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1203 /* Mic-in jack as mic in */
1204 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1205 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1206 /* Line-in jack as Line in */
1207 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1208 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1209 /* Line-Out as Front */
1210 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1217 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1218 /* Mic-in jack as mic in */
1219 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1220 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1221 /* Line-in jack as Surround */
1222 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1223 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1224 /* Line-Out as Front */
1225 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1232 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1233 /* Mic-in jack as CLFE */
1234 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1235 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1236 /* Line-in jack as Surround */
1237 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1238 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1239 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1240 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1247 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1248 /* Mic-in jack as CLFE */
1249 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1250 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1251 /* Line-in jack as Surround */
1252 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1253 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1254 /* Line-Out as Side */
1255 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1259 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1260 { 2, alc888_4ST_ch2_intel_init },
1261 { 4, alc888_4ST_ch4_intel_init },
1262 { 6, alc888_4ST_ch6_intel_init },
1263 { 8, alc888_4ST_ch8_intel_init },
1267 * ALC888 Fujitsu Siemens Amillo xa3530
1270 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1271 /* Front Mic: set to PIN_IN (empty by default) */
1272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1273 /* Connect Internal HP to Front */
1274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1275 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1276 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1277 /* Connect Bass HP to Front */
1278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1279 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1280 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1281 /* Connect Line-Out side jack (SPDIF) to Side */
1282 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1283 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1284 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1285 /* Connect Mic jack to CLFE */
1286 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1287 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1288 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1289 /* Connect Line-in jack to Surround */
1290 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1291 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1292 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1293 /* Connect HP out jack to Front */
1294 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1295 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1296 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1297 /* Enable unsolicited event for HP jack and Line-out jack */
1298 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1299 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1303 static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1305 unsigned int present;
1307 /* Line out presence */
1308 present = snd_hda_codec_read(codec, 0x17, 0,
1309 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1310 /* HP out presence */
1311 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1312 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1313 bits = present ? HDA_AMP_MUTE : 0;
1314 /* Toggle internal speakers muting */
1315 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1316 HDA_AMP_MUTE, bits);
1317 /* Toggle internal bass muting */
1318 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1319 HDA_AMP_MUTE, bits);
1322 static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1325 if (res >> 26 == ALC880_HP_EVENT)
1326 alc888_fujitsu_xa3530_automute(codec);
1331 * ALC888 Acer Aspire 4930G model
1334 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1335 /* Front Mic: set to PIN_IN (empty by default) */
1336 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1337 /* Unselect Front Mic by default in input mixer 3 */
1338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1339 /* Enable unsolicited event for HP jack */
1340 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1341 /* Connect Internal HP to front */
1342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1344 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1345 /* Connect HP out to front */
1346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1348 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1352 static struct hda_input_mux alc888_2_capture_sources[2] = {
1353 /* Front mic only available on one ADC */
1360 { "Front Mic", 0xb },
1373 static struct snd_kcontrol_new alc888_base_mixer[] = {
1374 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1375 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1377 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1380 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1381 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1382 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1383 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1384 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1390 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1392 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1393 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1397 static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1399 unsigned int present;
1401 present = snd_hda_codec_read(codec, 0x15, 0,
1402 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1403 bits = present ? HDA_AMP_MUTE : 0;
1404 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1405 HDA_AMP_MUTE, bits);
1408 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1411 if (res >> 26 == ALC880_HP_EVENT)
1412 alc888_acer_aspire_4930g_automute(codec);
1416 * ALC880 3-stack model
1418 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1419 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1420 * F-Mic = 0x1b, HP = 0x19
1423 static hda_nid_t alc880_dac_nids[4] = {
1424 /* front, rear, clfe, rear_surr */
1425 0x02, 0x05, 0x04, 0x03
1428 static hda_nid_t alc880_adc_nids[3] = {
1433 /* The datasheet says the node 0x07 is connected from inputs,
1434 * but it shows zero connection in the real implementation on some devices.
1435 * Note: this is a 915GAV bug, fixed on 915GLV
1437 static hda_nid_t alc880_adc_nids_alt[2] = {
1442 #define ALC880_DIGOUT_NID 0x06
1443 #define ALC880_DIGIN_NID 0x0a
1445 static struct hda_input_mux alc880_capture_source = {
1449 { "Front Mic", 0x3 },
1455 /* channel source setting (2/6 channel selection for 3-stack) */
1457 static struct hda_verb alc880_threestack_ch2_init[] = {
1458 /* set line-in to input, mute it */
1459 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1460 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1461 /* set mic-in to input vref 80%, mute it */
1462 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1463 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1468 static struct hda_verb alc880_threestack_ch6_init[] = {
1469 /* set line-in to output, unmute it */
1470 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1471 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1472 /* set mic-in to output, unmute it */
1473 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1474 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1478 static struct hda_channel_mode alc880_threestack_modes[2] = {
1479 { 2, alc880_threestack_ch2_init },
1480 { 6, alc880_threestack_ch6_init },
1483 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1486 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1487 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1488 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1489 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1490 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1491 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1492 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1493 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1494 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1495 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1497 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1498 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1499 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1500 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1501 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1504 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1505 .name = "Channel Mode",
1506 .info = alc_ch_mode_info,
1507 .get = alc_ch_mode_get,
1508 .put = alc_ch_mode_put,
1513 /* capture mixer elements */
1514 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1515 struct snd_ctl_elem_info *uinfo)
1517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1518 struct alc_spec *spec = codec->spec;
1521 mutex_lock(&codec->control_mutex);
1522 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1524 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1525 mutex_unlock(&codec->control_mutex);
1529 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1530 unsigned int size, unsigned int __user *tlv)
1532 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1533 struct alc_spec *spec = codec->spec;
1536 mutex_lock(&codec->control_mutex);
1537 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1539 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1540 mutex_unlock(&codec->control_mutex);
1544 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1545 struct snd_ctl_elem_value *ucontrol);
1547 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1548 struct snd_ctl_elem_value *ucontrol,
1551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1552 struct alc_spec *spec = codec->spec;
1553 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1556 mutex_lock(&codec->control_mutex);
1557 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1559 err = func(kcontrol, ucontrol);
1560 mutex_unlock(&codec->control_mutex);
1564 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1565 struct snd_ctl_elem_value *ucontrol)
1567 return alc_cap_getput_caller(kcontrol, ucontrol,
1568 snd_hda_mixer_amp_volume_get);
1571 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1572 struct snd_ctl_elem_value *ucontrol)
1574 return alc_cap_getput_caller(kcontrol, ucontrol,
1575 snd_hda_mixer_amp_volume_put);
1578 /* capture mixer elements */
1579 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1581 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1582 struct snd_ctl_elem_value *ucontrol)
1584 return alc_cap_getput_caller(kcontrol, ucontrol,
1585 snd_hda_mixer_amp_switch_get);
1588 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1589 struct snd_ctl_elem_value *ucontrol)
1591 return alc_cap_getput_caller(kcontrol, ucontrol,
1592 snd_hda_mixer_amp_switch_put);
1595 #define DEFINE_CAPMIX(num) \
1596 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1599 .name = "Capture Switch", \
1600 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1602 .info = alc_cap_sw_info, \
1603 .get = alc_cap_sw_get, \
1604 .put = alc_cap_sw_put, \
1607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1608 .name = "Capture Volume", \
1609 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1610 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1611 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1613 .info = alc_cap_vol_info, \
1614 .get = alc_cap_vol_get, \
1615 .put = alc_cap_vol_put, \
1616 .tlv = { .c = alc_cap_vol_tlv }, \
1619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1620 /* .name = "Capture Source", */ \
1621 .name = "Input Source", \
1623 .info = alc_mux_enum_info, \
1624 .get = alc_mux_enum_get, \
1625 .put = alc_mux_enum_put, \
1630 /* up to three ADCs */
1637 * ALC880 5-stack model
1639 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1641 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1642 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1645 /* additional mixers to alc880_three_stack_mixer */
1646 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1647 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1648 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1652 /* channel source setting (6/8 channel selection for 5-stack) */
1654 static struct hda_verb alc880_fivestack_ch6_init[] = {
1655 /* set line-in to input, mute it */
1656 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1657 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1662 static struct hda_verb alc880_fivestack_ch8_init[] = {
1663 /* set line-in to output, unmute it */
1664 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1665 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1669 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1670 { 6, alc880_fivestack_ch6_init },
1671 { 8, alc880_fivestack_ch8_init },
1676 * ALC880 6-stack model
1678 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1679 * Side = 0x05 (0x0f)
1680 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1681 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1684 static hda_nid_t alc880_6st_dac_nids[4] = {
1685 /* front, rear, clfe, rear_surr */
1686 0x02, 0x03, 0x04, 0x05
1689 static struct hda_input_mux alc880_6stack_capture_source = {
1693 { "Front Mic", 0x1 },
1699 /* fixed 8-channels */
1700 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1704 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1705 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1706 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1707 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1708 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1709 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1710 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1711 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1712 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1713 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1714 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1715 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1716 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1721 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1722 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1723 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1724 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1726 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1727 .name = "Channel Mode",
1728 .info = alc_ch_mode_info,
1729 .get = alc_ch_mode_get,
1730 .put = alc_ch_mode_put,
1739 * W810 has rear IO for:
1742 * Center/LFE (DAC 04)
1745 * The system also has a pair of internal speakers, and a headphone jack.
1746 * These are both connected to Line2 on the codec, hence to DAC 02.
1748 * There is a variable resistor to control the speaker or headphone
1749 * volume. This is a hardware-only device without a software API.
1751 * Plugging headphones in will disable the internal speakers. This is
1752 * implemented in hardware, not via the driver using jack sense. In
1753 * a similar fashion, plugging into the rear socket marked "front" will
1754 * disable both the speakers and headphones.
1756 * For input, there's a microphone jack, and an "audio in" jack.
1757 * These may not do anything useful with this driver yet, because I
1758 * haven't setup any initialization verbs for these yet...
1761 static hda_nid_t alc880_w810_dac_nids[3] = {
1762 /* front, rear/surround, clfe */
1766 /* fixed 6 channels */
1767 static struct hda_channel_mode alc880_w810_modes[1] = {
1771 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1772 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1773 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1774 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1775 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1776 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1777 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1778 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1779 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1780 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1789 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1790 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1794 static hda_nid_t alc880_z71v_dac_nids[1] = {
1797 #define ALC880_Z71V_HP_DAC 0x03
1799 /* fixed 2 channels */
1800 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1804 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1805 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1806 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1807 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1808 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1809 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1810 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1818 * ALC880 F1734 model
1820 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1821 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1824 static hda_nid_t alc880_f1734_dac_nids[1] = {
1827 #define ALC880_F1734_HP_DAC 0x02
1829 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1830 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1831 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1832 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1833 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1834 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1835 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1841 static struct hda_input_mux alc880_f1734_capture_source = {
1853 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1854 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1855 * Mic = 0x18, Line = 0x1a
1858 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1859 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1861 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1863 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1864 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1865 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1866 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1867 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1868 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1869 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1877 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1878 .name = "Channel Mode",
1879 .info = alc_ch_mode_info,
1880 .get = alc_ch_mode_get,
1881 .put = alc_ch_mode_put,
1887 * ALC880 ASUS W1V model
1889 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1890 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1891 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1894 /* additional mixers to alc880_asus_mixer */
1895 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1896 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1897 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1901 /* additional mixers to alc880_asus_mixer */
1902 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1903 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1904 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1909 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1911 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1913 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1914 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1916 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1917 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1918 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1923 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1924 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1925 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1926 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1927 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1928 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1929 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1930 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1931 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1936 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1937 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1940 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1941 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1944 .name = "Channel Mode",
1945 .info = alc_ch_mode_info,
1946 .get = alc_ch_mode_get,
1947 .put = alc_ch_mode_put,
1952 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1953 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1954 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1955 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1956 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1957 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1958 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1959 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1960 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1961 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1962 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1966 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1968 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1970 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1977 * virtual master controls
1981 * slave controls for virtual master
1983 static const char *alc_slave_vols[] = {
1984 "Front Playback Volume",
1985 "Surround Playback Volume",
1986 "Center Playback Volume",
1987 "LFE Playback Volume",
1988 "Side Playback Volume",
1989 "Headphone Playback Volume",
1990 "Speaker Playback Volume",
1991 "Mono Playback Volume",
1992 "Line-Out Playback Volume",
1993 "PCM Playback Volume",
1997 static const char *alc_slave_sws[] = {
1998 "Front Playback Switch",
1999 "Surround Playback Switch",
2000 "Center Playback Switch",
2001 "LFE Playback Switch",
2002 "Side Playback Switch",
2003 "Headphone Playback Switch",
2004 "Speaker Playback Switch",
2005 "Mono Playback Switch",
2006 "IEC958 Playback Switch",
2011 * build control elements
2014 static void alc_free_kctls(struct hda_codec *codec);
2016 static int alc_build_controls(struct hda_codec *codec)
2018 struct alc_spec *spec = codec->spec;
2022 for (i = 0; i < spec->num_mixers; i++) {
2023 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2027 if (spec->cap_mixer) {
2028 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2032 if (spec->multiout.dig_out_nid) {
2033 err = snd_hda_create_spdif_out_ctls(codec,
2034 spec->multiout.dig_out_nid);
2037 if (!spec->no_analog) {
2038 err = snd_hda_create_spdif_share_sw(codec,
2042 spec->multiout.share_spdif = 1;
2045 if (spec->dig_in_nid) {
2046 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2051 /* if we have no master control, let's create it */
2052 if (!spec->no_analog &&
2053 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2054 unsigned int vmaster_tlv[4];
2055 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2056 HDA_OUTPUT, vmaster_tlv);
2057 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2058 vmaster_tlv, alc_slave_vols);
2062 if (!spec->no_analog &&
2063 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2064 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2065 NULL, alc_slave_sws);
2070 alc_free_kctls(codec); /* no longer needed */
2076 * initialize the codec volumes, etc
2080 * generic initialization of ADC, input mixers and output mixers
2082 static struct hda_verb alc880_volume_init_verbs[] = {
2084 * Unmute ADC0-2 and set the default input to mic-in
2086 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2088 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2090 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2093 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2095 * Note: PASD motherboards uses the Line In 2 as the input for front
2098 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2108 * Set up output mixers (0x0c - 0x0f)
2110 /* set vol=0 to output mixers */
2111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2115 /* set up input amps for analog loopback */
2116 /* Amp Indices: DAC = 0, mixer = 1 */
2117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2130 * 3-stack pin configuration:
2131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2133 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2135 * preset connection lists of input pins
2136 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2138 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2139 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2140 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2143 * Set pin mode and muting
2145 /* set front pin widgets 0x14 for output */
2146 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2147 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2148 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2150 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2151 /* Mic2 (as headphone out) for HP output */
2152 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2154 /* Line In pin widget for input */
2155 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2156 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2157 /* Line2 (as front mic) pin widget for input and vref at 80% */
2158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2160 /* CD pin widget for input */
2161 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2167 * 5-stack pin configuration:
2168 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2169 * line-in/side = 0x1a, f-mic = 0x1b
2171 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2173 * preset connection lists of input pins
2174 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2176 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2177 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2180 * Set pin mode and muting
2182 /* set pin widgets 0x14-0x17 for output */
2183 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2184 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2185 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2186 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2187 /* unmute pins for output (no gain on this amp) */
2188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2190 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2191 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2193 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2196 /* Mic2 (as headphone out) for HP output */
2197 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2199 /* Line In pin widget for input */
2200 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2201 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2202 /* Line2 (as front mic) pin widget for input and vref at 80% */
2203 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2204 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2205 /* CD pin widget for input */
2206 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2212 * W810 pin configuration:
2213 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2215 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2216 /* hphone/speaker input selector: front DAC */
2217 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2227 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2233 * Z71V pin configuration:
2234 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2236 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2243 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2245 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2251 * 6-stack pin configuration:
2252 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2253 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2255 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2256 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2259 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2261 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2263 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2264 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2267 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2268 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2270 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2271 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2272 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2274 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2275 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2281 * Uniwill pin configuration:
2282 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2285 static struct hda_verb alc880_uniwill_init_verbs[] = {
2286 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2293 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2294 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2299 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2300 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2301 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2303 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2304 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2305 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2306 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2309 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2310 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2311 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2313 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2314 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2321 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2323 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2324 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2329 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2330 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2331 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2335 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2337 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2341 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2343 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2346 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2347 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2352 static struct hda_verb alc880_beep_init_verbs[] = {
2353 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2357 /* toggle speaker-output according to the hp-jack state */
2358 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2360 unsigned int present;
2363 present = snd_hda_codec_read(codec, 0x14, 0,
2364 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2365 bits = present ? HDA_AMP_MUTE : 0;
2366 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2367 HDA_AMP_MUTE, bits);
2368 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2369 HDA_AMP_MUTE, bits);
2372 /* auto-toggle front mic */
2373 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2375 unsigned int present;
2378 present = snd_hda_codec_read(codec, 0x18, 0,
2379 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2380 bits = present ? HDA_AMP_MUTE : 0;
2381 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2384 static void alc880_uniwill_automute(struct hda_codec *codec)
2386 alc880_uniwill_hp_automute(codec);
2387 alc880_uniwill_mic_automute(codec);
2390 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2393 /* Looks like the unsol event is incompatible with the standard
2394 * definition. 4bit tag is placed at 28 bit!
2396 switch (res >> 28) {
2397 case ALC880_HP_EVENT:
2398 alc880_uniwill_hp_automute(codec);
2400 case ALC880_MIC_EVENT:
2401 alc880_uniwill_mic_automute(codec);
2406 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2408 unsigned int present;
2411 present = snd_hda_codec_read(codec, 0x14, 0,
2412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2413 bits = present ? HDA_AMP_MUTE : 0;
2414 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2417 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2419 unsigned int present;
2421 present = snd_hda_codec_read(codec, 0x21, 0,
2422 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2423 present &= HDA_AMP_VOLMASK;
2424 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2425 HDA_AMP_VOLMASK, present);
2426 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2427 HDA_AMP_VOLMASK, present);
2430 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2433 /* Looks like the unsol event is incompatible with the standard
2434 * definition. 4bit tag is placed at 28 bit!
2436 if ((res >> 28) == ALC880_HP_EVENT)
2437 alc880_uniwill_p53_hp_automute(codec);
2438 if ((res >> 28) == ALC880_DCVOL_EVENT)
2439 alc880_uniwill_p53_dcvol_automute(codec);
2443 * F1734 pin configuration:
2444 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2446 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2447 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2448 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2449 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2450 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2451 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2454 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2458 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2459 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2460 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2461 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2462 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2463 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2464 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2465 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2466 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2468 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2469 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2475 * ASUS pin configuration:
2476 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2478 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2479 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2480 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2481 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2482 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2491 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2493 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2495 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2499 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2500 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2506 /* Enable GPIO mask and set output */
2507 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2508 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2510 /* Clevo m520g init */
2511 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2512 /* headphone output */
2513 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2519 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2522 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 /* Mic1 (rear panel) */
2524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2525 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2526 /* Mic2 (front panel) */
2527 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2528 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2531 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2532 /* change to EAPD mode */
2533 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2534 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2539 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2540 /* change to EAPD mode */
2541 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2542 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2544 /* Headphone output */
2545 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2547 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2548 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2550 /* Line In pin widget for input */
2551 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2552 /* CD pin widget for input */
2553 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2554 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2555 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2557 /* change to EAPD mode */
2558 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2559 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2565 * LG m1 express dual
2568 * Rear Line-In/Out (blue): 0x14
2569 * Build-in Mic-In: 0x15
2571 * HP-Out (green): 0x1b
2572 * Mic-In/Out (red): 0x19
2576 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2577 static hda_nid_t alc880_lg_dac_nids[3] = {
2581 /* seems analog CD is not working */
2582 static struct hda_input_mux alc880_lg_capture_source = {
2587 { "Internal Mic", 0x6 },
2591 /* 2,4,6 channel modes */
2592 static struct hda_verb alc880_lg_ch2_init[] = {
2593 /* set line-in and mic-in to input */
2594 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2595 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2599 static struct hda_verb alc880_lg_ch4_init[] = {
2600 /* set line-in to out and mic-in to input */
2601 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2602 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2606 static struct hda_verb alc880_lg_ch6_init[] = {
2607 /* set line-in and mic-in to output */
2608 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2609 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2613 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2614 { 2, alc880_lg_ch2_init },
2615 { 4, alc880_lg_ch4_init },
2616 { 6, alc880_lg_ch6_init },
2619 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2620 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2621 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2622 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2623 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2624 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2625 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2626 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2627 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2630 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2631 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2632 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2633 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2636 .name = "Channel Mode",
2637 .info = alc_ch_mode_info,
2638 .get = alc_ch_mode_get,
2639 .put = alc_ch_mode_put,
2644 static struct hda_verb alc880_lg_init_verbs[] = {
2645 /* set capture source to mic-in */
2646 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2648 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2649 /* mute all amp mixer inputs */
2650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2651 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2652 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2653 /* line-in to input */
2654 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2655 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2658 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2662 /* mic-in to input */
2663 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2664 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2665 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2668 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2669 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2671 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2675 /* toggle speaker-output according to the hp-jack state */
2676 static void alc880_lg_automute(struct hda_codec *codec)
2678 unsigned int present;
2681 present = snd_hda_codec_read(codec, 0x1b, 0,
2682 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2683 bits = present ? HDA_AMP_MUTE : 0;
2684 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2685 HDA_AMP_MUTE, bits);
2688 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2690 /* Looks like the unsol event is incompatible with the standard
2691 * definition. 4bit tag is placed at 28 bit!
2693 if ((res >> 28) == 0x01)
2694 alc880_lg_automute(codec);
2703 * Built-in Mic-In: 0x19
2709 static struct hda_input_mux alc880_lg_lw_capture_source = {
2713 { "Internal Mic", 0x1 },
2718 #define alc880_lg_lw_modes alc880_threestack_modes
2720 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2721 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2724 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2725 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2726 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2727 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2728 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2730 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2733 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2734 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2737 .name = "Channel Mode",
2738 .info = alc_ch_mode_info,
2739 .get = alc_ch_mode_get,
2740 .put = alc_ch_mode_put,
2745 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2746 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2747 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2748 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2750 /* set capture source to mic-in */
2751 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2754 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2760 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2761 /* mic-in to input */
2762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2763 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2765 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2768 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2772 /* toggle speaker-output according to the hp-jack state */
2773 static void alc880_lg_lw_automute(struct hda_codec *codec)
2775 unsigned int present;
2778 present = snd_hda_codec_read(codec, 0x1b, 0,
2779 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2780 bits = present ? HDA_AMP_MUTE : 0;
2781 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2782 HDA_AMP_MUTE, bits);
2785 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2787 /* Looks like the unsol event is incompatible with the standard
2788 * definition. 4bit tag is placed at 28 bit!
2790 if ((res >> 28) == 0x01)
2791 alc880_lg_lw_automute(codec);
2794 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2795 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2796 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2798 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2799 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2800 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2804 static struct hda_input_mux alc880_medion_rim_capture_source = {
2808 { "Internal Mic", 0x1 },
2812 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2813 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2816 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2818 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2820 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2821 /* Mic2 (as headphone out) for HP output */
2822 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 /* Internal Speaker */
2825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2829 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2831 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2835 /* toggle speaker-output according to the hp-jack state */
2836 static void alc880_medion_rim_automute(struct hda_codec *codec)
2838 unsigned int present;
2841 present = snd_hda_codec_read(codec, 0x14, 0,
2842 AC_VERB_GET_PIN_SENSE, 0)
2843 & AC_PINSENSE_PRESENCE;
2844 bits = present ? HDA_AMP_MUTE : 0;
2845 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2846 HDA_AMP_MUTE, bits);
2848 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2850 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2853 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2856 /* Looks like the unsol event is incompatible with the standard
2857 * definition. 4bit tag is placed at 28 bit!
2859 if ((res >> 28) == ALC880_HP_EVENT)
2860 alc880_medion_rim_automute(codec);
2863 #ifdef CONFIG_SND_HDA_POWER_SAVE
2864 static struct hda_amp_list alc880_loopbacks[] = {
2865 { 0x0b, HDA_INPUT, 0 },
2866 { 0x0b, HDA_INPUT, 1 },
2867 { 0x0b, HDA_INPUT, 2 },
2868 { 0x0b, HDA_INPUT, 3 },
2869 { 0x0b, HDA_INPUT, 4 },
2873 static struct hda_amp_list alc880_lg_loopbacks[] = {
2874 { 0x0b, HDA_INPUT, 1 },
2875 { 0x0b, HDA_INPUT, 6 },
2876 { 0x0b, HDA_INPUT, 7 },
2885 static int alc_init(struct hda_codec *codec)
2887 struct alc_spec *spec = codec->spec;
2891 if (codec->vendor_id == 0x10ec0888)
2892 alc888_coef_init(codec);
2894 for (i = 0; i < spec->num_init_verbs; i++)
2895 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2897 if (spec->init_hook)
2898 spec->init_hook(codec);
2903 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2905 struct alc_spec *spec = codec->spec;
2907 if (spec->unsol_event)
2908 spec->unsol_event(codec, res);
2911 #ifdef CONFIG_SND_HDA_POWER_SAVE
2912 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2914 struct alc_spec *spec = codec->spec;
2915 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2920 * Analog playback callbacks
2922 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2923 struct hda_codec *codec,
2924 struct snd_pcm_substream *substream)
2926 struct alc_spec *spec = codec->spec;
2927 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2931 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2932 struct hda_codec *codec,
2933 unsigned int stream_tag,
2934 unsigned int format,
2935 struct snd_pcm_substream *substream)
2937 struct alc_spec *spec = codec->spec;
2938 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2939 stream_tag, format, substream);
2942 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2943 struct hda_codec *codec,
2944 struct snd_pcm_substream *substream)
2946 struct alc_spec *spec = codec->spec;
2947 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2953 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2954 struct hda_codec *codec,
2955 struct snd_pcm_substream *substream)
2957 struct alc_spec *spec = codec->spec;
2958 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2961 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2962 struct hda_codec *codec,
2963 unsigned int stream_tag,
2964 unsigned int format,
2965 struct snd_pcm_substream *substream)
2967 struct alc_spec *spec = codec->spec;
2968 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2969 stream_tag, format, substream);
2972 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2973 struct hda_codec *codec,
2974 struct snd_pcm_substream *substream)
2976 struct alc_spec *spec = codec->spec;
2977 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2983 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2984 struct hda_codec *codec,
2985 unsigned int stream_tag,
2986 unsigned int format,
2987 struct snd_pcm_substream *substream)
2989 struct alc_spec *spec = codec->spec;
2991 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2992 stream_tag, 0, format);
2996 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2997 struct hda_codec *codec,
2998 struct snd_pcm_substream *substream)
3000 struct alc_spec *spec = codec->spec;
3002 snd_hda_codec_cleanup_stream(codec,
3003 spec->adc_nids[substream->number + 1]);
3010 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3014 /* NID is set in alc_build_pcms */
3016 .open = alc880_playback_pcm_open,
3017 .prepare = alc880_playback_pcm_prepare,
3018 .cleanup = alc880_playback_pcm_cleanup
3022 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3026 /* NID is set in alc_build_pcms */
3029 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3033 /* NID is set in alc_build_pcms */
3036 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3037 .substreams = 2, /* can be overridden */
3040 /* NID is set in alc_build_pcms */
3042 .prepare = alc880_alt_capture_pcm_prepare,
3043 .cleanup = alc880_alt_capture_pcm_cleanup
3047 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3051 /* NID is set in alc_build_pcms */
3053 .open = alc880_dig_playback_pcm_open,
3054 .close = alc880_dig_playback_pcm_close,
3055 .prepare = alc880_dig_playback_pcm_prepare
3059 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3063 /* NID is set in alc_build_pcms */
3066 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3067 static struct hda_pcm_stream alc_pcm_null_stream = {
3073 static int alc_build_pcms(struct hda_codec *codec)
3075 struct alc_spec *spec = codec->spec;
3076 struct hda_pcm *info = spec->pcm_rec;
3079 codec->num_pcms = 1;
3080 codec->pcm_info = info;
3082 if (spec->no_analog)
3085 info->name = spec->stream_name_analog;
3086 if (spec->stream_analog_playback) {
3087 if (snd_BUG_ON(!spec->multiout.dac_nids))
3089 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3090 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3092 if (spec->stream_analog_capture) {
3093 if (snd_BUG_ON(!spec->adc_nids))
3095 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3096 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3099 if (spec->channel_mode) {
3100 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3101 for (i = 0; i < spec->num_channel_mode; i++) {
3102 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3103 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3109 /* SPDIF for stream index #1 */
3110 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3111 codec->num_pcms = 2;
3112 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3113 info = spec->pcm_rec + 1;
3114 info->name = spec->stream_name_digital;
3115 if (spec->dig_out_type)
3116 info->pcm_type = spec->dig_out_type;
3118 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3119 if (spec->multiout.dig_out_nid &&
3120 spec->stream_digital_playback) {
3121 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3122 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3124 if (spec->dig_in_nid &&
3125 spec->stream_digital_capture) {
3126 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3127 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3129 /* FIXME: do we need this for all Realtek codec models? */
3130 codec->spdif_status_reset = 1;
3133 if (spec->no_analog)
3136 /* If the use of more than one ADC is requested for the current
3137 * model, configure a second analog capture-only PCM.
3139 /* Additional Analaog capture for index #2 */
3140 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3141 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3142 codec->num_pcms = 3;
3143 info = spec->pcm_rec + 2;
3144 info->name = spec->stream_name_analog;
3145 if (spec->alt_dac_nid) {
3146 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3147 *spec->stream_analog_alt_playback;
3148 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3151 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3152 alc_pcm_null_stream;
3153 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3155 if (spec->num_adc_nids > 1) {
3156 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3157 *spec->stream_analog_alt_capture;
3158 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3160 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3161 spec->num_adc_nids - 1;
3163 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3164 alc_pcm_null_stream;
3165 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3172 static void alc_free_kctls(struct hda_codec *codec)
3174 struct alc_spec *spec = codec->spec;
3176 if (spec->kctls.list) {
3177 struct snd_kcontrol_new *kctl = spec->kctls.list;
3179 for (i = 0; i < spec->kctls.used; i++)
3180 kfree(kctl[i].name);
3182 snd_array_free(&spec->kctls);
3185 static void alc_free(struct hda_codec *codec)
3187 struct alc_spec *spec = codec->spec;
3192 alc_free_kctls(codec);
3194 snd_hda_detach_beep_device(codec);
3195 codec->spec = NULL; /* to be sure */
3198 #ifdef SND_HDA_NEEDS_RESUME
3199 static void store_pin_configs(struct hda_codec *codec)
3201 struct alc_spec *spec = codec->spec;
3202 hda_nid_t nid, end_nid;
3204 end_nid = codec->start_nid + codec->num_nodes;
3205 for (nid = codec->start_nid; nid < end_nid; nid++) {
3206 unsigned int wid_caps = get_wcaps(codec, nid);
3207 unsigned int wid_type =
3208 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3209 if (wid_type != AC_WID_PIN)
3211 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
3213 spec->pin_nids[spec->num_pins] = nid;
3214 spec->pin_cfgs[spec->num_pins] =
3215 snd_hda_codec_read(codec, nid, 0,
3216 AC_VERB_GET_CONFIG_DEFAULT, 0);
3221 static void resume_pin_configs(struct hda_codec *codec)
3223 struct alc_spec *spec = codec->spec;
3226 for (i = 0; i < spec->num_pins; i++) {
3227 hda_nid_t pin_nid = spec->pin_nids[i];
3228 unsigned int pin_config = spec->pin_cfgs[i];
3229 snd_hda_codec_write(codec, pin_nid, 0,
3230 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
3231 pin_config & 0x000000ff);
3232 snd_hda_codec_write(codec, pin_nid, 0,
3233 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
3234 (pin_config & 0x0000ff00) >> 8);
3235 snd_hda_codec_write(codec, pin_nid, 0,
3236 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
3237 (pin_config & 0x00ff0000) >> 16);
3238 snd_hda_codec_write(codec, pin_nid, 0,
3239 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
3244 static int alc_resume(struct hda_codec *codec)
3246 resume_pin_configs(codec);
3247 codec->patch_ops.init(codec);
3248 snd_hda_codec_resume_amp(codec);
3249 snd_hda_codec_resume_cache(codec);
3253 #define store_pin_configs(codec)
3258 static struct hda_codec_ops alc_patch_ops = {
3259 .build_controls = alc_build_controls,
3260 .build_pcms = alc_build_pcms,
3263 .unsol_event = alc_unsol_event,
3264 #ifdef SND_HDA_NEEDS_RESUME
3265 .resume = alc_resume,
3267 #ifdef CONFIG_SND_HDA_POWER_SAVE
3268 .check_power_status = alc_check_power_status,
3274 * Test configuration for debugging
3276 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3279 #ifdef CONFIG_SND_DEBUG
3280 static hda_nid_t alc880_test_dac_nids[4] = {
3281 0x02, 0x03, 0x04, 0x05
3284 static struct hda_input_mux alc880_test_capture_source = {
3293 { "Surround", 0x6 },
3297 static struct hda_channel_mode alc880_test_modes[4] = {
3304 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3305 struct snd_ctl_elem_info *uinfo)
3307 static char *texts[] = {
3308 "N/A", "Line Out", "HP Out",
3309 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3311 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3313 uinfo->value.enumerated.items = 8;
3314 if (uinfo->value.enumerated.item >= 8)
3315 uinfo->value.enumerated.item = 7;
3316 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3320 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3321 struct snd_ctl_elem_value *ucontrol)
3323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3324 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3325 unsigned int pin_ctl, item = 0;
3327 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3328 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3329 if (pin_ctl & AC_PINCTL_OUT_EN) {
3330 if (pin_ctl & AC_PINCTL_HP_EN)
3334 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3335 switch (pin_ctl & AC_PINCTL_VREFEN) {
3336 case AC_PINCTL_VREF_HIZ: item = 3; break;
3337 case AC_PINCTL_VREF_50: item = 4; break;
3338 case AC_PINCTL_VREF_GRD: item = 5; break;
3339 case AC_PINCTL_VREF_80: item = 6; break;
3340 case AC_PINCTL_VREF_100: item = 7; break;
3343 ucontrol->value.enumerated.item[0] = item;
3347 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3348 struct snd_ctl_elem_value *ucontrol)
3350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3351 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3352 static unsigned int ctls[] = {
3353 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3354 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3355 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3356 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3357 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3358 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3360 unsigned int old_ctl, new_ctl;
3362 old_ctl = snd_hda_codec_read(codec, nid, 0,
3363 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3364 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3365 if (old_ctl != new_ctl) {
3367 snd_hda_codec_write_cache(codec, nid, 0,
3368 AC_VERB_SET_PIN_WIDGET_CONTROL,
3370 val = ucontrol->value.enumerated.item[0] >= 3 ?
3372 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3379 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3380 struct snd_ctl_elem_info *uinfo)
3382 static char *texts[] = {
3383 "Front", "Surround", "CLFE", "Side"
3385 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3387 uinfo->value.enumerated.items = 4;
3388 if (uinfo->value.enumerated.item >= 4)
3389 uinfo->value.enumerated.item = 3;
3390 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3394 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3395 struct snd_ctl_elem_value *ucontrol)
3397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3398 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3401 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3402 ucontrol->value.enumerated.item[0] = sel & 3;
3406 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3407 struct snd_ctl_elem_value *ucontrol)
3409 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3410 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3413 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3414 if (ucontrol->value.enumerated.item[0] != sel) {
3415 sel = ucontrol->value.enumerated.item[0] & 3;
3416 snd_hda_codec_write_cache(codec, nid, 0,
3417 AC_VERB_SET_CONNECT_SEL, sel);
3423 #define PIN_CTL_TEST(xname,nid) { \
3424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3426 .info = alc_test_pin_ctl_info, \
3427 .get = alc_test_pin_ctl_get, \
3428 .put = alc_test_pin_ctl_put, \
3429 .private_value = nid \
3432 #define PIN_SRC_TEST(xname,nid) { \
3433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3435 .info = alc_test_pin_src_info, \
3436 .get = alc_test_pin_src_get, \
3437 .put = alc_test_pin_src_put, \
3438 .private_value = nid \
3441 static struct snd_kcontrol_new alc880_test_mixer[] = {
3442 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3443 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3444 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3445 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3447 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3448 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3449 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3450 PIN_CTL_TEST("Front Pin Mode", 0x14),
3451 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3452 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3453 PIN_CTL_TEST("Side Pin Mode", 0x17),
3454 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3455 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3456 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3457 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3458 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3459 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3460 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3461 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3462 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3463 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3464 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3465 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3466 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3467 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3468 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3469 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3470 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3471 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3474 .name = "Channel Mode",
3475 .info = alc_ch_mode_info,
3476 .get = alc_ch_mode_get,
3477 .put = alc_ch_mode_put,
3482 static struct hda_verb alc880_test_init_verbs[] = {
3483 /* Unmute inputs of 0x0c - 0x0f */
3484 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3486 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3487 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3488 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3492 /* Vol output for 0x0c-0x0f */
3493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3494 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3495 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3496 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3497 /* Set output pins 0x14-0x17 */
3498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3500 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3501 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3502 /* Unmute output pins 0x14-0x17 */
3503 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3507 /* Set input pins 0x18-0x1c */
3508 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3509 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3510 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3512 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3513 /* Mute input pins 0x18-0x1b */
3514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3516 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3520 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3521 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3522 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3523 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3524 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3525 /* Analog input/passthru */
3526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3538 static const char *alc880_models[ALC880_MODEL_LAST] = {
3539 [ALC880_3ST] = "3stack",
3540 [ALC880_TCL_S700] = "tcl",
3541 [ALC880_3ST_DIG] = "3stack-digout",
3542 [ALC880_CLEVO] = "clevo",
3543 [ALC880_5ST] = "5stack",
3544 [ALC880_5ST_DIG] = "5stack-digout",
3545 [ALC880_W810] = "w810",
3546 [ALC880_Z71V] = "z71v",
3547 [ALC880_6ST] = "6stack",
3548 [ALC880_6ST_DIG] = "6stack-digout",
3549 [ALC880_ASUS] = "asus",
3550 [ALC880_ASUS_W1V] = "asus-w1v",
3551 [ALC880_ASUS_DIG] = "asus-dig",
3552 [ALC880_ASUS_DIG2] = "asus-dig2",
3553 [ALC880_UNIWILL_DIG] = "uniwill",
3554 [ALC880_UNIWILL_P53] = "uniwill-p53",
3555 [ALC880_FUJITSU] = "fujitsu",
3556 [ALC880_F1734] = "F1734",
3558 [ALC880_LG_LW] = "lg-lw",
3559 [ALC880_MEDION_RIM] = "medion",
3560 #ifdef CONFIG_SND_DEBUG
3561 [ALC880_TEST] = "test",
3563 [ALC880_AUTO] = "auto",
3566 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3567 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3568 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3569 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3570 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3571 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3572 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3573 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3574 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3575 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3576 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3577 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3578 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3579 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3580 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3581 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3582 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3583 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3584 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3585 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3586 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3587 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3588 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3589 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3590 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3591 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3592 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3593 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3594 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3595 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3596 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3597 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3598 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3599 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3600 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3601 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3602 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3603 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3604 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3605 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3606 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3607 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3608 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3609 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3610 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3611 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3612 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3613 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3614 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3615 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3616 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3617 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3618 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3619 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3620 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3621 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3622 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3623 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3624 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3625 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3626 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3627 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3628 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3629 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3630 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3631 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3632 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3633 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3634 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3635 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3636 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3637 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3642 * ALC880 codec presets
3644 static struct alc_config_preset alc880_presets[] = {
3646 .mixers = { alc880_three_stack_mixer },
3647 .init_verbs = { alc880_volume_init_verbs,
3648 alc880_pin_3stack_init_verbs },
3649 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3650 .dac_nids = alc880_dac_nids,
3651 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3652 .channel_mode = alc880_threestack_modes,
3654 .input_mux = &alc880_capture_source,
3656 [ALC880_3ST_DIG] = {
3657 .mixers = { alc880_three_stack_mixer },
3658 .init_verbs = { alc880_volume_init_verbs,
3659 alc880_pin_3stack_init_verbs },
3660 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3661 .dac_nids = alc880_dac_nids,
3662 .dig_out_nid = ALC880_DIGOUT_NID,
3663 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3664 .channel_mode = alc880_threestack_modes,
3666 .input_mux = &alc880_capture_source,
3668 [ALC880_TCL_S700] = {
3669 .mixers = { alc880_tcl_s700_mixer },
3670 .init_verbs = { alc880_volume_init_verbs,
3671 alc880_pin_tcl_S700_init_verbs,
3672 alc880_gpio2_init_verbs },
3673 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3674 .dac_nids = alc880_dac_nids,
3675 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3676 .num_adc_nids = 1, /* single ADC */
3678 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3679 .channel_mode = alc880_2_jack_modes,
3680 .input_mux = &alc880_capture_source,
3683 .mixers = { alc880_three_stack_mixer,
3684 alc880_five_stack_mixer},
3685 .init_verbs = { alc880_volume_init_verbs,
3686 alc880_pin_5stack_init_verbs },
3687 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3688 .dac_nids = alc880_dac_nids,
3689 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3690 .channel_mode = alc880_fivestack_modes,
3691 .input_mux = &alc880_capture_source,
3693 [ALC880_5ST_DIG] = {
3694 .mixers = { alc880_three_stack_mixer,
3695 alc880_five_stack_mixer },
3696 .init_verbs = { alc880_volume_init_verbs,
3697 alc880_pin_5stack_init_verbs },
3698 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3699 .dac_nids = alc880_dac_nids,
3700 .dig_out_nid = ALC880_DIGOUT_NID,
3701 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3702 .channel_mode = alc880_fivestack_modes,
3703 .input_mux = &alc880_capture_source,
3706 .mixers = { alc880_six_stack_mixer },
3707 .init_verbs = { alc880_volume_init_verbs,
3708 alc880_pin_6stack_init_verbs },
3709 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3710 .dac_nids = alc880_6st_dac_nids,
3711 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3712 .channel_mode = alc880_sixstack_modes,
3713 .input_mux = &alc880_6stack_capture_source,
3715 [ALC880_6ST_DIG] = {
3716 .mixers = { alc880_six_stack_mixer },
3717 .init_verbs = { alc880_volume_init_verbs,
3718 alc880_pin_6stack_init_verbs },
3719 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3720 .dac_nids = alc880_6st_dac_nids,
3721 .dig_out_nid = ALC880_DIGOUT_NID,
3722 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3723 .channel_mode = alc880_sixstack_modes,
3724 .input_mux = &alc880_6stack_capture_source,
3727 .mixers = { alc880_w810_base_mixer },
3728 .init_verbs = { alc880_volume_init_verbs,
3729 alc880_pin_w810_init_verbs,
3730 alc880_gpio2_init_verbs },
3731 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3732 .dac_nids = alc880_w810_dac_nids,
3733 .dig_out_nid = ALC880_DIGOUT_NID,
3734 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3735 .channel_mode = alc880_w810_modes,
3736 .input_mux = &alc880_capture_source,
3739 .mixers = { alc880_z71v_mixer },
3740 .init_verbs = { alc880_volume_init_verbs,
3741 alc880_pin_z71v_init_verbs },
3742 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3743 .dac_nids = alc880_z71v_dac_nids,
3744 .dig_out_nid = ALC880_DIGOUT_NID,
3746 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3747 .channel_mode = alc880_2_jack_modes,
3748 .input_mux = &alc880_capture_source,
3751 .mixers = { alc880_f1734_mixer },
3752 .init_verbs = { alc880_volume_init_verbs,
3753 alc880_pin_f1734_init_verbs },
3754 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3755 .dac_nids = alc880_f1734_dac_nids,
3757 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3758 .channel_mode = alc880_2_jack_modes,
3759 .input_mux = &alc880_f1734_capture_source,
3760 .unsol_event = alc880_uniwill_p53_unsol_event,
3761 .init_hook = alc880_uniwill_p53_hp_automute,
3764 .mixers = { alc880_asus_mixer },
3765 .init_verbs = { alc880_volume_init_verbs,
3766 alc880_pin_asus_init_verbs,
3767 alc880_gpio1_init_verbs },
3768 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3769 .dac_nids = alc880_asus_dac_nids,
3770 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3771 .channel_mode = alc880_asus_modes,
3773 .input_mux = &alc880_capture_source,
3775 [ALC880_ASUS_DIG] = {
3776 .mixers = { alc880_asus_mixer },
3777 .init_verbs = { alc880_volume_init_verbs,
3778 alc880_pin_asus_init_verbs,
3779 alc880_gpio1_init_verbs },
3780 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3781 .dac_nids = alc880_asus_dac_nids,
3782 .dig_out_nid = ALC880_DIGOUT_NID,
3783 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3784 .channel_mode = alc880_asus_modes,
3786 .input_mux = &alc880_capture_source,
3788 [ALC880_ASUS_DIG2] = {
3789 .mixers = { alc880_asus_mixer },
3790 .init_verbs = { alc880_volume_init_verbs,
3791 alc880_pin_asus_init_verbs,
3792 alc880_gpio2_init_verbs }, /* use GPIO2 */
3793 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3794 .dac_nids = alc880_asus_dac_nids,
3795 .dig_out_nid = ALC880_DIGOUT_NID,
3796 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3797 .channel_mode = alc880_asus_modes,
3799 .input_mux = &alc880_capture_source,
3801 [ALC880_ASUS_W1V] = {
3802 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3803 .init_verbs = { alc880_volume_init_verbs,
3804 alc880_pin_asus_init_verbs,
3805 alc880_gpio1_init_verbs },
3806 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3807 .dac_nids = alc880_asus_dac_nids,
3808 .dig_out_nid = ALC880_DIGOUT_NID,
3809 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3810 .channel_mode = alc880_asus_modes,
3812 .input_mux = &alc880_capture_source,
3814 [ALC880_UNIWILL_DIG] = {
3815 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3816 .init_verbs = { alc880_volume_init_verbs,
3817 alc880_pin_asus_init_verbs },
3818 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3819 .dac_nids = alc880_asus_dac_nids,
3820 .dig_out_nid = ALC880_DIGOUT_NID,
3821 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3822 .channel_mode = alc880_asus_modes,
3824 .input_mux = &alc880_capture_source,
3826 [ALC880_UNIWILL] = {
3827 .mixers = { alc880_uniwill_mixer },
3828 .init_verbs = { alc880_volume_init_verbs,
3829 alc880_uniwill_init_verbs },
3830 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3831 .dac_nids = alc880_asus_dac_nids,
3832 .dig_out_nid = ALC880_DIGOUT_NID,
3833 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3834 .channel_mode = alc880_threestack_modes,
3836 .input_mux = &alc880_capture_source,
3837 .unsol_event = alc880_uniwill_unsol_event,
3838 .init_hook = alc880_uniwill_automute,
3840 [ALC880_UNIWILL_P53] = {
3841 .mixers = { alc880_uniwill_p53_mixer },
3842 .init_verbs = { alc880_volume_init_verbs,
3843 alc880_uniwill_p53_init_verbs },
3844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3845 .dac_nids = alc880_asus_dac_nids,
3846 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3847 .channel_mode = alc880_threestack_modes,
3848 .input_mux = &alc880_capture_source,
3849 .unsol_event = alc880_uniwill_p53_unsol_event,
3850 .init_hook = alc880_uniwill_p53_hp_automute,
3852 [ALC880_FUJITSU] = {
3853 .mixers = { alc880_fujitsu_mixer,
3854 alc880_pcbeep_mixer, },
3855 .init_verbs = { alc880_volume_init_verbs,
3856 alc880_uniwill_p53_init_verbs,
3857 alc880_beep_init_verbs },
3858 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3859 .dac_nids = alc880_dac_nids,
3860 .dig_out_nid = ALC880_DIGOUT_NID,
3861 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3862 .channel_mode = alc880_2_jack_modes,
3863 .input_mux = &alc880_capture_source,
3864 .unsol_event = alc880_uniwill_p53_unsol_event,
3865 .init_hook = alc880_uniwill_p53_hp_automute,
3868 .mixers = { alc880_three_stack_mixer },
3869 .init_verbs = { alc880_volume_init_verbs,
3870 alc880_pin_clevo_init_verbs },
3871 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3872 .dac_nids = alc880_dac_nids,
3874 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3875 .channel_mode = alc880_threestack_modes,
3877 .input_mux = &alc880_capture_source,
3880 .mixers = { alc880_lg_mixer },
3881 .init_verbs = { alc880_volume_init_verbs,
3882 alc880_lg_init_verbs },
3883 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3884 .dac_nids = alc880_lg_dac_nids,
3885 .dig_out_nid = ALC880_DIGOUT_NID,
3886 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3887 .channel_mode = alc880_lg_ch_modes,
3889 .input_mux = &alc880_lg_capture_source,
3890 .unsol_event = alc880_lg_unsol_event,
3891 .init_hook = alc880_lg_automute,
3892 #ifdef CONFIG_SND_HDA_POWER_SAVE
3893 .loopbacks = alc880_lg_loopbacks,
3897 .mixers = { alc880_lg_lw_mixer },
3898 .init_verbs = { alc880_volume_init_verbs,
3899 alc880_lg_lw_init_verbs },
3900 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3901 .dac_nids = alc880_dac_nids,
3902 .dig_out_nid = ALC880_DIGOUT_NID,
3903 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3904 .channel_mode = alc880_lg_lw_modes,
3905 .input_mux = &alc880_lg_lw_capture_source,
3906 .unsol_event = alc880_lg_lw_unsol_event,
3907 .init_hook = alc880_lg_lw_automute,
3909 [ALC880_MEDION_RIM] = {
3910 .mixers = { alc880_medion_rim_mixer },
3911 .init_verbs = { alc880_volume_init_verbs,
3912 alc880_medion_rim_init_verbs,
3913 alc_gpio2_init_verbs },
3914 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3915 .dac_nids = alc880_dac_nids,
3916 .dig_out_nid = ALC880_DIGOUT_NID,
3917 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3918 .channel_mode = alc880_2_jack_modes,
3919 .input_mux = &alc880_medion_rim_capture_source,
3920 .unsol_event = alc880_medion_rim_unsol_event,
3921 .init_hook = alc880_medion_rim_automute,
3923 #ifdef CONFIG_SND_DEBUG
3925 .mixers = { alc880_test_mixer },
3926 .init_verbs = { alc880_test_init_verbs },
3927 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3928 .dac_nids = alc880_test_dac_nids,
3929 .dig_out_nid = ALC880_DIGOUT_NID,
3930 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3931 .channel_mode = alc880_test_modes,
3932 .input_mux = &alc880_test_capture_source,
3938 * Automatic parse of I/O pins from the BIOS configuration
3943 ALC_CTL_WIDGET_MUTE,
3946 static struct snd_kcontrol_new alc880_control_templates[] = {
3947 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3948 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3949 HDA_BIND_MUTE(NULL, 0, 0, 0),
3952 /* add dynamic controls */
3953 static int add_control(struct alc_spec *spec, int type, const char *name,
3956 struct snd_kcontrol_new *knew;
3958 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3959 knew = snd_array_new(&spec->kctls);
3962 *knew = alc880_control_templates[type];
3963 knew->name = kstrdup(name, GFP_KERNEL);
3966 knew->private_value = val;
3970 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3971 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3972 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3973 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3974 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3975 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3976 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3977 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3978 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3979 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3980 #define ALC880_PIN_CD_NID 0x1c
3982 /* fill in the dac_nids table from the parsed pin configuration */
3983 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3984 const struct auto_pin_cfg *cfg)
3990 memset(assigned, 0, sizeof(assigned));
3991 spec->multiout.dac_nids = spec->private_dac_nids;
3993 /* check the pins hardwired to audio widget */
3994 for (i = 0; i < cfg->line_outs; i++) {
3995 nid = cfg->line_out_pins[i];
3996 if (alc880_is_fixed_pin(nid)) {
3997 int idx = alc880_fixed_pin_idx(nid);
3998 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4002 /* left pins can be connect to any audio widget */
4003 for (i = 0; i < cfg->line_outs; i++) {
4004 nid = cfg->line_out_pins[i];
4005 if (alc880_is_fixed_pin(nid))
4007 /* search for an empty channel */
4008 for (j = 0; j < cfg->line_outs; j++) {
4010 spec->multiout.dac_nids[i] =
4011 alc880_idx_to_dac(j);
4017 spec->multiout.num_dacs = cfg->line_outs;
4021 /* add playback controls from the parsed DAC table */
4022 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4023 const struct auto_pin_cfg *cfg)
4026 static const char *chname[4] = {
4027 "Front", "Surround", NULL /*CLFE*/, "Side"
4032 for (i = 0; i < cfg->line_outs; i++) {
4033 if (!spec->multiout.dac_nids[i])
4035 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4038 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4039 "Center Playback Volume",
4040 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4044 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4045 "LFE Playback Volume",
4046 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4050 err = add_control(spec, ALC_CTL_BIND_MUTE,
4051 "Center Playback Switch",
4052 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4056 err = add_control(spec, ALC_CTL_BIND_MUTE,
4057 "LFE Playback Switch",
4058 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4063 sprintf(name, "%s Playback Volume", chname[i]);
4064 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4065 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4069 sprintf(name, "%s Playback Switch", chname[i]);
4070 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4071 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4080 /* add playback controls for speaker and HP outputs */
4081 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4091 if (alc880_is_fixed_pin(pin)) {
4092 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4093 /* specify the DAC as the extra output */
4094 if (!spec->multiout.hp_nid)
4095 spec->multiout.hp_nid = nid;
4097 spec->multiout.extra_out_nid[0] = nid;
4098 /* control HP volume/switch on the output mixer amp */
4099 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4100 sprintf(name, "%s Playback Volume", pfx);
4101 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4102 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4105 sprintf(name, "%s Playback Switch", pfx);
4106 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4107 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4110 } else if (alc880_is_multi_pin(pin)) {
4111 /* set manual connection */
4112 /* we have only a switch on HP-out PIN */
4113 sprintf(name, "%s Playback Switch", pfx);
4114 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4115 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4122 /* create input playback/capture controls for the given pin */
4123 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4124 const char *ctlname,
4125 int idx, hda_nid_t mix_nid)
4130 sprintf(name, "%s Playback Volume", ctlname);
4131 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4132 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4135 sprintf(name, "%s Playback Switch", ctlname);
4136 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4137 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4143 /* create playback/capture controls for input pins */
4144 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4145 const struct auto_pin_cfg *cfg)
4147 struct hda_input_mux *imux = &spec->private_imux[0];
4150 for (i = 0; i < AUTO_PIN_LAST; i++) {
4151 if (alc880_is_input_pin(cfg->input_pins[i])) {
4152 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4153 err = new_analog_input(spec, cfg->input_pins[i],
4154 auto_pin_cfg_labels[i],
4158 imux->items[imux->num_items].label =
4159 auto_pin_cfg_labels[i];
4160 imux->items[imux->num_items].index =
4161 alc880_input_pin_idx(cfg->input_pins[i]);
4168 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4169 unsigned int pin_type)
4171 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4174 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4178 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4179 hda_nid_t nid, int pin_type,
4182 alc_set_pin_output(codec, nid, pin_type);
4183 /* need the manual connection? */
4184 if (alc880_is_multi_pin(nid)) {
4185 struct alc_spec *spec = codec->spec;
4186 int idx = alc880_multi_pin_idx(nid);
4187 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4188 AC_VERB_SET_CONNECT_SEL,
4189 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4193 static int get_pin_type(int line_out_type)
4195 if (line_out_type == AUTO_PIN_HP_OUT)
4201 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4203 struct alc_spec *spec = codec->spec;
4206 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4207 for (i = 0; i < spec->autocfg.line_outs; i++) {
4208 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4209 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4210 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4214 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4216 struct alc_spec *spec = codec->spec;
4219 pin = spec->autocfg.speaker_pins[0];
4220 if (pin) /* connect to front */
4221 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4222 pin = spec->autocfg.hp_pins[0];
4223 if (pin) /* connect to front */
4224 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4227 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4229 struct alc_spec *spec = codec->spec;
4232 for (i = 0; i < AUTO_PIN_LAST; i++) {
4233 hda_nid_t nid = spec->autocfg.input_pins[i];
4234 if (alc880_is_input_pin(nid)) {
4235 snd_hda_codec_write(codec, nid, 0,
4236 AC_VERB_SET_PIN_WIDGET_CONTROL,
4237 i <= AUTO_PIN_FRONT_MIC ?
4238 PIN_VREF80 : PIN_IN);
4239 if (nid != ALC880_PIN_CD_NID)
4240 snd_hda_codec_write(codec, nid, 0,
4241 AC_VERB_SET_AMP_GAIN_MUTE,
4247 /* parse the BIOS configuration and set up the alc_spec */
4248 /* return 1 if successful, 0 if the proper config is not found,
4249 * or a negative error code
4251 static int alc880_parse_auto_config(struct hda_codec *codec)
4253 struct alc_spec *spec = codec->spec;
4255 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4257 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4261 if (!spec->autocfg.line_outs)
4262 return 0; /* can't find valid BIOS pin config */
4264 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4267 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4270 err = alc880_auto_create_extra_out(spec,
4271 spec->autocfg.speaker_pins[0],
4275 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4279 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4283 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4285 if (spec->autocfg.dig_out_pin)
4286 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4287 if (spec->autocfg.dig_in_pin)
4288 spec->dig_in_nid = ALC880_DIGIN_NID;
4290 if (spec->kctls.list)
4291 add_mixer(spec, spec->kctls.list);
4293 add_verb(spec, alc880_volume_init_verbs);
4295 spec->num_mux_defs = 1;
4296 spec->input_mux = &spec->private_imux[0];
4298 store_pin_configs(codec);
4302 /* additional initialization for auto-configuration model */
4303 static void alc880_auto_init(struct hda_codec *codec)
4305 struct alc_spec *spec = codec->spec;
4306 alc880_auto_init_multi_out(codec);
4307 alc880_auto_init_extra_out(codec);
4308 alc880_auto_init_analog_input(codec);
4309 if (spec->unsol_event)
4310 alc_inithook(codec);
4314 * OK, here we have finally the patch for ALC880
4317 static void set_capture_mixer(struct alc_spec *spec)
4319 static struct snd_kcontrol_new *caps[3] = {
4324 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3)
4325 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4328 static int patch_alc880(struct hda_codec *codec)
4330 struct alc_spec *spec;
4334 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4340 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4343 if (board_config < 0) {
4344 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4345 "trying auto-probe from BIOS...\n");
4346 board_config = ALC880_AUTO;
4349 if (board_config == ALC880_AUTO) {
4350 /* automatic parse from the BIOS config */
4351 err = alc880_parse_auto_config(codec);
4357 "hda_codec: Cannot set up configuration "
4358 "from BIOS. Using 3-stack mode...\n");
4359 board_config = ALC880_3ST;
4363 err = snd_hda_attach_beep_device(codec, 0x1);
4369 if (board_config != ALC880_AUTO)
4370 setup_preset(spec, &alc880_presets[board_config]);
4372 spec->stream_name_analog = "ALC880 Analog";
4373 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4374 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4375 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4377 spec->stream_name_digital = "ALC880 Digital";
4378 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4379 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4381 if (!spec->adc_nids && spec->input_mux) {
4382 /* check whether NID 0x07 is valid */
4383 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4385 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4386 if (wcap != AC_WID_AUD_IN) {
4387 spec->adc_nids = alc880_adc_nids_alt;
4388 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4390 spec->adc_nids = alc880_adc_nids;
4391 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4394 set_capture_mixer(spec);
4396 spec->vmaster_nid = 0x0c;
4398 codec->patch_ops = alc_patch_ops;
4399 if (board_config == ALC880_AUTO)
4400 spec->init_hook = alc880_auto_init;
4401 #ifdef CONFIG_SND_HDA_POWER_SAVE
4402 if (!spec->loopback.amplist)
4403 spec->loopback.amplist = alc880_loopbacks;
4405 codec->proc_widget_hook = print_realtek_coef;
4415 static hda_nid_t alc260_dac_nids[1] = {
4420 static hda_nid_t alc260_adc_nids[1] = {
4425 static hda_nid_t alc260_adc_nids_alt[1] = {
4430 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4431 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4433 static hda_nid_t alc260_dual_adc_nids[2] = {
4438 #define ALC260_DIGOUT_NID 0x03
4439 #define ALC260_DIGIN_NID 0x06
4441 static struct hda_input_mux alc260_capture_source = {
4445 { "Front Mic", 0x1 },
4451 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4452 * headphone jack and the internal CD lines since these are the only pins at
4453 * which audio can appear. For flexibility, also allow the option of
4454 * recording the mixer output on the second ADC (ADC0 doesn't have a
4455 * connection to the mixer output).
4457 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4461 { "Mic/Line", 0x0 },
4463 { "Headphone", 0x2 },
4469 { "Mic/Line", 0x0 },
4471 { "Headphone", 0x2 },
4478 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4479 * the Fujitsu S702x, but jacks are marked differently.
4481 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4488 { "Headphone", 0x5 },
4497 { "Headphone", 0x6 },
4503 * This is just place-holder, so there's something for alc_build_pcms to look
4504 * at when it calculates the maximum number of channels. ALC260 has no mixer
4505 * element which allows changing the channel mode, so the verb list is
4508 static struct hda_channel_mode alc260_modes[1] = {
4513 /* Mixer combinations
4515 * basic: base_output + input + pc_beep + capture
4516 * HP: base_output + input + capture_alt
4517 * HP_3013: hp_3013 + input + capture
4518 * fujitsu: fujitsu + capture
4519 * acer: acer + capture
4522 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4523 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4524 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4525 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4526 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4527 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4528 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4532 static struct snd_kcontrol_new alc260_input_mixer[] = {
4533 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4534 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4535 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4536 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4538 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4539 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4540 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4544 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4545 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4546 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4550 /* update HP, line and mono out pins according to the master switch */
4551 static void alc260_hp_master_update(struct hda_codec *codec,
4552 hda_nid_t hp, hda_nid_t line,
4555 struct alc_spec *spec = codec->spec;
4556 unsigned int val = spec->master_sw ? PIN_HP : 0;
4557 /* change HP and line-out pins */
4558 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4560 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4562 /* mono (speaker) depending on the HP jack sense */
4563 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4564 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4568 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4569 struct snd_ctl_elem_value *ucontrol)
4571 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4572 struct alc_spec *spec = codec->spec;
4573 *ucontrol->value.integer.value = spec->master_sw;
4577 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4578 struct snd_ctl_elem_value *ucontrol)
4580 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4581 struct alc_spec *spec = codec->spec;
4582 int val = !!*ucontrol->value.integer.value;
4583 hda_nid_t hp, line, mono;
4585 if (val == spec->master_sw)
4587 spec->master_sw = val;
4588 hp = (kcontrol->private_value >> 16) & 0xff;
4589 line = (kcontrol->private_value >> 8) & 0xff;
4590 mono = kcontrol->private_value & 0xff;
4591 alc260_hp_master_update(codec, hp, line, mono);
4595 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4598 .name = "Master Playback Switch",
4599 .info = snd_ctl_boolean_mono_info,
4600 .get = alc260_hp_master_sw_get,
4601 .put = alc260_hp_master_sw_put,
4602 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4604 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4605 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4606 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4607 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4608 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4610 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4614 static struct hda_verb alc260_hp_unsol_verbs[] = {
4615 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4619 static void alc260_hp_automute(struct hda_codec *codec)
4621 struct alc_spec *spec = codec->spec;
4622 unsigned int present;
4624 present = snd_hda_codec_read(codec, 0x10, 0,
4625 AC_VERB_GET_PIN_SENSE, 0);
4626 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4627 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4630 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4632 if ((res >> 26) == ALC880_HP_EVENT)
4633 alc260_hp_automute(codec);
4636 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4639 .name = "Master Playback Switch",
4640 .info = snd_ctl_boolean_mono_info,
4641 .get = alc260_hp_master_sw_get,
4642 .put = alc260_hp_master_sw_put,
4643 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4645 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4646 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4647 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4648 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4649 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4651 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4652 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4656 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4657 .ops = &snd_hda_bind_vol,
4659 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4660 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4661 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4666 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4667 .ops = &snd_hda_bind_sw,
4669 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4670 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4675 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4676 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4677 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4678 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4683 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4684 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4688 static void alc260_hp_3013_automute(struct hda_codec *codec)
4690 struct alc_spec *spec = codec->spec;
4691 unsigned int present;
4693 present = snd_hda_codec_read(codec, 0x15, 0,
4694 AC_VERB_GET_PIN_SENSE, 0);
4695 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4696 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4699 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4702 if ((res >> 26) == ALC880_HP_EVENT)
4703 alc260_hp_3013_automute(codec);
4706 static void alc260_hp_3012_automute(struct hda_codec *codec)
4708 unsigned int present, bits;
4710 present = snd_hda_codec_read(codec, 0x10, 0,
4711 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4713 bits = present ? 0 : PIN_OUT;
4714 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4716 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4718 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4722 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4725 if ((res >> 26) == ALC880_HP_EVENT)
4726 alc260_hp_3012_automute(codec);
4729 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4730 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4732 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4733 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4734 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4735 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4736 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4737 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4738 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4739 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4740 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4741 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4742 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4743 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4744 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4748 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4749 * versions of the ALC260 don't act on requests to enable mic bias from NID
4750 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4751 * datasheet doesn't mention this restriction. At this stage it's not clear
4752 * whether this behaviour is intentional or is a hardware bug in chip
4753 * revisions available in early 2006. Therefore for now allow the
4754 * "Headphone Jack Mode" control to span all choices, but if it turns out
4755 * that the lack of mic bias for this NID is intentional we could change the
4756 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4758 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4759 * don't appear to make the mic bias available from the "line" jack, even
4760 * though the NID used for this jack (0x14) can supply it. The theory is
4761 * that perhaps Acer have included blocking capacitors between the ALC260
4762 * and the output jack. If this turns out to be the case for all such
4763 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4764 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4766 * The C20x Tablet series have a mono internal speaker which is controlled
4767 * via the chip's Mono sum widget and pin complex, so include the necessary
4768 * controls for such models. On models without a "mono speaker" the control
4769 * won't do anything.
4771 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4772 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4773 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4774 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4775 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4777 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4779 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4780 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4782 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4783 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4784 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4785 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4786 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4787 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4788 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4792 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4793 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4795 static struct snd_kcontrol_new alc260_will_mixer[] = {
4796 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4797 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4799 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4800 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4801 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4802 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4803 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4804 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4805 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4806 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4807 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4811 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4812 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4814 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4815 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4816 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4818 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4819 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4820 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4821 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4822 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4823 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4824 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4829 * initialization verbs
4831 static struct hda_verb alc260_init_verbs[] = {
4832 /* Line In pin widget for input */
4833 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4834 /* CD pin widget for input */
4835 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4836 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4838 /* Mic2 (front panel) pin widget for input and vref at 80% */
4839 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4840 /* LINE-2 is used for line-out in rear */
4841 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4842 /* select line-out */
4843 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4845 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4847 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4849 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4850 /* mute capture amp left and right */
4851 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4852 /* set connection select to line in (default select for this ADC) */
4853 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4854 /* mute capture amp left and right */
4855 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4856 /* set connection select to line in (default select for this ADC) */
4857 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4858 /* set vol=0 Line-Out mixer amp left and right */
4859 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4860 /* unmute pin widget amp left and right (no gain on this amp) */
4861 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4862 /* set vol=0 HP mixer amp left and right */
4863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4864 /* unmute pin widget amp left and right (no gain on this amp) */
4865 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4866 /* set vol=0 Mono mixer amp left and right */
4867 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4868 /* unmute pin widget amp left and right (no gain on this amp) */
4869 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4870 /* unmute LINE-2 out pin */
4871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4872 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4875 /* mute analog inputs */
4876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4878 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4879 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4880 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4881 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4882 /* mute Front out path */
4883 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4884 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4885 /* mute Headphone out path */
4886 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4887 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4888 /* mute Mono out path */
4889 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4890 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4894 #if 0 /* should be identical with alc260_init_verbs? */
4895 static struct hda_verb alc260_hp_init_verbs[] = {
4896 /* Headphone and output */
4897 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4899 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4900 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4901 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4902 /* Mic2 (front panel) pin widget for input and vref at 80% */
4903 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4904 /* Line In pin widget for input */
4905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4906 /* Line-2 pin widget for output */
4907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4908 /* CD pin widget for input */
4909 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4910 /* unmute amp left and right */
4911 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4912 /* set connection select to line in (default select for this ADC) */
4913 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4914 /* unmute Line-Out mixer amp left and right (volume = 0) */
4915 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4916 /* mute pin widget amp left and right (no gain on this amp) */
4917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4918 /* unmute HP mixer amp left and right (volume = 0) */
4919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4920 /* mute pin widget amp left and right (no gain on this amp) */
4921 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4922 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4925 /* mute analog inputs */
4926 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4927 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4928 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4929 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4930 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4931 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4932 /* Unmute Front out path */
4933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4934 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4935 /* Unmute Headphone out path */
4936 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4937 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4938 /* Unmute Mono out path */
4939 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4940 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4945 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4946 /* Line out and output */
4947 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4949 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4950 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4951 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4952 /* Mic2 (front panel) pin widget for input and vref at 80% */
4953 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4954 /* Line In pin widget for input */
4955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4956 /* Headphone pin widget for output */
4957 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4958 /* CD pin widget for input */
4959 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4960 /* unmute amp left and right */
4961 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4962 /* set connection select to line in (default select for this ADC) */
4963 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4964 /* unmute Line-Out mixer amp left and right (volume = 0) */
4965 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4966 /* mute pin widget amp left and right (no gain on this amp) */
4967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4968 /* unmute HP mixer amp left and right (volume = 0) */
4969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4970 /* mute pin widget amp left and right (no gain on this amp) */
4971 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4972 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4975 /* mute analog inputs */
4976 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4977 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4978 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4979 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4980 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4981 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4982 /* Unmute Front out path */
4983 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4984 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4985 /* Unmute Headphone out path */
4986 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4987 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4988 /* Unmute Mono out path */
4989 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4990 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4994 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4995 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4996 * audio = 0x16, internal speaker = 0x10.
4998 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4999 /* Disable all GPIOs */
5000 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5001 /* Internal speaker is connected to headphone pin */
5002 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5003 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5004 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5005 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5006 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5007 /* Ensure all other unused pins are disabled and muted. */
5008 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5009 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5010 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5011 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5012 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5013 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5014 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5017 /* Disable digital (SPDIF) pins */
5018 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5019 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5021 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5022 * when acting as an output.
5024 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5026 /* Start with output sum widgets muted and their output gains at min */
5027 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5029 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5030 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5031 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5033 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5034 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5035 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5037 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5038 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5039 /* Unmute Line1 pin widget output buffer since it starts as an output.
5040 * If the pin mode is changed by the user the pin mode control will
5041 * take care of enabling the pin's input/output buffers as needed.
5042 * Therefore there's no need to enable the input buffer at this
5045 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5046 /* Unmute input buffer of pin widget used for Line-in (no equiv
5049 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5051 /* Mute capture amp left and right */
5052 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5053 /* Set ADC connection select to match default mixer setting - line
5056 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5058 /* Do the same for the second ADC: mute capture input amp and
5059 * set ADC connection to line in (on mic1 pin)
5061 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5062 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5064 /* Mute all inputs to mixer widget (even unconnected ones) */
5065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5072 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5077 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5078 * similar laptops (adapted from Fujitsu init verbs).
5080 static struct hda_verb alc260_acer_init_verbs[] = {
5081 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5082 * the headphone jack. Turn this on and rely on the standard mute
5083 * methods whenever the user wants to turn these outputs off.
5085 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5086 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5087 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5088 /* Internal speaker/Headphone jack is connected to Line-out pin */
5089 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5090 /* Internal microphone/Mic jack is connected to Mic1 pin */
5091 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5092 /* Line In jack is connected to Line1 pin */
5093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5094 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5095 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5096 /* Ensure all other unused pins are disabled and muted. */
5097 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5098 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5099 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5100 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5101 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103 /* Disable digital (SPDIF) pins */
5104 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5105 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5107 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5108 * bus when acting as outputs.
5110 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5111 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5113 /* Start with output sum widgets muted and their output gains at min */
5114 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5116 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5117 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5118 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5119 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5120 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5121 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5122 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5124 /* Unmute Line-out pin widget amp left and right
5125 * (no equiv mixer ctrl)
5127 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5128 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5129 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5130 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5131 * inputs. If the pin mode is changed by the user the pin mode control
5132 * will take care of enabling the pin's input/output buffers as needed.
5133 * Therefore there's no need to enable the input buffer at this
5136 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5137 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5139 /* Mute capture amp left and right */
5140 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141 /* Set ADC connection select to match default mixer setting - mic
5144 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5146 /* Do similar with the second ADC: mute capture input amp and
5147 * set ADC connection to mic to match ALSA's default state.
5149 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5150 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5152 /* Mute all inputs to mixer widget (even unconnected ones) */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5158 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5159 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5165 static struct hda_verb alc260_will_verbs[] = {
5166 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5167 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5168 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5169 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5170 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5171 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5175 static struct hda_verb alc260_replacer_672v_verbs[] = {
5176 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5177 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5178 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5180 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5181 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5182 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5184 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5188 /* toggle speaker-output according to the hp-jack state */
5189 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5191 unsigned int present;
5193 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5194 present = snd_hda_codec_read(codec, 0x0f, 0,
5195 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5197 snd_hda_codec_write_cache(codec, 0x01, 0,
5198 AC_VERB_SET_GPIO_DATA, 1);
5199 snd_hda_codec_write_cache(codec, 0x0f, 0,
5200 AC_VERB_SET_PIN_WIDGET_CONTROL,
5203 snd_hda_codec_write_cache(codec, 0x01, 0,
5204 AC_VERB_SET_GPIO_DATA, 0);
5205 snd_hda_codec_write_cache(codec, 0x0f, 0,
5206 AC_VERB_SET_PIN_WIDGET_CONTROL,
5211 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5214 if ((res >> 26) == ALC880_HP_EVENT)
5215 alc260_replacer_672v_automute(codec);
5218 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5219 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5221 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5222 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5223 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5225 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5226 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5227 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5228 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5232 /* Test configuration for debugging, modelled after the ALC880 test
5235 #ifdef CONFIG_SND_DEBUG
5236 static hda_nid_t alc260_test_dac_nids[1] = {
5239 static hda_nid_t alc260_test_adc_nids[2] = {
5242 /* For testing the ALC260, each input MUX needs its own definition since
5243 * the signal assignments are different. This assumes that the first ADC
5246 static struct hda_input_mux alc260_test_capture_sources[2] = {
5250 { "MIC1 pin", 0x0 },
5251 { "MIC2 pin", 0x1 },
5252 { "LINE1 pin", 0x2 },
5253 { "LINE2 pin", 0x3 },
5255 { "LINE-OUT pin", 0x5 },
5256 { "HP-OUT pin", 0x6 },
5262 { "MIC1 pin", 0x0 },
5263 { "MIC2 pin", 0x1 },
5264 { "LINE1 pin", 0x2 },
5265 { "LINE2 pin", 0x3 },
5268 { "LINE-OUT pin", 0x6 },
5269 { "HP-OUT pin", 0x7 },
5273 static struct snd_kcontrol_new alc260_test_mixer[] = {
5274 /* Output driver widgets */
5275 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5276 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5277 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5278 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5279 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5280 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5282 /* Modes for retasking pin widgets
5283 * Note: the ALC260 doesn't seem to act on requests to enable mic
5284 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5285 * mention this restriction. At this stage it's not clear whether
5286 * this behaviour is intentional or is a hardware bug in chip
5287 * revisions available at least up until early 2006. Therefore for
5288 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5289 * choices, but if it turns out that the lack of mic bias for these
5290 * NIDs is intentional we could change their modes from
5291 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5293 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5294 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5295 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5296 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5297 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5298 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5300 /* Loopback mixer controls */
5301 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5302 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5303 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5304 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5305 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5306 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5307 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5308 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5309 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5310 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5311 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5312 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5313 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5314 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5315 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5316 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5318 /* Controls for GPIO pins, assuming they are configured as outputs */
5319 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5320 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5321 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5322 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5324 /* Switches to allow the digital IO pins to be enabled. The datasheet
5325 * is ambigious as to which NID is which; testing on laptops which
5326 * make this output available should provide clarification.
5328 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5329 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5331 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5332 * this output to turn on an external amplifier.
5334 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5335 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5339 static struct hda_verb alc260_test_init_verbs[] = {
5340 /* Enable all GPIOs as outputs with an initial value of 0 */
5341 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5342 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5343 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5345 /* Enable retasking pins as output, initially without power amp */
5346 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5347 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5350 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5351 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5353 /* Disable digital (SPDIF) pins initially, but users can enable
5354 * them via a mixer switch. In the case of SPDIF-out, this initverb
5355 * payload also sets the generation to 0, output to be in "consumer"
5356 * PCM format, copyright asserted, no pre-emphasis and no validity
5359 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5360 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5362 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5363 * OUT1 sum bus when acting as an output.
5365 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5366 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5367 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5368 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5370 /* Start with output sum widgets muted and their output gains at min */
5371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5374 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5377 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5378 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5379 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5381 /* Unmute retasking pin widget output buffers since the default
5382 * state appears to be output. As the pin mode is changed by the
5383 * user the pin mode control will take care of enabling the pin's
5384 * input/output buffers as needed.
5386 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5387 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5390 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5391 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5392 /* Also unmute the mono-out pin widget */
5393 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5395 /* Mute capture amp left and right */
5396 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5397 /* Set ADC connection select to match default mixer setting (mic1
5400 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5402 /* Do the same for the second ADC: mute capture input amp and
5403 * set ADC connection to mic1 pin
5405 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5406 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5408 /* Mute all inputs to mixer widget (even unconnected ones) */
5409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5422 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5423 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5425 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5426 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5429 * for BIOS auto-configuration
5432 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5433 const char *pfx, int *vol_bits)
5436 unsigned long vol_val, sw_val;
5440 if (nid >= 0x0f && nid < 0x11) {
5441 nid_vol = nid - 0x7;
5442 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5443 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5444 } else if (nid == 0x11) {
5445 nid_vol = nid - 0x7;
5446 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5447 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5448 } else if (nid >= 0x12 && nid <= 0x15) {
5450 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5451 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5455 if (!(*vol_bits & (1 << nid_vol))) {
5456 /* first control for the volume widget */
5457 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5458 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5461 *vol_bits |= (1 << nid_vol);
5463 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5464 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5470 /* add playback controls from the parsed DAC table */
5471 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5472 const struct auto_pin_cfg *cfg)
5478 spec->multiout.num_dacs = 1;
5479 spec->multiout.dac_nids = spec->private_dac_nids;
5480 spec->multiout.dac_nids[0] = 0x02;
5482 nid = cfg->line_out_pins[0];
5484 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5489 nid = cfg->speaker_pins[0];
5491 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5496 nid = cfg->hp_pins[0];
5498 err = alc260_add_playback_controls(spec, nid, "Headphone",
5506 /* create playback/capture controls for input pins */
5507 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5508 const struct auto_pin_cfg *cfg)
5510 struct hda_input_mux *imux = &spec->private_imux[0];
5513 for (i = 0; i < AUTO_PIN_LAST; i++) {
5514 if (cfg->input_pins[i] >= 0x12) {
5515 idx = cfg->input_pins[i] - 0x12;
5516 err = new_analog_input(spec, cfg->input_pins[i],
5517 auto_pin_cfg_labels[i], idx,
5521 imux->items[imux->num_items].label =
5522 auto_pin_cfg_labels[i];
5523 imux->items[imux->num_items].index = idx;
5526 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5527 idx = cfg->input_pins[i] - 0x09;
5528 err = new_analog_input(spec, cfg->input_pins[i],
5529 auto_pin_cfg_labels[i], idx,
5533 imux->items[imux->num_items].label =
5534 auto_pin_cfg_labels[i];
5535 imux->items[imux->num_items].index = idx;
5542 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5543 hda_nid_t nid, int pin_type,
5546 alc_set_pin_output(codec, nid, pin_type);
5547 /* need the manual connection? */
5549 int idx = nid - 0x12;
5550 snd_hda_codec_write(codec, idx + 0x0b, 0,
5551 AC_VERB_SET_CONNECT_SEL, sel_idx);
5555 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5557 struct alc_spec *spec = codec->spec;
5560 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5561 nid = spec->autocfg.line_out_pins[0];
5563 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5564 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5567 nid = spec->autocfg.speaker_pins[0];
5569 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5571 nid = spec->autocfg.hp_pins[0];
5573 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5576 #define ALC260_PIN_CD_NID 0x16
5577 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5579 struct alc_spec *spec = codec->spec;
5582 for (i = 0; i < AUTO_PIN_LAST; i++) {
5583 hda_nid_t nid = spec->autocfg.input_pins[i];
5585 snd_hda_codec_write(codec, nid, 0,
5586 AC_VERB_SET_PIN_WIDGET_CONTROL,
5587 i <= AUTO_PIN_FRONT_MIC ?
5588 PIN_VREF80 : PIN_IN);
5589 if (nid != ALC260_PIN_CD_NID)
5590 snd_hda_codec_write(codec, nid, 0,
5591 AC_VERB_SET_AMP_GAIN_MUTE,
5598 * generic initialization of ADC, input mixers and output mixers
5600 static struct hda_verb alc260_volume_init_verbs[] = {
5602 * Unmute ADC0-1 and set the default input to mic-in
5604 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5605 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5606 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5607 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5609 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5611 * Note: PASD motherboards uses the Line In 2 as the input for
5612 * front panel mic (mic 2)
5614 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5615 /* mute analog inputs */
5616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5623 * Set up output mixers (0x08 - 0x0a)
5625 /* set vol=0 to output mixers */
5626 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5628 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5629 /* set up input amps for analog loopback */
5630 /* Amp Indices: DAC = 0, mixer = 1 */
5631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5632 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5634 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5635 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5636 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5641 static int alc260_parse_auto_config(struct hda_codec *codec)
5643 struct alc_spec *spec = codec->spec;
5645 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5647 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5651 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5654 if (!spec->kctls.list)
5655 return 0; /* can't find valid BIOS pin config */
5656 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5660 spec->multiout.max_channels = 2;
5662 if (spec->autocfg.dig_out_pin)
5663 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5664 if (spec->kctls.list)
5665 add_mixer(spec, spec->kctls.list);
5667 add_verb(spec, alc260_volume_init_verbs);
5669 spec->num_mux_defs = 1;
5670 spec->input_mux = &spec->private_imux[0];
5672 store_pin_configs(codec);
5676 /* additional initialization for auto-configuration model */
5677 static void alc260_auto_init(struct hda_codec *codec)
5679 struct alc_spec *spec = codec->spec;
5680 alc260_auto_init_multi_out(codec);
5681 alc260_auto_init_analog_input(codec);
5682 if (spec->unsol_event)
5683 alc_inithook(codec);
5686 #ifdef CONFIG_SND_HDA_POWER_SAVE
5687 static struct hda_amp_list alc260_loopbacks[] = {
5688 { 0x07, HDA_INPUT, 0 },
5689 { 0x07, HDA_INPUT, 1 },
5690 { 0x07, HDA_INPUT, 2 },
5691 { 0x07, HDA_INPUT, 3 },
5692 { 0x07, HDA_INPUT, 4 },
5698 * ALC260 configurations
5700 static const char *alc260_models[ALC260_MODEL_LAST] = {
5701 [ALC260_BASIC] = "basic",
5703 [ALC260_HP_3013] = "hp-3013",
5704 [ALC260_HP_DC7600] = "hp-dc7600",
5705 [ALC260_FUJITSU_S702X] = "fujitsu",
5706 [ALC260_ACER] = "acer",
5707 [ALC260_WILL] = "will",
5708 [ALC260_REPLACER_672V] = "replacer",
5709 #ifdef CONFIG_SND_DEBUG
5710 [ALC260_TEST] = "test",
5712 [ALC260_AUTO] = "auto",
5715 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5716 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5717 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5718 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5719 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5720 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5721 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5722 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5723 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5724 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5725 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5726 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5727 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5728 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5729 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5730 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5731 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5732 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5733 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5737 static struct alc_config_preset alc260_presets[] = {
5739 .mixers = { alc260_base_output_mixer,
5741 alc260_pc_beep_mixer },
5742 .init_verbs = { alc260_init_verbs },
5743 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5744 .dac_nids = alc260_dac_nids,
5745 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5746 .adc_nids = alc260_adc_nids,
5747 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5748 .channel_mode = alc260_modes,
5749 .input_mux = &alc260_capture_source,
5752 .mixers = { alc260_hp_output_mixer,
5753 alc260_input_mixer },
5754 .init_verbs = { alc260_init_verbs,
5755 alc260_hp_unsol_verbs },
5756 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5757 .dac_nids = alc260_dac_nids,
5758 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5759 .adc_nids = alc260_adc_nids_alt,
5760 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5761 .channel_mode = alc260_modes,
5762 .input_mux = &alc260_capture_source,
5763 .unsol_event = alc260_hp_unsol_event,
5764 .init_hook = alc260_hp_automute,
5766 [ALC260_HP_DC7600] = {
5767 .mixers = { alc260_hp_dc7600_mixer,
5768 alc260_input_mixer },
5769 .init_verbs = { alc260_init_verbs,
5770 alc260_hp_dc7600_verbs },
5771 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5772 .dac_nids = alc260_dac_nids,
5773 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5774 .adc_nids = alc260_adc_nids_alt,
5775 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5776 .channel_mode = alc260_modes,
5777 .input_mux = &alc260_capture_source,
5778 .unsol_event = alc260_hp_3012_unsol_event,
5779 .init_hook = alc260_hp_3012_automute,
5781 [ALC260_HP_3013] = {
5782 .mixers = { alc260_hp_3013_mixer,
5783 alc260_input_mixer },
5784 .init_verbs = { alc260_hp_3013_init_verbs,
5785 alc260_hp_3013_unsol_verbs },
5786 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5787 .dac_nids = alc260_dac_nids,
5788 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5789 .adc_nids = alc260_adc_nids_alt,
5790 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5791 .channel_mode = alc260_modes,
5792 .input_mux = &alc260_capture_source,
5793 .unsol_event = alc260_hp_3013_unsol_event,
5794 .init_hook = alc260_hp_3013_automute,
5796 [ALC260_FUJITSU_S702X] = {
5797 .mixers = { alc260_fujitsu_mixer },
5798 .init_verbs = { alc260_fujitsu_init_verbs },
5799 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5800 .dac_nids = alc260_dac_nids,
5801 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5802 .adc_nids = alc260_dual_adc_nids,
5803 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5804 .channel_mode = alc260_modes,
5805 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5806 .input_mux = alc260_fujitsu_capture_sources,
5809 .mixers = { alc260_acer_mixer },
5810 .init_verbs = { alc260_acer_init_verbs },
5811 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5812 .dac_nids = alc260_dac_nids,
5813 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5814 .adc_nids = alc260_dual_adc_nids,
5815 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5816 .channel_mode = alc260_modes,
5817 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5818 .input_mux = alc260_acer_capture_sources,
5821 .mixers = { alc260_will_mixer },
5822 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5823 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5824 .dac_nids = alc260_dac_nids,
5825 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5826 .adc_nids = alc260_adc_nids,
5827 .dig_out_nid = ALC260_DIGOUT_NID,
5828 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5829 .channel_mode = alc260_modes,
5830 .input_mux = &alc260_capture_source,
5832 [ALC260_REPLACER_672V] = {
5833 .mixers = { alc260_replacer_672v_mixer },
5834 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5835 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5836 .dac_nids = alc260_dac_nids,
5837 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5838 .adc_nids = alc260_adc_nids,
5839 .dig_out_nid = ALC260_DIGOUT_NID,
5840 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5841 .channel_mode = alc260_modes,
5842 .input_mux = &alc260_capture_source,
5843 .unsol_event = alc260_replacer_672v_unsol_event,
5844 .init_hook = alc260_replacer_672v_automute,
5846 #ifdef CONFIG_SND_DEBUG
5848 .mixers = { alc260_test_mixer },
5849 .init_verbs = { alc260_test_init_verbs },
5850 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5851 .dac_nids = alc260_test_dac_nids,
5852 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5853 .adc_nids = alc260_test_adc_nids,
5854 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5855 .channel_mode = alc260_modes,
5856 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5857 .input_mux = alc260_test_capture_sources,
5862 static int patch_alc260(struct hda_codec *codec)
5864 struct alc_spec *spec;
5865 int err, board_config;
5867 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5873 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5876 if (board_config < 0) {
5877 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5878 "trying auto-probe from BIOS...\n");
5879 board_config = ALC260_AUTO;
5882 if (board_config == ALC260_AUTO) {
5883 /* automatic parse from the BIOS config */
5884 err = alc260_parse_auto_config(codec);
5890 "hda_codec: Cannot set up configuration "
5891 "from BIOS. Using base mode...\n");
5892 board_config = ALC260_BASIC;
5896 err = snd_hda_attach_beep_device(codec, 0x1);
5902 if (board_config != ALC260_AUTO)
5903 setup_preset(spec, &alc260_presets[board_config]);
5905 spec->stream_name_analog = "ALC260 Analog";
5906 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5907 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5909 spec->stream_name_digital = "ALC260 Digital";
5910 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5911 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5913 if (!spec->adc_nids && spec->input_mux) {
5914 /* check whether NID 0x04 is valid */
5915 unsigned int wcap = get_wcaps(codec, 0x04);
5916 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5918 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5919 spec->adc_nids = alc260_adc_nids_alt;
5920 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5922 spec->adc_nids = alc260_adc_nids;
5923 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5926 set_capture_mixer(spec);
5928 spec->vmaster_nid = 0x08;
5930 codec->patch_ops = alc_patch_ops;
5931 if (board_config == ALC260_AUTO)
5932 spec->init_hook = alc260_auto_init;
5933 #ifdef CONFIG_SND_HDA_POWER_SAVE
5934 if (!spec->loopback.amplist)
5935 spec->loopback.amplist = alc260_loopbacks;
5937 codec->proc_widget_hook = print_realtek_coef;
5946 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5947 * configuration. Each pin widget can choose any input DACs and a mixer.
5948 * Each ADC is connected from a mixer of all inputs. This makes possible
5949 * 6-channel independent captures.
5951 * In addition, an independent DAC for the multi-playback (not used in this
5954 #define ALC882_DIGOUT_NID 0x06
5955 #define ALC882_DIGIN_NID 0x0a
5957 static struct hda_channel_mode alc882_ch_modes[1] = {
5961 static hda_nid_t alc882_dac_nids[4] = {
5962 /* front, rear, clfe, rear_surr */
5963 0x02, 0x03, 0x04, 0x05
5966 /* identical with ALC880 */
5967 #define alc882_adc_nids alc880_adc_nids
5968 #define alc882_adc_nids_alt alc880_adc_nids_alt
5970 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5971 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5974 /* FIXME: should be a matrix-type input source selection */
5976 static struct hda_input_mux alc882_capture_source = {
5980 { "Front Mic", 0x1 },
5988 static struct hda_verb alc882_3ST_ch2_init[] = {
5989 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5990 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5991 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5992 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5999 static struct hda_verb alc882_3ST_ch6_init[] = {
6000 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6001 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6002 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6003 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6004 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6005 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6009 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6010 { 2, alc882_3ST_ch2_init },
6011 { 6, alc882_3ST_ch6_init },
6017 static struct hda_verb alc882_sixstack_ch6_init[] = {
6018 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6019 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6020 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6021 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6028 static struct hda_verb alc882_sixstack_ch8_init[] = {
6029 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6030 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6031 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6032 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6036 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6037 { 6, alc882_sixstack_ch6_init },
6038 { 8, alc882_sixstack_ch8_init },
6042 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6048 static struct hda_verb alc885_mbp_ch2_init[] = {
6049 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6050 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6051 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6058 static struct hda_verb alc885_mbp_ch6_init[] = {
6059 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6060 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6061 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6062 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6063 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6067 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6068 { 2, alc885_mbp_ch2_init },
6069 { 6, alc885_mbp_ch6_init },
6073 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6074 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6076 static struct snd_kcontrol_new alc882_base_mixer[] = {
6077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6078 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6079 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6080 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6081 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6082 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6083 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6084 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6085 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6086 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6087 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6088 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6089 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6090 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6091 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6093 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6095 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6096 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6097 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6098 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6099 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6103 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6104 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6105 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6106 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6107 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6108 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6109 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6111 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6112 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6113 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6116 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6117 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6118 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6119 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6120 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6121 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6122 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6124 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6126 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6127 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6131 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6133 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6135 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6136 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6137 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6138 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6141 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6142 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6144 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6148 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6149 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6151 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6152 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6153 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6155 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6156 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6157 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6158 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6159 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6160 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6161 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6164 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6168 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6169 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6170 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6172 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6173 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6175 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6177 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6179 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6180 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6184 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6186 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6187 .name = "Channel Mode",
6188 .info = alc_ch_mode_info,
6189 .get = alc_ch_mode_get,
6190 .put = alc_ch_mode_put,
6195 static struct hda_verb alc882_init_verbs[] = {
6196 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6197 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6202 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6203 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6205 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6206 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6207 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6209 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6211 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6213 /* Front Pin: output 0 (0x0c) */
6214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6216 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6217 /* Rear Pin: output 1 (0x0d) */
6218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6219 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6221 /* CLFE Pin: output 2 (0x0e) */
6222 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6223 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6224 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6225 /* Side Pin: output 3 (0x0f) */
6226 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6227 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6228 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6229 /* Mic (rear) pin: input vref at 80% */
6230 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6232 /* Front Mic pin: input vref at 80% */
6233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6235 /* Line In pin: input */
6236 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6238 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6239 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6241 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6242 /* CD pin widget for input */
6243 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6245 /* FIXME: use matrix-type input source selection */
6246 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6247 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6251 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6253 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6256 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6262 /* ADC1: mute amp left and right */
6263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6264 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6265 /* ADC2: mute amp left and right */
6266 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6267 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6268 /* ADC3: mute amp left and right */
6269 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6270 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6275 static struct hda_verb alc882_eapd_verbs[] = {
6276 /* change to EAPD mode */
6277 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6278 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6283 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6284 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6285 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6287 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6288 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6289 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6290 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6294 static struct hda_verb alc882_macpro_init_verbs[] = {
6295 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6299 /* Front Pin: output 0 (0x0c) */
6300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6302 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6303 /* Front Mic pin: input vref at 80% */
6304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6305 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6306 /* Speaker: output */
6307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6309 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6310 /* Headphone output (output 0 - 0x0c) */
6311 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6313 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6315 /* FIXME: use matrix-type input source selection */
6316 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6317 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6323 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6328 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6332 /* ADC1: mute amp left and right */
6333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6334 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6335 /* ADC2: mute amp left and right */
6336 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6337 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6338 /* ADC3: mute amp left and right */
6339 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6340 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6345 /* Macbook Pro rev3 */
6346 static struct hda_verb alc885_mbp3_init_verbs[] = {
6347 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6348 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6349 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6355 /* Front Pin: output 0 (0x0c) */
6356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6359 /* HP Pin: output 0 (0x0d) */
6360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6363 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6364 /* Mic (rear) pin: input vref at 80% */
6365 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6366 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6367 /* Front Mic pin: input vref at 80% */
6368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6370 /* Line In pin: use output 1 when in LineOut mode */
6371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6373 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6375 /* FIXME: use matrix-type input source selection */
6376 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6377 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6380 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6381 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6385 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6390 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6391 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6392 /* ADC1: mute amp left and right */
6393 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6394 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6395 /* ADC2: mute amp left and right */
6396 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6397 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6398 /* ADC3: mute amp left and right */
6399 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6400 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6405 /* iMac 24 mixer. */
6406 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6407 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6408 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6412 /* iMac 24 init verbs. */
6413 static struct hda_verb alc885_imac24_init_verbs[] = {
6414 /* Internal speakers: output 0 (0x0c) */
6415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6417 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6418 /* Internal speakers: output 0 (0x0c) */
6419 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6420 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6421 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6422 /* Headphone: output 0 (0x0c) */
6423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6424 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6425 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6426 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6427 /* Front Mic: 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},
6433 /* Toggle speaker-output according to the hp-jack state */
6434 static void alc885_imac24_automute(struct hda_codec *codec)
6436 unsigned int present;
6438 present = snd_hda_codec_read(codec, 0x14, 0,
6439 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6440 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6441 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6442 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6443 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6446 /* Processes unsolicited events. */
6447 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6450 /* Headphone insertion or removal. */
6451 if ((res >> 26) == ALC880_HP_EVENT)
6452 alc885_imac24_automute(codec);
6455 static void alc885_mbp3_automute(struct hda_codec *codec)
6457 unsigned int present;
6459 present = snd_hda_codec_read(codec, 0x15, 0,
6460 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6461 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6462 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6463 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6464 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6467 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6470 /* Headphone insertion or removal. */
6471 if ((res >> 26) == ALC880_HP_EVENT)
6472 alc885_mbp3_automute(codec);
6476 static struct hda_verb alc882_targa_verbs[] = {
6477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6481 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6483 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6484 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6485 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6487 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6488 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6489 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6490 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6494 /* toggle speaker-output according to the hp-jack state */
6495 static void alc882_targa_automute(struct hda_codec *codec)
6497 unsigned int present;
6499 present = snd_hda_codec_read(codec, 0x14, 0,
6500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6501 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6502 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6503 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6507 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6509 /* Looks like the unsol event is incompatible with the standard
6510 * definition. 4bit tag is placed at 26 bit!
6512 if (((res >> 26) == ALC880_HP_EVENT)) {
6513 alc882_targa_automute(codec);
6517 static struct hda_verb alc882_asus_a7j_verbs[] = {
6518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6525 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6526 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6527 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6529 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6530 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6531 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6535 static struct hda_verb alc882_asus_a7m_verbs[] = {
6536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6540 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6541 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6543 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6545 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6547 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6548 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6549 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6553 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6555 unsigned int gpiostate, gpiomask, gpiodir;
6557 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6558 AC_VERB_GET_GPIO_DATA, 0);
6561 gpiostate |= (1 << pin);
6563 gpiostate &= ~(1 << pin);
6565 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6566 AC_VERB_GET_GPIO_MASK, 0);
6567 gpiomask |= (1 << pin);
6569 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6570 AC_VERB_GET_GPIO_DIRECTION, 0);
6571 gpiodir |= (1 << pin);
6574 snd_hda_codec_write(codec, codec->afg, 0,
6575 AC_VERB_SET_GPIO_MASK, gpiomask);
6576 snd_hda_codec_write(codec, codec->afg, 0,
6577 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6581 snd_hda_codec_write(codec, codec->afg, 0,
6582 AC_VERB_SET_GPIO_DATA, gpiostate);
6585 /* set up GPIO at initialization */
6586 static void alc885_macpro_init_hook(struct hda_codec *codec)
6588 alc882_gpio_mute(codec, 0, 0);
6589 alc882_gpio_mute(codec, 1, 0);
6592 /* set up GPIO and update auto-muting at initialization */
6593 static void alc885_imac24_init_hook(struct hda_codec *codec)
6595 alc885_macpro_init_hook(codec);
6596 alc885_imac24_automute(codec);
6600 * generic initialization of ADC, input mixers and output mixers
6602 static struct hda_verb alc882_auto_init_verbs[] = {
6604 * Unmute ADC0-2 and set the default input to mic-in
6606 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6607 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6608 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6609 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6610 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6611 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6613 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6615 * Note: PASD motherboards uses the Line In 2 as the input for
6616 * front panel mic (mic 2)
6618 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6619 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6620 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6621 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6622 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6623 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6626 * Set up output mixers (0x0c - 0x0f)
6628 /* set vol=0 to output mixers */
6629 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6631 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6632 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6633 /* set up input amps for analog loopback */
6634 /* Amp Indices: DAC = 0, mixer = 1 */
6635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6637 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6638 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6639 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6640 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6641 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6643 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6644 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6646 /* FIXME: use matrix-type input source selection */
6647 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6648 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6651 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6667 #ifdef CONFIG_SND_HDA_POWER_SAVE
6668 #define alc882_loopbacks alc880_loopbacks
6671 /* pcm configuration: identiacal with ALC880 */
6672 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6673 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6674 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6675 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6678 * configuration and preset
6680 static const char *alc882_models[ALC882_MODEL_LAST] = {
6681 [ALC882_3ST_DIG] = "3stack-dig",
6682 [ALC882_6ST_DIG] = "6stack-dig",
6683 [ALC882_ARIMA] = "arima",
6684 [ALC882_W2JC] = "w2jc",
6685 [ALC882_TARGA] = "targa",
6686 [ALC882_ASUS_A7J] = "asus-a7j",
6687 [ALC882_ASUS_A7M] = "asus-a7m",
6688 [ALC885_MACPRO] = "macpro",
6689 [ALC885_MBP3] = "mbp3",
6690 [ALC885_IMAC24] = "imac24",
6691 [ALC882_AUTO] = "auto",
6694 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6695 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6696 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6697 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6698 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6699 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6700 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6701 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6702 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6703 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6704 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6705 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6706 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6710 static struct alc_config_preset alc882_presets[] = {
6711 [ALC882_3ST_DIG] = {
6712 .mixers = { alc882_base_mixer },
6713 .init_verbs = { alc882_init_verbs },
6714 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6715 .dac_nids = alc882_dac_nids,
6716 .dig_out_nid = ALC882_DIGOUT_NID,
6717 .dig_in_nid = ALC882_DIGIN_NID,
6718 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6719 .channel_mode = alc882_ch_modes,
6721 .input_mux = &alc882_capture_source,
6723 [ALC882_6ST_DIG] = {
6724 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6725 .init_verbs = { alc882_init_verbs },
6726 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6727 .dac_nids = alc882_dac_nids,
6728 .dig_out_nid = ALC882_DIGOUT_NID,
6729 .dig_in_nid = ALC882_DIGIN_NID,
6730 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6731 .channel_mode = alc882_sixstack_modes,
6732 .input_mux = &alc882_capture_source,
6735 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6736 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6737 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6738 .dac_nids = alc882_dac_nids,
6739 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6740 .channel_mode = alc882_sixstack_modes,
6741 .input_mux = &alc882_capture_source,
6744 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6745 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6746 alc880_gpio1_init_verbs },
6747 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6748 .dac_nids = alc882_dac_nids,
6749 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6750 .channel_mode = alc880_threestack_modes,
6752 .input_mux = &alc882_capture_source,
6753 .dig_out_nid = ALC882_DIGOUT_NID,
6756 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6757 .init_verbs = { alc885_mbp3_init_verbs,
6758 alc880_gpio1_init_verbs },
6759 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6760 .dac_nids = alc882_dac_nids,
6761 .channel_mode = alc885_mbp_6ch_modes,
6762 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6763 .input_mux = &alc882_capture_source,
6764 .dig_out_nid = ALC882_DIGOUT_NID,
6765 .dig_in_nid = ALC882_DIGIN_NID,
6766 .unsol_event = alc885_mbp3_unsol_event,
6767 .init_hook = alc885_mbp3_automute,
6770 .mixers = { alc882_macpro_mixer },
6771 .init_verbs = { alc882_macpro_init_verbs },
6772 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6773 .dac_nids = alc882_dac_nids,
6774 .dig_out_nid = ALC882_DIGOUT_NID,
6775 .dig_in_nid = ALC882_DIGIN_NID,
6776 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6777 .channel_mode = alc882_ch_modes,
6778 .input_mux = &alc882_capture_source,
6779 .init_hook = alc885_macpro_init_hook,
6782 .mixers = { alc885_imac24_mixer },
6783 .init_verbs = { alc885_imac24_init_verbs },
6784 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6785 .dac_nids = alc882_dac_nids,
6786 .dig_out_nid = ALC882_DIGOUT_NID,
6787 .dig_in_nid = ALC882_DIGIN_NID,
6788 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6789 .channel_mode = alc882_ch_modes,
6790 .input_mux = &alc882_capture_source,
6791 .unsol_event = alc885_imac24_unsol_event,
6792 .init_hook = alc885_imac24_init_hook,
6795 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6796 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6797 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6798 .dac_nids = alc882_dac_nids,
6799 .dig_out_nid = ALC882_DIGOUT_NID,
6800 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6801 .adc_nids = alc882_adc_nids,
6802 .capsrc_nids = alc882_capsrc_nids,
6803 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6804 .channel_mode = alc882_3ST_6ch_modes,
6806 .input_mux = &alc882_capture_source,
6807 .unsol_event = alc882_targa_unsol_event,
6808 .init_hook = alc882_targa_automute,
6810 [ALC882_ASUS_A7J] = {
6811 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6812 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6813 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6814 .dac_nids = alc882_dac_nids,
6815 .dig_out_nid = ALC882_DIGOUT_NID,
6816 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6817 .adc_nids = alc882_adc_nids,
6818 .capsrc_nids = alc882_capsrc_nids,
6819 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6820 .channel_mode = alc882_3ST_6ch_modes,
6822 .input_mux = &alc882_capture_source,
6824 [ALC882_ASUS_A7M] = {
6825 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6826 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6827 alc880_gpio1_init_verbs,
6828 alc882_asus_a7m_verbs },
6829 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6830 .dac_nids = alc882_dac_nids,
6831 .dig_out_nid = ALC882_DIGOUT_NID,
6832 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6833 .channel_mode = alc880_threestack_modes,
6835 .input_mux = &alc882_capture_source,
6844 PINFIX_ABIT_AW9D_MAX
6847 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6848 { 0x15, 0x01080104 }, /* side */
6849 { 0x16, 0x01011012 }, /* rear */
6850 { 0x17, 0x01016011 }, /* clfe */
6854 static const struct alc_pincfg *alc882_pin_fixes[] = {
6855 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6858 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6859 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6864 * BIOS auto configuration
6866 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6867 hda_nid_t nid, int pin_type,
6871 struct alc_spec *spec = codec->spec;
6874 alc_set_pin_output(codec, nid, pin_type);
6875 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6878 idx = spec->multiout.dac_nids[dac_idx] - 2;
6879 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6883 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6885 struct alc_spec *spec = codec->spec;
6888 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6889 for (i = 0; i <= HDA_SIDE; i++) {
6890 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6891 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6893 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6898 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6900 struct alc_spec *spec = codec->spec;
6903 pin = spec->autocfg.hp_pins[0];
6904 if (pin) /* connect to front */
6906 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6907 pin = spec->autocfg.speaker_pins[0];
6909 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6912 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6913 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6915 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6917 struct alc_spec *spec = codec->spec;
6920 for (i = 0; i < AUTO_PIN_LAST; i++) {
6921 hda_nid_t nid = spec->autocfg.input_pins[i];
6926 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6927 unsigned int pincap;
6928 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6929 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6933 snd_hda_codec_write(codec, nid, 0,
6934 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6935 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6936 snd_hda_codec_write(codec, nid, 0,
6937 AC_VERB_SET_AMP_GAIN_MUTE,
6942 static void alc882_auto_init_input_src(struct hda_codec *codec)
6944 struct alc_spec *spec = codec->spec;
6947 for (c = 0; c < spec->num_adc_nids; c++) {
6948 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6949 hda_nid_t nid = spec->capsrc_nids[c];
6950 unsigned int mux_idx;
6951 const struct hda_input_mux *imux;
6952 int conns, mute, idx, item;
6954 conns = snd_hda_get_connections(codec, nid, conn_list,
6955 ARRAY_SIZE(conn_list));
6958 mux_idx = c >= spec->num_mux_defs ? 0 : c;
6959 imux = &spec->input_mux[mux_idx];
6960 for (idx = 0; idx < conns; idx++) {
6961 /* if the current connection is the selected one,
6962 * unmute it as default - otherwise mute it
6964 mute = AMP_IN_MUTE(idx);
6965 for (item = 0; item < imux->num_items; item++) {
6966 if (imux->items[item].index == idx) {
6967 if (spec->cur_mux[c] == item)
6968 mute = AMP_IN_UNMUTE(idx);
6972 /* check if we have a selector or mixer
6973 * we could check for the widget type instead, but
6974 * just check for Amp-In presence (in case of mixer
6975 * without amp-in there is something wrong, this
6976 * function shouldn't be used or capsrc nid is wrong)
6978 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
6979 snd_hda_codec_write(codec, nid, 0,
6980 AC_VERB_SET_AMP_GAIN_MUTE,
6982 else if (mute != AMP_IN_MUTE(idx))
6983 snd_hda_codec_write(codec, nid, 0,
6984 AC_VERB_SET_CONNECT_SEL,
6990 /* add mic boosts if needed */
6991 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6993 struct alc_spec *spec = codec->spec;
6997 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6998 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6999 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7001 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7005 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7006 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7007 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7009 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7016 /* almost identical with ALC880 parser... */
7017 static int alc882_parse_auto_config(struct hda_codec *codec)
7019 struct alc_spec *spec = codec->spec;
7020 int err = alc880_parse_auto_config(codec);
7025 return 0; /* no config found */
7027 err = alc_auto_add_mic_boost(codec);
7031 /* hack - override the init verbs */
7032 spec->init_verbs[0] = alc882_auto_init_verbs;
7034 return 1; /* config found */
7037 /* additional initialization for auto-configuration model */
7038 static void alc882_auto_init(struct hda_codec *codec)
7040 struct alc_spec *spec = codec->spec;
7041 alc882_auto_init_multi_out(codec);
7042 alc882_auto_init_hp_out(codec);
7043 alc882_auto_init_analog_input(codec);
7044 alc882_auto_init_input_src(codec);
7045 if (spec->unsol_event)
7046 alc_inithook(codec);
7049 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7051 static int patch_alc882(struct hda_codec *codec)
7053 struct alc_spec *spec;
7054 int err, board_config;
7056 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7062 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7066 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7067 /* Pick up systems that don't supply PCI SSID */
7068 switch (codec->subsystem_id) {
7069 case 0x106b0c00: /* Mac Pro */
7070 board_config = ALC885_MACPRO;
7072 case 0x106b1000: /* iMac 24 */
7073 case 0x106b2800: /* AppleTV */
7074 case 0x106b3e00: /* iMac 24 Aluminium */
7075 board_config = ALC885_IMAC24;
7077 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7078 case 0x106b00a4: /* MacbookPro4,1 */
7079 case 0x106b2c00: /* Macbook Pro rev3 */
7080 case 0x106b3600: /* Macbook 3.1 */
7081 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7082 board_config = ALC885_MBP3;
7085 /* ALC889A is handled better as ALC888-compatible */
7086 if (codec->revision_id == 0x100101 ||
7087 codec->revision_id == 0x100103) {
7089 return patch_alc883(codec);
7091 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7092 "trying auto-probe from BIOS...\n");
7093 board_config = ALC882_AUTO;
7097 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7099 if (board_config == ALC882_AUTO) {
7100 /* automatic parse from the BIOS config */
7101 err = alc882_parse_auto_config(codec);
7107 "hda_codec: Cannot set up configuration "
7108 "from BIOS. Using base mode...\n");
7109 board_config = ALC882_3ST_DIG;
7113 err = snd_hda_attach_beep_device(codec, 0x1);
7119 if (board_config != ALC882_AUTO)
7120 setup_preset(spec, &alc882_presets[board_config]);
7122 if (codec->vendor_id == 0x10ec0885) {
7123 spec->stream_name_analog = "ALC885 Analog";
7124 spec->stream_name_digital = "ALC885 Digital";
7126 spec->stream_name_analog = "ALC882 Analog";
7127 spec->stream_name_digital = "ALC882 Digital";
7130 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7131 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7132 /* FIXME: setup DAC5 */
7133 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7134 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7136 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7137 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7139 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7140 if (!spec->adc_nids && spec->input_mux) {
7141 /* check whether NID 0x07 is valid */
7142 unsigned int wcap = get_wcaps(codec, 0x07);
7144 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7145 if (wcap != AC_WID_AUD_IN) {
7146 spec->adc_nids = alc882_adc_nids_alt;
7147 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7148 spec->capsrc_nids = alc882_capsrc_nids_alt;
7150 spec->adc_nids = alc882_adc_nids;
7151 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7152 spec->capsrc_nids = alc882_capsrc_nids;
7155 set_capture_mixer(spec);
7157 spec->vmaster_nid = 0x0c;
7159 codec->patch_ops = alc_patch_ops;
7160 if (board_config == ALC882_AUTO)
7161 spec->init_hook = alc882_auto_init;
7162 #ifdef CONFIG_SND_HDA_POWER_SAVE
7163 if (!spec->loopback.amplist)
7164 spec->loopback.amplist = alc882_loopbacks;
7166 codec->proc_widget_hook = print_realtek_coef;
7174 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7175 * configuration. Each pin widget can choose any input DACs and a mixer.
7176 * Each ADC is connected from a mixer of all inputs. This makes possible
7177 * 6-channel independent captures.
7179 * In addition, an independent DAC for the multi-playback (not used in this
7182 #define ALC883_DIGOUT_NID 0x06
7183 #define ALC883_DIGIN_NID 0x0a
7185 #define ALC1200_DIGOUT_NID 0x10
7187 static hda_nid_t alc883_dac_nids[4] = {
7188 /* front, rear, clfe, rear_surr */
7189 0x02, 0x03, 0x04, 0x05
7192 static hda_nid_t alc883_adc_nids[2] = {
7197 static hda_nid_t alc883_adc_nids_alt[1] = {
7202 static hda_nid_t alc883_adc_nids_rev[2] = {
7207 #define alc889_adc_nids alc880_adc_nids
7209 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7211 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7213 #define alc889_capsrc_nids alc882_capsrc_nids
7216 /* FIXME: should be a matrix-type input source selection */
7218 static struct hda_input_mux alc883_capture_source = {
7222 { "Front Mic", 0x1 },
7228 static struct hda_input_mux alc883_3stack_6ch_intel = {
7232 { "Front Mic", 0x0 },
7238 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7246 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7256 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7264 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7268 { "Front Mic", 0x1 },
7273 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7284 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7291 static struct hda_verb alc883_3ST_ch2_init[] = {
7292 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7293 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7294 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7295 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7302 static struct hda_verb alc883_3ST_ch4_init[] = {
7303 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7304 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7305 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7307 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7314 static struct hda_verb alc883_3ST_ch6_init[] = {
7315 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7316 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7317 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7318 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7319 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7320 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7324 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7325 { 2, alc883_3ST_ch2_init },
7326 { 4, alc883_3ST_ch4_init },
7327 { 6, alc883_3ST_ch6_init },
7333 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7334 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7335 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7336 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7337 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7344 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7345 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7346 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7347 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7348 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7349 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7356 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7357 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7358 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7359 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7360 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7361 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7362 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7366 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7367 { 2, alc883_3ST_ch2_intel_init },
7368 { 4, alc883_3ST_ch4_intel_init },
7369 { 6, alc883_3ST_ch6_intel_init },
7375 static struct hda_verb alc883_sixstack_ch6_init[] = {
7376 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7377 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7378 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7379 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7386 static struct hda_verb alc883_sixstack_ch8_init[] = {
7387 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7388 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7389 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7390 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7394 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7395 { 6, alc883_sixstack_ch6_init },
7396 { 8, alc883_sixstack_ch8_init },
7399 static struct hda_verb alc883_medion_eapd_verbs[] = {
7400 /* eanable EAPD on medion laptop */
7401 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7402 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7406 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7407 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7410 static struct snd_kcontrol_new alc883_base_mixer[] = {
7411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7412 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7413 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7414 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7415 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7418 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7419 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7420 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7421 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7422 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7423 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7424 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7425 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7429 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7430 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7431 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7432 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7433 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7437 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7438 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7439 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7440 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7441 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7442 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7443 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7446 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7448 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7449 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7454 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7456 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7458 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7460 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7461 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7462 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7463 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7464 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7468 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7469 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7470 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7471 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7472 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7474 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7475 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7476 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7477 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7478 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7482 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7483 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7486 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7487 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7491 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7493 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7494 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7496 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7497 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7501 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7502 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7503 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7504 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7505 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7506 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7507 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7508 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7509 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7510 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7511 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7512 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7513 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7514 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7515 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7516 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7518 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7519 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7520 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7521 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7522 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7526 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7527 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7528 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7529 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7530 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7531 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7533 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7534 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7535 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7539 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7540 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7541 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7542 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7543 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7544 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7546 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7547 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7548 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7552 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7553 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7554 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7555 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7556 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7557 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7558 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7559 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7560 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7562 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7563 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7564 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7565 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7567 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7568 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7569 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7570 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7571 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7572 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7573 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7577 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7578 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7580 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7581 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7582 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7583 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7584 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7585 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7586 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7587 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7588 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7597 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7598 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7599 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7600 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7601 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7602 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7605 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7606 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7607 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7608 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7612 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7613 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7614 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7615 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7616 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7617 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7619 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7620 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7624 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7626 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7628 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7629 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7632 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7633 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7637 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7638 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7640 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7650 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7651 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7652 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7662 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7663 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7664 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7666 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7667 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7668 0x0d, 1, 0x0, HDA_OUTPUT),
7669 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7671 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7672 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7673 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7675 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7676 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7677 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7681 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7682 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7684 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7685 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7689 static struct hda_bind_ctls alc883_bind_cap_vol = {
7690 .ops = &snd_hda_bind_vol,
7692 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7693 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7698 static struct hda_bind_ctls alc883_bind_cap_switch = {
7699 .ops = &snd_hda_bind_sw,
7701 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7702 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7707 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7708 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7709 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7710 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7711 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7712 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7719 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7720 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7721 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7724 /* .name = "Capture Source", */
7725 .name = "Input Source",
7727 .info = alc_mux_enum_info,
7728 .get = alc_mux_enum_get,
7729 .put = alc_mux_enum_put,
7734 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7736 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7737 .name = "Channel Mode",
7738 .info = alc_ch_mode_info,
7739 .get = alc_ch_mode_get,
7740 .put = alc_ch_mode_put,
7745 static struct hda_verb alc883_init_verbs[] = {
7746 /* ADC1: mute amp left and right */
7747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7748 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7749 /* ADC2: mute amp left and right */
7750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7751 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7752 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7755 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7757 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7758 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7759 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7761 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7762 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7763 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7767 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7769 /* mute analog input loopbacks */
7770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7772 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7773 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7774 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7776 /* Front Pin: output 0 (0x0c) */
7777 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7779 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7780 /* Rear Pin: output 1 (0x0d) */
7781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7782 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7783 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7784 /* CLFE Pin: output 2 (0x0e) */
7785 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7786 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7787 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7788 /* Side Pin: output 3 (0x0f) */
7789 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7790 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7791 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7792 /* Mic (rear) pin: input vref at 80% */
7793 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7794 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7795 /* Front Mic pin: input vref at 80% */
7796 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7798 /* Line In pin: input */
7799 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7800 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7801 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7802 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7803 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7804 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7805 /* CD pin widget for input */
7806 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7808 /* FIXME: use matrix-type input source selection */
7809 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7812 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7823 /* toggle speaker-output according to the hp-jack state */
7824 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7826 unsigned int present;
7828 present = snd_hda_codec_read(codec, 0x15, 0,
7829 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7830 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7831 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7832 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7833 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7836 /* auto-toggle front mic */
7838 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7840 unsigned int present;
7843 present = snd_hda_codec_read(codec, 0x18, 0,
7844 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7845 bits = present ? HDA_AMP_MUTE : 0;
7846 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7850 static void alc883_mitac_automute(struct hda_codec *codec)
7852 alc883_mitac_hp_automute(codec);
7853 /* alc883_mitac_mic_automute(codec); */
7856 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7859 switch (res >> 26) {
7860 case ALC880_HP_EVENT:
7861 alc883_mitac_hp_automute(codec);
7863 case ALC880_MIC_EVENT:
7864 /* alc883_mitac_mic_automute(codec); */
7869 static struct hda_verb alc883_mitac_verbs[] = {
7871 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7874 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7875 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7877 /* enable unsolicited event */
7878 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7879 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7884 static struct hda_verb alc883_clevo_m720_verbs[] = {
7886 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7887 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7892 /* enable unsolicited event */
7893 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7894 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7899 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7901 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7902 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7904 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7905 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7907 /* enable unsolicited event */
7908 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7913 static struct hda_verb alc883_tagra_verbs[] = {
7914 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7920 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7921 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7922 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7924 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7925 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7926 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7927 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7932 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7933 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7934 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7935 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7939 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7940 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7942 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7947 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7949 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7950 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7951 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7952 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7956 static struct hda_verb alc883_haier_w66_verbs[] = {
7957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7960 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7963 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7965 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7969 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7972 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7973 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7974 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7976 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7977 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7981 static struct hda_verb alc888_3st_hp_verbs[] = {
7982 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7983 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7984 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7988 static struct hda_verb alc888_6st_dell_verbs[] = {
7989 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7993 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7994 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7995 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7996 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7997 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8001 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8002 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8003 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8004 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8005 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8009 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
8010 { 2, alc888_3st_hp_2ch_init },
8011 { 6, alc888_3st_hp_6ch_init },
8014 /* toggle front-jack and RCA according to the hp-jack state */
8015 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8017 unsigned int present;
8019 present = snd_hda_codec_read(codec, 0x1b, 0,
8020 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8021 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8022 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8023 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8024 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8027 /* toggle RCA according to the front-jack state */
8028 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8030 unsigned int present;
8032 present = snd_hda_codec_read(codec, 0x14, 0,
8033 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8034 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8035 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8038 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8041 if ((res >> 26) == ALC880_HP_EVENT)
8042 alc888_lenovo_ms7195_front_automute(codec);
8043 if ((res >> 26) == ALC880_FRONT_EVENT)
8044 alc888_lenovo_ms7195_rca_automute(codec);
8047 static struct hda_verb alc883_medion_md2_verbs[] = {
8048 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8049 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8053 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8057 /* toggle speaker-output according to the hp-jack state */
8058 static void alc883_medion_md2_automute(struct hda_codec *codec)
8060 unsigned int present;
8062 present = snd_hda_codec_read(codec, 0x14, 0,
8063 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8064 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8065 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8068 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8071 if ((res >> 26) == ALC880_HP_EVENT)
8072 alc883_medion_md2_automute(codec);
8075 /* toggle speaker-output according to the hp-jack state */
8076 static void alc883_tagra_automute(struct hda_codec *codec)
8078 unsigned int present;
8081 present = snd_hda_codec_read(codec, 0x14, 0,
8082 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8083 bits = present ? HDA_AMP_MUTE : 0;
8084 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8085 HDA_AMP_MUTE, bits);
8086 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8090 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8092 if ((res >> 26) == ALC880_HP_EVENT)
8093 alc883_tagra_automute(codec);
8096 /* toggle speaker-output according to the hp-jack state */
8097 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
8099 unsigned int present;
8102 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8103 & AC_PINSENSE_PRESENCE;
8104 bits = present ? HDA_AMP_MUTE : 0;
8105 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8106 HDA_AMP_MUTE, bits);
8109 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8111 unsigned int present;
8113 present = snd_hda_codec_read(codec, 0x18, 0,
8114 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8115 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8116 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8119 static void alc883_clevo_m720_automute(struct hda_codec *codec)
8121 alc883_clevo_m720_hp_automute(codec);
8122 alc883_clevo_m720_mic_automute(codec);
8125 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8128 switch (res >> 26) {
8129 case ALC880_HP_EVENT:
8130 alc883_clevo_m720_hp_automute(codec);
8132 case ALC880_MIC_EVENT:
8133 alc883_clevo_m720_mic_automute(codec);
8138 /* toggle speaker-output according to the hp-jack state */
8139 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8141 unsigned int present;
8144 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8145 & AC_PINSENSE_PRESENCE;
8146 bits = present ? HDA_AMP_MUTE : 0;
8147 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8148 HDA_AMP_MUTE, bits);
8151 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8154 if ((res >> 26) == ALC880_HP_EVENT)
8155 alc883_2ch_fujitsu_pi2515_automute(codec);
8158 static void alc883_haier_w66_automute(struct hda_codec *codec)
8160 unsigned int present;
8163 present = snd_hda_codec_read(codec, 0x1b, 0,
8164 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8165 bits = present ? 0x80 : 0;
8166 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8170 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8173 if ((res >> 26) == ALC880_HP_EVENT)
8174 alc883_haier_w66_automute(codec);
8177 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8179 unsigned int present;
8182 present = snd_hda_codec_read(codec, 0x14, 0,
8183 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8184 bits = present ? HDA_AMP_MUTE : 0;
8185 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8186 HDA_AMP_MUTE, bits);
8189 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8191 unsigned int present;
8194 present = snd_hda_codec_read(codec, 0x1b, 0,
8195 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8196 bits = present ? HDA_AMP_MUTE : 0;
8197 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8198 HDA_AMP_MUTE, bits);
8199 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8200 HDA_AMP_MUTE, bits);
8203 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8206 if ((res >> 26) == ALC880_HP_EVENT)
8207 alc883_lenovo_101e_all_automute(codec);
8208 if ((res >> 26) == ALC880_FRONT_EVENT)
8209 alc883_lenovo_101e_ispeaker_automute(codec);
8212 /* toggle speaker-output according to the hp-jack state */
8213 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8215 unsigned int present;
8217 present = snd_hda_codec_read(codec, 0x14, 0,
8218 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8219 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8220 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8221 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8222 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8225 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8228 if ((res >> 26) == ALC880_HP_EVENT)
8229 alc883_acer_aspire_automute(codec);
8232 static struct hda_verb alc883_acer_eapd_verbs[] = {
8233 /* HP Pin: output 0 (0x0c) */
8234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8237 /* Front Pin: output 0 (0x0c) */
8238 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8239 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8240 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8241 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8242 /* eanable EAPD on medion laptop */
8243 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8244 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8245 /* enable unsolicited event */
8246 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8250 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8252 unsigned int present;
8254 present = snd_hda_codec_read(codec, 0x1b, 0,
8255 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8256 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8257 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8258 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8259 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8260 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8261 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8262 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8263 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8266 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8269 switch (res >> 26) {
8270 case ALC880_HP_EVENT:
8271 /* printk(KERN_DEBUG "hp_event\n"); */
8272 alc888_6st_dell_front_automute(codec);
8277 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8280 unsigned int present;
8282 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8283 present = snd_hda_codec_read(codec, 0x1b, 0,
8284 AC_VERB_GET_PIN_SENSE, 0);
8285 present = (present & 0x80000000) != 0;
8287 /* mute internal speaker */
8288 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8289 HDA_AMP_MUTE, HDA_AMP_MUTE);
8290 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8291 HDA_AMP_MUTE, HDA_AMP_MUTE);
8292 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8293 HDA_AMP_MUTE, HDA_AMP_MUTE);
8294 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8295 HDA_AMP_MUTE, HDA_AMP_MUTE);
8296 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8297 HDA_AMP_MUTE, HDA_AMP_MUTE);
8299 /* unmute internal speaker if necessary */
8300 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8301 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8302 HDA_AMP_MUTE, mute);
8303 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8304 HDA_AMP_MUTE, mute);
8305 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8306 HDA_AMP_MUTE, mute);
8307 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8308 HDA_AMP_MUTE, mute);
8309 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8310 HDA_AMP_MUTE, mute);
8314 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8317 if ((res >> 26) == ALC880_HP_EVENT)
8318 alc888_lenovo_sky_front_automute(codec);
8322 * generic initialization of ADC, input mixers and output mixers
8324 static struct hda_verb alc883_auto_init_verbs[] = {
8326 * Unmute ADC0-2 and set the default input to mic-in
8328 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8330 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8333 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8335 * Note: PASD motherboards uses the Line In 2 as the input for
8336 * front panel mic (mic 2)
8338 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8341 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8342 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8346 * Set up output mixers (0x0c - 0x0f)
8348 /* set vol=0 to output mixers */
8349 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8350 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8351 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8353 /* set up input amps for analog loopback */
8354 /* Amp Indices: DAC = 0, mixer = 1 */
8355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8360 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8361 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8362 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8363 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8364 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8366 /* FIXME: use matrix-type input source selection */
8367 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8371 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8372 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8373 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8378 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8384 static struct hda_verb alc888_asus_m90v_verbs[] = {
8385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8388 /* enable unsolicited event */
8389 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8390 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8394 static void alc883_nb_mic_automute(struct hda_codec *codec)
8396 unsigned int present;
8398 present = snd_hda_codec_read(codec, 0x18, 0,
8399 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8400 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8401 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8402 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8403 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8406 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8408 unsigned int present;
8411 present = snd_hda_codec_read(codec, 0x1b, 0,
8412 AC_VERB_GET_PIN_SENSE, 0)
8413 & AC_PINSENSE_PRESENCE;
8414 bits = present ? 0 : PIN_OUT;
8415 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8417 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8419 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8423 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8426 switch (res >> 26) {
8427 case ALC880_HP_EVENT:
8428 alc883_M90V_speaker_automute(codec);
8430 case ALC880_MIC_EVENT:
8431 alc883_nb_mic_automute(codec);
8436 static void alc883_mode2_inithook(struct hda_codec *codec)
8438 alc883_M90V_speaker_automute(codec);
8439 alc883_nb_mic_automute(codec);
8442 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8444 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8448 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8449 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8450 /* enable unsolicited event */
8451 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8455 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8457 unsigned int present;
8460 present = snd_hda_codec_read(codec, 0x14, 0,
8461 AC_VERB_GET_PIN_SENSE, 0)
8462 & AC_PINSENSE_PRESENCE;
8463 bits = present ? 0 : PIN_OUT;
8464 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8468 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8471 switch (res >> 26) {
8472 case ALC880_HP_EVENT:
8473 alc883_eee1601_speaker_automute(codec);
8478 static void alc883_eee1601_inithook(struct hda_codec *codec)
8480 alc883_eee1601_speaker_automute(codec);
8483 #ifdef CONFIG_SND_HDA_POWER_SAVE
8484 #define alc883_loopbacks alc880_loopbacks
8487 /* pcm configuration: identiacal with ALC880 */
8488 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8489 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8490 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8491 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8492 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8495 * configuration and preset
8497 static const char *alc883_models[ALC883_MODEL_LAST] = {
8498 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8499 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8500 [ALC883_3ST_6ch] = "3stack-6ch",
8501 [ALC883_6ST_DIG] = "6stack-dig",
8502 [ALC883_TARGA_DIG] = "targa-dig",
8503 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8504 [ALC883_ACER] = "acer",
8505 [ALC883_ACER_ASPIRE] = "acer-aspire",
8506 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8507 [ALC883_MEDION] = "medion",
8508 [ALC883_MEDION_MD2] = "medion-md2",
8509 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8510 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8511 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8512 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8513 [ALC888_LENOVO_SKY] = "lenovo-sky",
8514 [ALC883_HAIER_W66] = "haier-w66",
8515 [ALC888_3ST_HP] = "3stack-hp",
8516 [ALC888_6ST_DELL] = "6stack-dell",
8517 [ALC883_MITAC] = "mitac",
8518 [ALC883_CLEVO_M720] = "clevo-m720",
8519 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8520 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8521 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8522 [ALC1200_ASUS_P5Q] = "asus-p5q",
8523 [ALC883_AUTO] = "auto",
8526 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8527 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8528 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8529 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8530 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8531 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8532 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8533 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8534 ALC888_ACER_ASPIRE_4930G),
8535 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8536 ALC888_ACER_ASPIRE_4930G),
8537 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8538 ALC888_ACER_ASPIRE_4930G),
8539 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8540 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8541 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8542 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8543 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8544 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8545 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8546 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8547 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8548 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8549 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8550 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8551 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8552 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8553 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8554 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8555 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8556 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8557 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8558 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8559 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8560 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8561 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8562 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8563 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8564 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8565 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8566 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8567 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8568 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8569 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8570 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8571 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8572 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8573 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8574 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8575 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8576 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8577 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8578 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8579 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8580 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8581 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8582 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8583 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8584 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8585 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8586 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8587 SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550",
8588 ALC883_FUJITSU_PI2515),
8589 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8590 SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
8591 ALC888_FUJITSU_XA3530),
8592 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8593 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8594 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8595 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8596 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8597 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8598 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8599 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8600 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8601 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8602 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8603 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8604 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8605 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8609 static hda_nid_t alc1200_slave_dig_outs[] = {
8610 ALC883_DIGOUT_NID, 0,
8613 static struct alc_config_preset alc883_presets[] = {
8614 [ALC883_3ST_2ch_DIG] = {
8615 .mixers = { alc883_3ST_2ch_mixer },
8616 .init_verbs = { alc883_init_verbs },
8617 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8618 .dac_nids = alc883_dac_nids,
8619 .dig_out_nid = ALC883_DIGOUT_NID,
8620 .dig_in_nid = ALC883_DIGIN_NID,
8621 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8622 .channel_mode = alc883_3ST_2ch_modes,
8623 .input_mux = &alc883_capture_source,
8625 [ALC883_3ST_6ch_DIG] = {
8626 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8627 .init_verbs = { alc883_init_verbs },
8628 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8629 .dac_nids = alc883_dac_nids,
8630 .dig_out_nid = ALC883_DIGOUT_NID,
8631 .dig_in_nid = ALC883_DIGIN_NID,
8632 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8633 .channel_mode = alc883_3ST_6ch_modes,
8635 .input_mux = &alc883_capture_source,
8637 [ALC883_3ST_6ch] = {
8638 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8639 .init_verbs = { alc883_init_verbs },
8640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8641 .dac_nids = alc883_dac_nids,
8642 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8643 .channel_mode = alc883_3ST_6ch_modes,
8645 .input_mux = &alc883_capture_source,
8647 [ALC883_3ST_6ch_INTEL] = {
8648 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8649 .init_verbs = { alc883_init_verbs },
8650 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8651 .dac_nids = alc883_dac_nids,
8652 .dig_out_nid = ALC883_DIGOUT_NID,
8653 .dig_in_nid = ALC883_DIGIN_NID,
8654 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8655 .channel_mode = alc883_3ST_6ch_intel_modes,
8657 .input_mux = &alc883_3stack_6ch_intel,
8659 [ALC883_6ST_DIG] = {
8660 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8661 .init_verbs = { alc883_init_verbs },
8662 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8663 .dac_nids = alc883_dac_nids,
8664 .dig_out_nid = ALC883_DIGOUT_NID,
8665 .dig_in_nid = ALC883_DIGIN_NID,
8666 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8667 .channel_mode = alc883_sixstack_modes,
8668 .input_mux = &alc883_capture_source,
8670 [ALC883_TARGA_DIG] = {
8671 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8672 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8673 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8674 .dac_nids = alc883_dac_nids,
8675 .dig_out_nid = ALC883_DIGOUT_NID,
8676 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8677 .channel_mode = alc883_3ST_6ch_modes,
8679 .input_mux = &alc883_capture_source,
8680 .unsol_event = alc883_tagra_unsol_event,
8681 .init_hook = alc883_tagra_automute,
8683 [ALC883_TARGA_2ch_DIG] = {
8684 .mixers = { alc883_tagra_2ch_mixer},
8685 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8686 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8687 .dac_nids = alc883_dac_nids,
8688 .adc_nids = alc883_adc_nids_alt,
8689 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8690 .dig_out_nid = ALC883_DIGOUT_NID,
8691 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8692 .channel_mode = alc883_3ST_2ch_modes,
8693 .input_mux = &alc883_capture_source,
8694 .unsol_event = alc883_tagra_unsol_event,
8695 .init_hook = alc883_tagra_automute,
8698 .mixers = { alc883_base_mixer },
8699 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8700 * and the headphone jack. Turn this on and rely on the
8701 * standard mute methods whenever the user wants to turn
8702 * these outputs off.
8704 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8705 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8706 .dac_nids = alc883_dac_nids,
8707 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8708 .channel_mode = alc883_3ST_2ch_modes,
8709 .input_mux = &alc883_capture_source,
8711 [ALC883_ACER_ASPIRE] = {
8712 .mixers = { alc883_acer_aspire_mixer },
8713 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8714 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8715 .dac_nids = alc883_dac_nids,
8716 .dig_out_nid = ALC883_DIGOUT_NID,
8717 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8718 .channel_mode = alc883_3ST_2ch_modes,
8719 .input_mux = &alc883_capture_source,
8720 .unsol_event = alc883_acer_aspire_unsol_event,
8721 .init_hook = alc883_acer_aspire_automute,
8723 [ALC888_ACER_ASPIRE_4930G] = {
8724 .mixers = { alc888_base_mixer,
8725 alc883_chmode_mixer },
8726 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8727 alc888_acer_aspire_4930g_verbs },
8728 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8729 .dac_nids = alc883_dac_nids,
8730 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8731 .adc_nids = alc883_adc_nids_rev,
8732 .capsrc_nids = alc883_capsrc_nids_rev,
8733 .dig_out_nid = ALC883_DIGOUT_NID,
8734 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8735 .channel_mode = alc883_3ST_6ch_modes,
8738 ARRAY_SIZE(alc888_2_capture_sources),
8739 .input_mux = alc888_2_capture_sources,
8740 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8741 .init_hook = alc888_acer_aspire_4930g_automute,
8744 .mixers = { alc883_fivestack_mixer,
8745 alc883_chmode_mixer },
8746 .init_verbs = { alc883_init_verbs,
8747 alc883_medion_eapd_verbs },
8748 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8749 .dac_nids = alc883_dac_nids,
8750 .adc_nids = alc883_adc_nids_alt,
8751 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8752 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8753 .channel_mode = alc883_sixstack_modes,
8754 .input_mux = &alc883_capture_source,
8756 [ALC883_MEDION_MD2] = {
8757 .mixers = { alc883_medion_md2_mixer},
8758 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8760 .dac_nids = alc883_dac_nids,
8761 .dig_out_nid = ALC883_DIGOUT_NID,
8762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8763 .channel_mode = alc883_3ST_2ch_modes,
8764 .input_mux = &alc883_capture_source,
8765 .unsol_event = alc883_medion_md2_unsol_event,
8766 .init_hook = alc883_medion_md2_automute,
8768 [ALC883_LAPTOP_EAPD] = {
8769 .mixers = { alc883_base_mixer },
8770 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8771 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8772 .dac_nids = alc883_dac_nids,
8773 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8774 .channel_mode = alc883_3ST_2ch_modes,
8775 .input_mux = &alc883_capture_source,
8777 [ALC883_CLEVO_M720] = {
8778 .mixers = { alc883_clevo_m720_mixer },
8779 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8780 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8781 .dac_nids = alc883_dac_nids,
8782 .dig_out_nid = ALC883_DIGOUT_NID,
8783 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8784 .channel_mode = alc883_3ST_2ch_modes,
8785 .input_mux = &alc883_capture_source,
8786 .unsol_event = alc883_clevo_m720_unsol_event,
8787 .init_hook = alc883_clevo_m720_automute,
8789 [ALC883_LENOVO_101E_2ch] = {
8790 .mixers = { alc883_lenovo_101e_2ch_mixer},
8791 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8792 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8793 .dac_nids = alc883_dac_nids,
8794 .adc_nids = alc883_adc_nids_alt,
8795 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8796 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8797 .channel_mode = alc883_3ST_2ch_modes,
8798 .input_mux = &alc883_lenovo_101e_capture_source,
8799 .unsol_event = alc883_lenovo_101e_unsol_event,
8800 .init_hook = alc883_lenovo_101e_all_automute,
8802 [ALC883_LENOVO_NB0763] = {
8803 .mixers = { alc883_lenovo_nb0763_mixer },
8804 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8805 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8806 .dac_nids = alc883_dac_nids,
8807 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8808 .channel_mode = alc883_3ST_2ch_modes,
8810 .input_mux = &alc883_lenovo_nb0763_capture_source,
8811 .unsol_event = alc883_medion_md2_unsol_event,
8812 .init_hook = alc883_medion_md2_automute,
8814 [ALC888_LENOVO_MS7195_DIG] = {
8815 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8816 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8817 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8818 .dac_nids = alc883_dac_nids,
8819 .dig_out_nid = ALC883_DIGOUT_NID,
8820 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8821 .channel_mode = alc883_3ST_6ch_modes,
8823 .input_mux = &alc883_capture_source,
8824 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8825 .init_hook = alc888_lenovo_ms7195_front_automute,
8827 [ALC883_HAIER_W66] = {
8828 .mixers = { alc883_tagra_2ch_mixer},
8829 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8831 .dac_nids = alc883_dac_nids,
8832 .dig_out_nid = ALC883_DIGOUT_NID,
8833 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8834 .channel_mode = alc883_3ST_2ch_modes,
8835 .input_mux = &alc883_capture_source,
8836 .unsol_event = alc883_haier_w66_unsol_event,
8837 .init_hook = alc883_haier_w66_automute,
8840 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8841 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8843 .dac_nids = alc883_dac_nids,
8844 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8845 .channel_mode = alc888_3st_hp_modes,
8847 .input_mux = &alc883_capture_source,
8849 [ALC888_6ST_DELL] = {
8850 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8851 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8852 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8853 .dac_nids = alc883_dac_nids,
8854 .dig_out_nid = ALC883_DIGOUT_NID,
8855 .dig_in_nid = ALC883_DIGIN_NID,
8856 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8857 .channel_mode = alc883_sixstack_modes,
8858 .input_mux = &alc883_capture_source,
8859 .unsol_event = alc888_6st_dell_unsol_event,
8860 .init_hook = alc888_6st_dell_front_automute,
8863 .mixers = { alc883_mitac_mixer },
8864 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8865 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8866 .dac_nids = alc883_dac_nids,
8867 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8868 .channel_mode = alc883_3ST_2ch_modes,
8869 .input_mux = &alc883_capture_source,
8870 .unsol_event = alc883_mitac_unsol_event,
8871 .init_hook = alc883_mitac_automute,
8873 [ALC883_FUJITSU_PI2515] = {
8874 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8875 .init_verbs = { alc883_init_verbs,
8876 alc883_2ch_fujitsu_pi2515_verbs},
8877 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8878 .dac_nids = alc883_dac_nids,
8879 .dig_out_nid = ALC883_DIGOUT_NID,
8880 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8881 .channel_mode = alc883_3ST_2ch_modes,
8882 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8883 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8884 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8886 [ALC888_FUJITSU_XA3530] = {
8887 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8888 .init_verbs = { alc883_init_verbs,
8889 alc888_fujitsu_xa3530_verbs },
8890 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8891 .dac_nids = alc883_dac_nids,
8892 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8893 .adc_nids = alc883_adc_nids_rev,
8894 .capsrc_nids = alc883_capsrc_nids_rev,
8895 .dig_out_nid = ALC883_DIGOUT_NID,
8896 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8897 .channel_mode = alc888_4ST_8ch_intel_modes,
8899 ARRAY_SIZE(alc888_2_capture_sources),
8900 .input_mux = alc888_2_capture_sources,
8901 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
8902 .init_hook = alc888_fujitsu_xa3530_automute,
8904 [ALC888_LENOVO_SKY] = {
8905 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8906 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8907 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8908 .dac_nids = alc883_dac_nids,
8909 .dig_out_nid = ALC883_DIGOUT_NID,
8910 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8911 .channel_mode = alc883_sixstack_modes,
8913 .input_mux = &alc883_lenovo_sky_capture_source,
8914 .unsol_event = alc883_lenovo_sky_unsol_event,
8915 .init_hook = alc888_lenovo_sky_front_automute,
8917 [ALC888_ASUS_M90V] = {
8918 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8919 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8921 .dac_nids = alc883_dac_nids,
8922 .dig_out_nid = ALC883_DIGOUT_NID,
8923 .dig_in_nid = ALC883_DIGIN_NID,
8924 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8925 .channel_mode = alc883_3ST_6ch_modes,
8927 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8928 .unsol_event = alc883_mode2_unsol_event,
8929 .init_hook = alc883_mode2_inithook,
8931 [ALC888_ASUS_EEE1601] = {
8932 .mixers = { alc883_asus_eee1601_mixer },
8933 .cap_mixer = alc883_asus_eee1601_cap_mixer,
8934 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8935 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8936 .dac_nids = alc883_dac_nids,
8937 .dig_out_nid = ALC883_DIGOUT_NID,
8938 .dig_in_nid = ALC883_DIGIN_NID,
8939 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8940 .channel_mode = alc883_3ST_2ch_modes,
8942 .input_mux = &alc883_asus_eee1601_capture_source,
8943 .unsol_event = alc883_eee1601_unsol_event,
8944 .init_hook = alc883_eee1601_inithook,
8946 [ALC1200_ASUS_P5Q] = {
8947 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8948 .init_verbs = { alc883_init_verbs },
8949 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8950 .dac_nids = alc883_dac_nids,
8951 .dig_out_nid = ALC1200_DIGOUT_NID,
8952 .dig_in_nid = ALC883_DIGIN_NID,
8953 .slave_dig_outs = alc1200_slave_dig_outs,
8954 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8955 .channel_mode = alc883_sixstack_modes,
8956 .input_mux = &alc883_capture_source,
8962 * BIOS auto configuration
8964 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8965 hda_nid_t nid, int pin_type,
8969 struct alc_spec *spec = codec->spec;
8972 alc_set_pin_output(codec, nid, pin_type);
8973 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8976 idx = spec->multiout.dac_nids[dac_idx] - 2;
8977 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8981 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8983 struct alc_spec *spec = codec->spec;
8986 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8987 for (i = 0; i <= HDA_SIDE; i++) {
8988 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8989 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8991 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8996 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8998 struct alc_spec *spec = codec->spec;
9001 pin = spec->autocfg.hp_pins[0];
9002 if (pin) /* connect to front */
9004 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9005 pin = spec->autocfg.speaker_pins[0];
9007 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9010 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9011 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9013 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9015 struct alc_spec *spec = codec->spec;
9018 for (i = 0; i < AUTO_PIN_LAST; i++) {
9019 hda_nid_t nid = spec->autocfg.input_pins[i];
9020 if (alc883_is_input_pin(nid)) {
9021 snd_hda_codec_write(codec, nid, 0,
9022 AC_VERB_SET_PIN_WIDGET_CONTROL,
9023 (i <= AUTO_PIN_FRONT_MIC ?
9024 PIN_VREF80 : PIN_IN));
9025 if (nid != ALC883_PIN_CD_NID)
9026 snd_hda_codec_write(codec, nid, 0,
9027 AC_VERB_SET_AMP_GAIN_MUTE,
9033 #define alc883_auto_init_input_src alc882_auto_init_input_src
9035 /* almost identical with ALC880 parser... */
9036 static int alc883_parse_auto_config(struct hda_codec *codec)
9038 struct alc_spec *spec = codec->spec;
9039 int err = alc880_parse_auto_config(codec);
9040 struct auto_pin_cfg *cfg = &spec->autocfg;
9046 return 0; /* no config found */
9048 err = alc_auto_add_mic_boost(codec);
9052 /* hack - override the init verbs */
9053 spec->init_verbs[0] = alc883_auto_init_verbs;
9055 /* setup input_mux for ALC889 */
9056 if (codec->vendor_id == 0x10ec0889) {
9057 /* digital-mic input pin is excluded in alc880_auto_create..()
9058 * because it's under 0x18
9060 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9061 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9062 struct hda_input_mux *imux = &spec->private_imux[0];
9063 for (i = 1; i < 3; i++)
9064 memcpy(&spec->private_imux[i],
9065 &spec->private_imux[0],
9066 sizeof(spec->private_imux[0]));
9067 imux->items[imux->num_items].label = "Int DMic";
9068 imux->items[imux->num_items].index = 0x0b;
9070 spec->num_mux_defs = 3;
9071 spec->input_mux = spec->private_imux;
9075 return 1; /* config found */
9078 /* additional initialization for auto-configuration model */
9079 static void alc883_auto_init(struct hda_codec *codec)
9081 struct alc_spec *spec = codec->spec;
9082 alc883_auto_init_multi_out(codec);
9083 alc883_auto_init_hp_out(codec);
9084 alc883_auto_init_analog_input(codec);
9085 alc883_auto_init_input_src(codec);
9086 if (spec->unsol_event)
9087 alc_inithook(codec);
9090 static int patch_alc883(struct hda_codec *codec)
9092 struct alc_spec *spec;
9093 int err, board_config;
9095 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9101 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9103 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9106 if (board_config < 0) {
9107 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9108 "trying auto-probe from BIOS...\n");
9109 board_config = ALC883_AUTO;
9112 if (board_config == ALC883_AUTO) {
9113 /* automatic parse from the BIOS config */
9114 err = alc883_parse_auto_config(codec);
9120 "hda_codec: Cannot set up configuration "
9121 "from BIOS. Using base mode...\n");
9122 board_config = ALC883_3ST_2ch_DIG;
9126 err = snd_hda_attach_beep_device(codec, 0x1);
9132 if (board_config != ALC883_AUTO)
9133 setup_preset(spec, &alc883_presets[board_config]);
9135 switch (codec->vendor_id) {
9137 if (codec->revision_id == 0x100101) {
9138 spec->stream_name_analog = "ALC1200 Analog";
9139 spec->stream_name_digital = "ALC1200 Digital";
9141 spec->stream_name_analog = "ALC888 Analog";
9142 spec->stream_name_digital = "ALC888 Digital";
9144 if (!spec->num_adc_nids) {
9145 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9146 spec->adc_nids = alc883_adc_nids;
9148 if (!spec->capsrc_nids)
9149 spec->capsrc_nids = alc883_capsrc_nids;
9150 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9153 spec->stream_name_analog = "ALC889 Analog";
9154 spec->stream_name_digital = "ALC889 Digital";
9155 if (!spec->num_adc_nids) {
9156 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9157 spec->adc_nids = alc889_adc_nids;
9159 if (!spec->capsrc_nids)
9160 spec->capsrc_nids = alc889_capsrc_nids;
9161 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9165 spec->stream_name_analog = "ALC883 Analog";
9166 spec->stream_name_digital = "ALC883 Digital";
9167 if (!spec->num_adc_nids) {
9168 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9169 spec->adc_nids = alc883_adc_nids;
9171 if (!spec->capsrc_nids)
9172 spec->capsrc_nids = alc883_capsrc_nids;
9173 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9177 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9178 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9179 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9181 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9182 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9184 if (!spec->cap_mixer)
9185 set_capture_mixer(spec);
9187 spec->vmaster_nid = 0x0c;
9189 codec->patch_ops = alc_patch_ops;
9190 if (board_config == ALC883_AUTO)
9191 spec->init_hook = alc883_auto_init;
9193 #ifdef CONFIG_SND_HDA_POWER_SAVE
9194 if (!spec->loopback.amplist)
9195 spec->loopback.amplist = alc883_loopbacks;
9197 codec->proc_widget_hook = print_realtek_coef;
9206 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9207 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9209 #define alc262_dac_nids alc260_dac_nids
9210 #define alc262_adc_nids alc882_adc_nids
9211 #define alc262_adc_nids_alt alc882_adc_nids_alt
9212 #define alc262_capsrc_nids alc882_capsrc_nids
9213 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9215 #define alc262_modes alc260_modes
9216 #define alc262_capture_source alc882_capture_source
9218 static hda_nid_t alc262_dmic_adc_nids[1] = {
9223 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9225 static struct snd_kcontrol_new alc262_base_mixer[] = {
9226 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9227 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9230 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9231 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9234 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9235 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9236 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9238 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9239 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9241 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9242 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9243 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9247 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9249 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9250 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9251 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9252 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9253 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9256 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9258 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9260 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9261 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9262 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9267 /* update HP, line and mono-out pins according to the master switch */
9268 static void alc262_hp_master_update(struct hda_codec *codec)
9270 struct alc_spec *spec = codec->spec;
9271 int val = spec->master_sw;
9274 snd_hda_codec_write_cache(codec, 0x1b, 0,
9275 AC_VERB_SET_PIN_WIDGET_CONTROL,
9277 snd_hda_codec_write_cache(codec, 0x15, 0,
9278 AC_VERB_SET_PIN_WIDGET_CONTROL,
9280 /* mono (speaker) depending on the HP jack sense */
9281 val = val && !spec->jack_present;
9282 snd_hda_codec_write_cache(codec, 0x16, 0,
9283 AC_VERB_SET_PIN_WIDGET_CONTROL,
9287 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9289 struct alc_spec *spec = codec->spec;
9290 unsigned int presence;
9291 presence = snd_hda_codec_read(codec, 0x1b, 0,
9292 AC_VERB_GET_PIN_SENSE, 0);
9293 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9294 alc262_hp_master_update(codec);
9297 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9299 if ((res >> 26) != ALC880_HP_EVENT)
9301 alc262_hp_bpc_automute(codec);
9304 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9306 struct alc_spec *spec = codec->spec;
9307 unsigned int presence;
9308 presence = snd_hda_codec_read(codec, 0x15, 0,
9309 AC_VERB_GET_PIN_SENSE, 0);
9310 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9311 alc262_hp_master_update(codec);
9314 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9317 if ((res >> 26) != ALC880_HP_EVENT)
9319 alc262_hp_wildwest_automute(codec);
9322 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9323 struct snd_ctl_elem_value *ucontrol)
9325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9326 struct alc_spec *spec = codec->spec;
9327 *ucontrol->value.integer.value = spec->master_sw;
9331 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9332 struct snd_ctl_elem_value *ucontrol)
9334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9335 struct alc_spec *spec = codec->spec;
9336 int val = !!*ucontrol->value.integer.value;
9338 if (val == spec->master_sw)
9340 spec->master_sw = val;
9341 alc262_hp_master_update(codec);
9345 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9347 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9348 .name = "Master Playback Switch",
9349 .info = snd_ctl_boolean_mono_info,
9350 .get = alc262_hp_master_sw_get,
9351 .put = alc262_hp_master_sw_put,
9353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9354 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9355 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9356 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9358 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9362 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9363 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9365 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9368 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9369 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9370 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9371 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9372 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9373 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9377 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9379 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9380 .name = "Master Playback Switch",
9381 .info = snd_ctl_boolean_mono_info,
9382 .get = alc262_hp_master_sw_get,
9383 .put = alc262_hp_master_sw_put,
9385 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9386 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9387 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9388 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9389 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9391 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9393 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9395 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9396 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9397 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9398 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9399 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9400 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9401 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9405 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9406 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9407 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9408 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9412 /* mute/unmute internal speaker according to the hp jack and mute state */
9413 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9415 struct alc_spec *spec = codec->spec;
9417 if (force || !spec->sense_updated) {
9418 unsigned int present;
9419 present = snd_hda_codec_read(codec, 0x15, 0,
9420 AC_VERB_GET_PIN_SENSE, 0);
9421 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9422 spec->sense_updated = 1;
9424 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9425 spec->jack_present ? HDA_AMP_MUTE : 0);
9428 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9431 if ((res >> 26) != ALC880_HP_EVENT)
9433 alc262_hp_t5735_automute(codec, 1);
9436 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9438 alc262_hp_t5735_automute(codec, 1);
9441 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9442 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9443 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9444 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9448 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9452 static struct hda_verb alc262_hp_t5735_verbs[] = {
9453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9454 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9460 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9461 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9463 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9464 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9470 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9471 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9472 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9473 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9474 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9475 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9476 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9478 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9479 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9480 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9484 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9491 /* bind hp and internal speaker mute (with plug check) */
9492 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9493 struct snd_ctl_elem_value *ucontrol)
9495 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9496 long *valp = ucontrol->value.integer.value;
9499 /* change hp mute */
9500 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9502 valp[0] ? 0 : HDA_AMP_MUTE);
9503 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9505 valp[1] ? 0 : HDA_AMP_MUTE);
9507 /* change speaker according to HP jack state */
9508 struct alc_spec *spec = codec->spec;
9510 if (spec->jack_present)
9511 mute = HDA_AMP_MUTE;
9513 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9515 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9516 HDA_AMP_MUTE, mute);
9521 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9522 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9525 .name = "Master Playback Switch",
9526 .info = snd_hda_mixer_amp_switch_info,
9527 .get = snd_hda_mixer_amp_switch_get,
9528 .put = alc262_sony_master_sw_put,
9529 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9532 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9533 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9534 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9538 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9540 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9543 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9544 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9545 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9549 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9550 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9551 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9552 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9553 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9554 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9555 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9558 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9559 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9561 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9565 static struct hda_verb alc262_tyan_verbs[] = {
9566 /* Headphone automute */
9567 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9568 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9569 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9571 /* P11 AUX_IN, white 4-pin connector */
9572 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9573 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9574 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9575 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9580 /* unsolicited event for HP jack sensing */
9581 static void alc262_tyan_automute(struct hda_codec *codec)
9584 unsigned int present;
9586 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9587 present = snd_hda_codec_read(codec, 0x1b, 0,
9588 AC_VERB_GET_PIN_SENSE, 0);
9589 present = (present & 0x80000000) != 0;
9591 /* mute line output on ATX panel */
9592 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9593 HDA_AMP_MUTE, HDA_AMP_MUTE);
9595 /* unmute line output if necessary */
9596 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9597 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9598 HDA_AMP_MUTE, mute);
9602 static void alc262_tyan_unsol_event(struct hda_codec *codec,
9605 if ((res >> 26) != ALC880_HP_EVENT)
9607 alc262_tyan_automute(codec);
9610 #define alc262_capture_mixer alc882_capture_mixer
9611 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9614 * generic initialization of ADC, input mixers and output mixers
9616 static struct hda_verb alc262_init_verbs[] = {
9618 * Unmute ADC0-2 and set the default input to mic-in
9620 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9622 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9623 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9624 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9625 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9627 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9629 * Note: PASD motherboards uses the Line In 2 as the input for
9630 * front panel mic (mic 2)
9632 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9637 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9640 * Set up output mixers (0x0c - 0x0e)
9642 /* set vol=0 to output mixers */
9643 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9646 /* set up input amps for analog loopback */
9647 /* Amp Indices: DAC = 0, mixer = 1 */
9648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9656 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9657 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9658 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9660 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9662 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9666 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9668 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9669 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9671 /* FIXME: use matrix-type input source selection */
9672 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9673 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9675 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9676 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9677 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9680 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9681 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9682 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9684 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9685 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9686 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9692 static struct hda_verb alc262_eapd_verbs[] = {
9693 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9694 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9698 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9699 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9704 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9705 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9709 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9710 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9714 static struct hda_verb alc262_sony_unsol_verbs[] = {
9715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9716 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9719 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9724 static struct hda_input_mux alc262_dmic_capture_source = {
9727 { "Int DMic", 0x9 },
9732 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9733 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9734 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9735 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9737 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9741 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9742 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9745 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9746 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9748 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9749 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9753 static void alc262_dmic_automute(struct hda_codec *codec)
9755 unsigned int present;
9757 present = snd_hda_codec_read(codec, 0x18, 0,
9758 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9759 snd_hda_codec_write(codec, 0x22, 0,
9760 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9763 /* toggle speaker-output according to the hp-jack state */
9764 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9766 unsigned int present;
9769 present = snd_hda_codec_read(codec, 0x15, 0,
9770 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9771 bits = present ? 0 : PIN_OUT;
9772 snd_hda_codec_write(codec, 0x14, 0,
9773 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9778 /* unsolicited event for HP jack sensing */
9779 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9782 if ((res >> 26) == ALC880_HP_EVENT)
9783 alc262_toshiba_s06_speaker_automute(codec);
9784 if ((res >> 26) == ALC880_MIC_EVENT)
9785 alc262_dmic_automute(codec);
9789 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9791 alc262_toshiba_s06_speaker_automute(codec);
9792 alc262_dmic_automute(codec);
9795 /* mute/unmute internal speaker according to the hp jack and mute state */
9796 static void alc262_hippo_automute(struct hda_codec *codec)
9798 struct alc_spec *spec = codec->spec;
9800 unsigned int present;
9802 /* need to execute and sync at first */
9803 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9804 present = snd_hda_codec_read(codec, 0x15, 0,
9805 AC_VERB_GET_PIN_SENSE, 0);
9806 spec->jack_present = (present & 0x80000000) != 0;
9807 if (spec->jack_present) {
9808 /* mute internal speaker */
9809 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9810 HDA_AMP_MUTE, HDA_AMP_MUTE);
9812 /* unmute internal speaker if necessary */
9813 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9814 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9815 HDA_AMP_MUTE, mute);
9819 /* unsolicited event for HP jack sensing */
9820 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9823 if ((res >> 26) != ALC880_HP_EVENT)
9825 alc262_hippo_automute(codec);
9828 static void alc262_hippo1_automute(struct hda_codec *codec)
9831 unsigned int present;
9833 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9834 present = snd_hda_codec_read(codec, 0x1b, 0,
9835 AC_VERB_GET_PIN_SENSE, 0);
9836 present = (present & 0x80000000) != 0;
9838 /* mute internal speaker */
9839 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9840 HDA_AMP_MUTE, HDA_AMP_MUTE);
9842 /* unmute internal speaker if necessary */
9843 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9844 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9845 HDA_AMP_MUTE, mute);
9849 /* unsolicited event for HP jack sensing */
9850 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9853 if ((res >> 26) != ALC880_HP_EVENT)
9855 alc262_hippo1_automute(codec);
9861 * 0x16 = internal speaker
9862 * 0x18 = external mic
9865 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9866 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9867 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9871 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9873 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9874 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9878 static struct hda_verb alc262_nec_verbs[] = {
9879 /* Unmute Speaker */
9880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9883 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9886 /* External mic to headphone */
9887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9888 /* External mic to speaker */
9889 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9895 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9896 * 0x1b = port replicator headphone out
9899 #define ALC_HP_EVENT 0x37
9901 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9902 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9903 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9904 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9905 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9909 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9910 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9911 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9915 static struct hda_input_mux alc262_fujitsu_capture_source = {
9924 static struct hda_input_mux alc262_HP_capture_source = {
9928 { "Front Mic", 0x1 },
9935 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9939 { "Front Mic", 0x2 },
9945 /* mute/unmute internal speaker according to the hp jacks and mute state */
9946 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9948 struct alc_spec *spec = codec->spec;
9951 if (force || !spec->sense_updated) {
9952 unsigned int present;
9953 /* need to execute and sync at first */
9954 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9955 /* check laptop HP jack */
9956 present = snd_hda_codec_read(codec, 0x14, 0,
9957 AC_VERB_GET_PIN_SENSE, 0);
9958 /* need to execute and sync at first */
9959 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9960 /* check docking HP jack */
9961 present |= snd_hda_codec_read(codec, 0x1b, 0,
9962 AC_VERB_GET_PIN_SENSE, 0);
9963 if (present & AC_PINSENSE_PRESENCE)
9964 spec->jack_present = 1;
9966 spec->jack_present = 0;
9967 spec->sense_updated = 1;
9969 /* unmute internal speaker only if both HPs are unplugged and
9970 * master switch is on
9972 if (spec->jack_present)
9973 mute = HDA_AMP_MUTE;
9975 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9976 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9977 HDA_AMP_MUTE, mute);
9980 /* unsolicited event for HP jack sensing */
9981 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9984 if ((res >> 26) != ALC_HP_EVENT)
9986 alc262_fujitsu_automute(codec, 1);
9989 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9991 alc262_fujitsu_automute(codec, 1);
9994 /* bind volumes of both NID 0x0c and 0x0d */
9995 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9996 .ops = &snd_hda_bind_vol,
9998 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9999 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10004 /* mute/unmute internal speaker according to the hp jack and mute state */
10005 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10007 struct alc_spec *spec = codec->spec;
10010 if (force || !spec->sense_updated) {
10011 unsigned int present_int_hp;
10012 /* need to execute and sync at first */
10013 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10014 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10015 AC_VERB_GET_PIN_SENSE, 0);
10016 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10017 spec->sense_updated = 1;
10019 if (spec->jack_present) {
10020 /* mute internal speaker */
10021 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10022 HDA_AMP_MUTE, HDA_AMP_MUTE);
10023 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10024 HDA_AMP_MUTE, HDA_AMP_MUTE);
10026 /* unmute internal speaker if necessary */
10027 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10028 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10029 HDA_AMP_MUTE, mute);
10030 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10031 HDA_AMP_MUTE, mute);
10035 /* unsolicited event for HP jack sensing */
10036 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10039 if ((res >> 26) != ALC_HP_EVENT)
10041 alc262_lenovo_3000_automute(codec, 1);
10044 /* bind hp and internal speaker mute (with plug check) */
10045 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10046 struct snd_ctl_elem_value *ucontrol)
10048 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10049 long *valp = ucontrol->value.integer.value;
10052 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10054 valp ? 0 : HDA_AMP_MUTE);
10055 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10057 valp ? 0 : HDA_AMP_MUTE);
10060 alc262_fujitsu_automute(codec, 0);
10064 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10065 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10068 .name = "Master Playback Switch",
10069 .info = snd_hda_mixer_amp_switch_info,
10070 .get = snd_hda_mixer_amp_switch_get,
10071 .put = alc262_fujitsu_master_sw_put,
10072 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10074 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10075 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10076 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
10077 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
10078 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10080 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10081 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10082 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10083 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10087 /* bind hp and internal speaker mute (with plug check) */
10088 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10089 struct snd_ctl_elem_value *ucontrol)
10091 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10092 long *valp = ucontrol->value.integer.value;
10095 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10097 valp ? 0 : HDA_AMP_MUTE);
10100 alc262_lenovo_3000_automute(codec, 0);
10104 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10105 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10108 .name = "Master Playback Switch",
10109 .info = snd_hda_mixer_amp_switch_info,
10110 .get = snd_hda_mixer_amp_switch_get,
10111 .put = alc262_lenovo_3000_master_sw_put,
10112 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10114 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10115 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10116 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10119 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10120 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10121 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10125 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10126 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10129 .name = "Master Playback Switch",
10130 .info = snd_hda_mixer_amp_switch_info,
10131 .get = snd_hda_mixer_amp_switch_get,
10132 .put = alc262_sony_master_sw_put,
10133 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10135 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10136 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10137 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10138 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10139 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10140 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10144 /* additional init verbs for Benq laptops */
10145 static struct hda_verb alc262_EAPD_verbs[] = {
10146 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10147 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10151 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10152 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10153 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10155 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10156 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10160 /* Samsung Q1 Ultra Vista model setup */
10161 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10162 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10163 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10166 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10167 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10171 static struct hda_verb alc262_ultra_verbs[] = {
10173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10178 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10179 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10180 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10183 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10184 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10185 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10186 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10188 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10189 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10190 /* ADC, choose mic */
10191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10195 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10197 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10204 /* mute/unmute internal speaker according to the hp jack and mute state */
10205 static void alc262_ultra_automute(struct hda_codec *codec)
10207 struct alc_spec *spec = codec->spec;
10211 /* auto-mute only when HP is used as HP */
10212 if (!spec->cur_mux[0]) {
10213 unsigned int present;
10214 /* need to execute and sync at first */
10215 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10216 present = snd_hda_codec_read(codec, 0x15, 0,
10217 AC_VERB_GET_PIN_SENSE, 0);
10218 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10219 if (spec->jack_present)
10220 mute = HDA_AMP_MUTE;
10222 /* mute/unmute internal speaker */
10223 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10224 HDA_AMP_MUTE, mute);
10225 /* mute/unmute HP */
10226 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10227 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10230 /* unsolicited event for HP jack sensing */
10231 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10234 if ((res >> 26) != ALC880_HP_EVENT)
10236 alc262_ultra_automute(codec);
10239 static struct hda_input_mux alc262_ultra_capture_source = {
10243 { "Headphone", 0x7 },
10247 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10248 struct snd_ctl_elem_value *ucontrol)
10250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10251 struct alc_spec *spec = codec->spec;
10254 ret = alc_mux_enum_put(kcontrol, ucontrol);
10257 /* reprogram the HP pin as mic or HP according to the input source */
10258 snd_hda_codec_write_cache(codec, 0x15, 0,
10259 AC_VERB_SET_PIN_WIDGET_CONTROL,
10260 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10261 alc262_ultra_automute(codec); /* mute/unmute HP */
10265 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10266 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10267 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10270 .name = "Capture Source",
10271 .info = alc_mux_enum_info,
10272 .get = alc_mux_enum_get,
10273 .put = alc262_ultra_mux_enum_put,
10278 /* add playback controls from the parsed DAC table */
10279 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10280 const struct auto_pin_cfg *cfg)
10285 spec->multiout.num_dacs = 1; /* only use one dac */
10286 spec->multiout.dac_nids = spec->private_dac_nids;
10287 spec->multiout.dac_nids[0] = 2;
10289 nid = cfg->line_out_pins[0];
10291 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10292 "Front Playback Volume",
10293 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10296 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10297 "Front Playback Switch",
10298 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10303 nid = cfg->speaker_pins[0];
10306 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10307 "Speaker Playback Volume",
10308 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10312 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10313 "Speaker Playback Switch",
10314 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10319 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10320 "Speaker Playback Switch",
10321 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10327 nid = cfg->hp_pins[0];
10329 /* spec->multiout.hp_nid = 2; */
10331 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10332 "Headphone Playback Volume",
10333 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10337 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10338 "Headphone Playback Switch",
10339 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10344 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10345 "Headphone Playback Switch",
10346 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10355 /* identical with ALC880 */
10356 #define alc262_auto_create_analog_input_ctls \
10357 alc880_auto_create_analog_input_ctls
10360 * generic initialization of ADC, input mixers and output mixers
10362 static struct hda_verb alc262_volume_init_verbs[] = {
10364 * Unmute ADC0-2 and set the default input to mic-in
10366 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10368 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10369 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10370 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10371 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10373 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10375 * Note: PASD motherboards uses the Line In 2 as the input for
10376 * front panel mic (mic 2)
10378 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10382 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10386 * Set up output mixers (0x0c - 0x0f)
10388 /* set vol=0 to output mixers */
10389 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10390 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10391 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10393 /* set up input amps for analog loopback */
10394 /* Amp Indices: DAC = 0, mixer = 1 */
10395 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10398 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10399 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10402 /* FIXME: use matrix-type input source selection */
10403 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10404 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10407 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10410 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10411 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10412 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10416 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10417 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10423 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10425 * Unmute ADC0-2 and set the default input to mic-in
10427 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10429 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10431 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10434 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10436 * Note: PASD motherboards uses the Line In 2 as the input for
10437 * front panel mic (mic 2)
10439 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10440 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10441 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10442 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10443 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10449 * Set up output mixers (0x0c - 0x0e)
10451 /* set vol=0 to output mixers */
10452 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10454 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10456 /* set up input amps for analog loopback */
10457 /* Amp Indices: DAC = 0, mixer = 1 */
10458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10461 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10463 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10465 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10467 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10469 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10472 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10473 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10475 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10479 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10482 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10483 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10485 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10486 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10489 /* FIXME: use matrix-type input source selection */
10490 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10491 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10497 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10498 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10499 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10500 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10502 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10503 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10507 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10512 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10514 * Unmute ADC0-2 and set the default input to mic-in
10516 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10518 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10519 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10520 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10521 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10523 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10525 * Note: PASD motherboards uses the Line In 2 as the input for front
10526 * panel mic (mic 2)
10528 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10533 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10534 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10535 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10536 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10538 * Set up output mixers (0x0c - 0x0e)
10540 /* set vol=0 to output mixers */
10541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10543 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10545 /* set up input amps for analog loopback */
10546 /* Amp Indices: DAC = 0, mixer = 1 */
10547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10548 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10556 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10557 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10558 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10559 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10560 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10561 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10563 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10566 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10567 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10569 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10571 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10573 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10574 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10576 /* FIXME: use matrix-type input source selection */
10577 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10578 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10580 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10581 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10582 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10583 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10584 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10585 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10587 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10588 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10592 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10595 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10600 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10603 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10608 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10611 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10612 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10616 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10617 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10619 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10620 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10621 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10626 #ifdef CONFIG_SND_HDA_POWER_SAVE
10627 #define alc262_loopbacks alc880_loopbacks
10630 /* pcm configuration: identiacal with ALC880 */
10631 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10632 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10633 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10634 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10637 * BIOS auto configuration
10639 static int alc262_parse_auto_config(struct hda_codec *codec)
10641 struct alc_spec *spec = codec->spec;
10643 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10645 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10649 if (!spec->autocfg.line_outs) {
10650 if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
10651 spec->multiout.max_channels = 2;
10652 spec->no_analog = 1;
10655 return 0; /* can't find valid BIOS pin config */
10657 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10660 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10664 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10667 if (spec->autocfg.dig_out_pin) {
10668 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10669 spec->dig_out_type = spec->autocfg.dig_out_type;
10671 if (spec->autocfg.dig_in_pin)
10672 spec->dig_in_nid = ALC262_DIGIN_NID;
10674 if (spec->kctls.list)
10675 add_mixer(spec, spec->kctls.list);
10677 add_verb(spec, alc262_volume_init_verbs);
10678 spec->num_mux_defs = 1;
10679 spec->input_mux = &spec->private_imux[0];
10681 err = alc_auto_add_mic_boost(codec);
10685 store_pin_configs(codec);
10689 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10690 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10691 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10692 #define alc262_auto_init_input_src alc882_auto_init_input_src
10695 /* init callback for auto-configuration model -- overriding the default init */
10696 static void alc262_auto_init(struct hda_codec *codec)
10698 struct alc_spec *spec = codec->spec;
10699 alc262_auto_init_multi_out(codec);
10700 alc262_auto_init_hp_out(codec);
10701 alc262_auto_init_analog_input(codec);
10702 alc262_auto_init_input_src(codec);
10703 if (spec->unsol_event)
10704 alc_inithook(codec);
10708 * configuration and preset
10710 static const char *alc262_models[ALC262_MODEL_LAST] = {
10711 [ALC262_BASIC] = "basic",
10712 [ALC262_HIPPO] = "hippo",
10713 [ALC262_HIPPO_1] = "hippo_1",
10714 [ALC262_FUJITSU] = "fujitsu",
10715 [ALC262_HP_BPC] = "hp-bpc",
10716 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10717 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10718 [ALC262_HP_RP5700] = "hp-rp5700",
10719 [ALC262_BENQ_ED8] = "benq",
10720 [ALC262_BENQ_T31] = "benq-t31",
10721 [ALC262_SONY_ASSAMD] = "sony-assamd",
10722 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10723 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10724 [ALC262_ULTRA] = "ultra",
10725 [ALC262_LENOVO_3000] = "lenovo-3000",
10726 [ALC262_NEC] = "nec",
10727 [ALC262_TYAN] = "tyan",
10728 [ALC262_AUTO] = "auto",
10731 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10732 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10733 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10734 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10735 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10736 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10737 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10738 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10739 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10740 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10741 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10742 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10743 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10744 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10745 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10746 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10747 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10748 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10749 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10750 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10751 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10752 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10753 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10754 ALC262_HP_TC_T5735),
10755 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10756 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10757 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10758 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10759 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10760 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10761 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10762 ALC262_SONY_ASSAMD),
10763 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10764 ALC262_TOSHIBA_RX1),
10765 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10766 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10767 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10768 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10769 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10770 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10771 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10772 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10773 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10774 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10775 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10779 static struct alc_config_preset alc262_presets[] = {
10781 .mixers = { alc262_base_mixer },
10782 .init_verbs = { alc262_init_verbs },
10783 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10784 .dac_nids = alc262_dac_nids,
10786 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10787 .channel_mode = alc262_modes,
10788 .input_mux = &alc262_capture_source,
10791 .mixers = { alc262_base_mixer },
10792 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10793 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10794 .dac_nids = alc262_dac_nids,
10796 .dig_out_nid = ALC262_DIGOUT_NID,
10797 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10798 .channel_mode = alc262_modes,
10799 .input_mux = &alc262_capture_source,
10800 .unsol_event = alc262_hippo_unsol_event,
10801 .init_hook = alc262_hippo_automute,
10803 [ALC262_HIPPO_1] = {
10804 .mixers = { alc262_hippo1_mixer },
10805 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10806 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10807 .dac_nids = alc262_dac_nids,
10809 .dig_out_nid = ALC262_DIGOUT_NID,
10810 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10811 .channel_mode = alc262_modes,
10812 .input_mux = &alc262_capture_source,
10813 .unsol_event = alc262_hippo1_unsol_event,
10814 .init_hook = alc262_hippo1_automute,
10816 [ALC262_FUJITSU] = {
10817 .mixers = { alc262_fujitsu_mixer },
10818 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10819 alc262_fujitsu_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_fujitsu_capture_source,
10827 .unsol_event = alc262_fujitsu_unsol_event,
10828 .init_hook = alc262_fujitsu_init_hook,
10830 [ALC262_HP_BPC] = {
10831 .mixers = { alc262_HP_BPC_mixer },
10832 .init_verbs = { alc262_HP_BPC_init_verbs },
10833 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10834 .dac_nids = alc262_dac_nids,
10836 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10837 .channel_mode = alc262_modes,
10838 .input_mux = &alc262_HP_capture_source,
10839 .unsol_event = alc262_hp_bpc_unsol_event,
10840 .init_hook = alc262_hp_bpc_automute,
10842 [ALC262_HP_BPC_D7000_WF] = {
10843 .mixers = { alc262_HP_BPC_WildWest_mixer },
10844 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10845 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10846 .dac_nids = alc262_dac_nids,
10848 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10849 .channel_mode = alc262_modes,
10850 .input_mux = &alc262_HP_D7000_capture_source,
10851 .unsol_event = alc262_hp_wildwest_unsol_event,
10852 .init_hook = alc262_hp_wildwest_automute,
10854 [ALC262_HP_BPC_D7000_WL] = {
10855 .mixers = { alc262_HP_BPC_WildWest_mixer,
10856 alc262_HP_BPC_WildWest_option_mixer },
10857 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10858 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10859 .dac_nids = alc262_dac_nids,
10861 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10862 .channel_mode = alc262_modes,
10863 .input_mux = &alc262_HP_D7000_capture_source,
10864 .unsol_event = alc262_hp_wildwest_unsol_event,
10865 .init_hook = alc262_hp_wildwest_automute,
10867 [ALC262_HP_TC_T5735] = {
10868 .mixers = { alc262_hp_t5735_mixer },
10869 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10870 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10871 .dac_nids = alc262_dac_nids,
10873 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10874 .channel_mode = alc262_modes,
10875 .input_mux = &alc262_capture_source,
10876 .unsol_event = alc262_hp_t5735_unsol_event,
10877 .init_hook = alc262_hp_t5735_init_hook,
10879 [ALC262_HP_RP5700] = {
10880 .mixers = { alc262_hp_rp5700_mixer },
10881 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10882 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10883 .dac_nids = alc262_dac_nids,
10884 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10885 .channel_mode = alc262_modes,
10886 .input_mux = &alc262_hp_rp5700_capture_source,
10888 [ALC262_BENQ_ED8] = {
10889 .mixers = { alc262_base_mixer },
10890 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10891 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10892 .dac_nids = alc262_dac_nids,
10894 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10895 .channel_mode = alc262_modes,
10896 .input_mux = &alc262_capture_source,
10898 [ALC262_SONY_ASSAMD] = {
10899 .mixers = { alc262_sony_mixer },
10900 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10901 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10902 .dac_nids = alc262_dac_nids,
10904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10905 .channel_mode = alc262_modes,
10906 .input_mux = &alc262_capture_source,
10907 .unsol_event = alc262_hippo_unsol_event,
10908 .init_hook = alc262_hippo_automute,
10910 [ALC262_BENQ_T31] = {
10911 .mixers = { alc262_benq_t31_mixer },
10912 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10913 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10914 .dac_nids = alc262_dac_nids,
10916 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10917 .channel_mode = alc262_modes,
10918 .input_mux = &alc262_capture_source,
10919 .unsol_event = alc262_hippo_unsol_event,
10920 .init_hook = alc262_hippo_automute,
10923 .mixers = { alc262_ultra_mixer },
10924 .cap_mixer = alc262_ultra_capture_mixer,
10925 .init_verbs = { alc262_ultra_verbs },
10926 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10927 .dac_nids = alc262_dac_nids,
10928 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10929 .channel_mode = alc262_modes,
10930 .input_mux = &alc262_ultra_capture_source,
10931 .adc_nids = alc262_adc_nids, /* ADC0 */
10932 .capsrc_nids = alc262_capsrc_nids,
10933 .num_adc_nids = 1, /* single ADC */
10934 .unsol_event = alc262_ultra_unsol_event,
10935 .init_hook = alc262_ultra_automute,
10937 [ALC262_LENOVO_3000] = {
10938 .mixers = { alc262_lenovo_3000_mixer },
10939 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10940 alc262_lenovo_3000_unsol_verbs },
10941 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10942 .dac_nids = alc262_dac_nids,
10944 .dig_out_nid = ALC262_DIGOUT_NID,
10945 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10946 .channel_mode = alc262_modes,
10947 .input_mux = &alc262_fujitsu_capture_source,
10948 .unsol_event = alc262_lenovo_3000_unsol_event,
10951 .mixers = { alc262_nec_mixer },
10952 .init_verbs = { alc262_nec_verbs },
10953 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10954 .dac_nids = alc262_dac_nids,
10956 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10957 .channel_mode = alc262_modes,
10958 .input_mux = &alc262_capture_source,
10960 [ALC262_TOSHIBA_S06] = {
10961 .mixers = { alc262_toshiba_s06_mixer },
10962 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10963 alc262_eapd_verbs },
10964 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10965 .capsrc_nids = alc262_dmic_capsrc_nids,
10966 .dac_nids = alc262_dac_nids,
10967 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10968 .dig_out_nid = ALC262_DIGOUT_NID,
10969 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10970 .channel_mode = alc262_modes,
10971 .input_mux = &alc262_dmic_capture_source,
10972 .unsol_event = alc262_toshiba_s06_unsol_event,
10973 .init_hook = alc262_toshiba_s06_init_hook,
10975 [ALC262_TOSHIBA_RX1] = {
10976 .mixers = { alc262_toshiba_rx1_mixer },
10977 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10978 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10979 .dac_nids = alc262_dac_nids,
10981 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10982 .channel_mode = alc262_modes,
10983 .input_mux = &alc262_capture_source,
10984 .unsol_event = alc262_hippo_unsol_event,
10985 .init_hook = alc262_hippo_automute,
10988 .mixers = { alc262_tyan_mixer },
10989 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
10990 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10991 .dac_nids = alc262_dac_nids,
10993 .dig_out_nid = ALC262_DIGOUT_NID,
10994 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10995 .channel_mode = alc262_modes,
10996 .input_mux = &alc262_capture_source,
10997 .unsol_event = alc262_tyan_unsol_event,
10998 .init_hook = alc262_tyan_automute,
11002 static int patch_alc262(struct hda_codec *codec)
11004 struct alc_spec *spec;
11008 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11012 codec->spec = spec;
11014 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11019 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11020 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11021 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11022 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11026 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11028 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11032 if (board_config < 0) {
11033 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11034 "trying auto-probe from BIOS...\n");
11035 board_config = ALC262_AUTO;
11038 if (board_config == ALC262_AUTO) {
11039 /* automatic parse from the BIOS config */
11040 err = alc262_parse_auto_config(codec);
11046 "hda_codec: Cannot set up configuration "
11047 "from BIOS. Using base mode...\n");
11048 board_config = ALC262_BASIC;
11052 err = snd_hda_attach_beep_device(codec, 0x1);
11058 if (board_config != ALC262_AUTO)
11059 setup_preset(spec, &alc262_presets[board_config]);
11061 spec->stream_name_analog = "ALC262 Analog";
11062 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11063 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11065 spec->stream_name_digital = "ALC262 Digital";
11066 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11067 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11069 spec->capture_style = CAPT_MIX;
11070 if (!spec->adc_nids && spec->input_mux) {
11071 /* check whether NID 0x07 is valid */
11072 unsigned int wcap = get_wcaps(codec, 0x07);
11075 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11076 if (wcap != AC_WID_AUD_IN) {
11077 spec->adc_nids = alc262_adc_nids_alt;
11078 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11079 spec->capsrc_nids = alc262_capsrc_nids_alt;
11081 spec->adc_nids = alc262_adc_nids;
11082 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11083 spec->capsrc_nids = alc262_capsrc_nids;
11086 if (!spec->cap_mixer && !spec->no_analog)
11087 set_capture_mixer(spec);
11089 spec->vmaster_nid = 0x0c;
11091 codec->patch_ops = alc_patch_ops;
11092 if (board_config == ALC262_AUTO)
11093 spec->init_hook = alc262_auto_init;
11094 #ifdef CONFIG_SND_HDA_POWER_SAVE
11095 if (!spec->loopback.amplist)
11096 spec->loopback.amplist = alc262_loopbacks;
11098 codec->proc_widget_hook = print_realtek_coef;
11104 * ALC268 channel source setting (2 channel)
11106 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11107 #define alc268_modes alc260_modes
11109 static hda_nid_t alc268_dac_nids[2] = {
11114 static hda_nid_t alc268_adc_nids[2] = {
11119 static hda_nid_t alc268_adc_nids_alt[1] = {
11124 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11126 static struct snd_kcontrol_new alc268_base_mixer[] = {
11127 /* output mixer control */
11128 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11129 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11130 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11132 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11133 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11134 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11138 /* bind Beep switches of both NID 0x0f and 0x10 */
11139 static struct hda_bind_ctls alc268_bind_beep_sw = {
11140 .ops = &snd_hda_bind_sw,
11142 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11143 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11148 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11149 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11150 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11154 static struct hda_verb alc268_eapd_verbs[] = {
11155 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11156 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11160 /* Toshiba specific */
11161 #define alc268_toshiba_automute alc262_hippo_automute
11163 static struct hda_verb alc268_toshiba_verbs[] = {
11164 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11168 static struct hda_input_mux alc268_acer_lc_capture_source = {
11176 /* Acer specific */
11177 /* bind volumes of both NID 0x02 and 0x03 */
11178 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11179 .ops = &snd_hda_bind_vol,
11181 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11182 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11187 /* mute/unmute internal speaker according to the hp jack and mute state */
11188 static void alc268_acer_automute(struct hda_codec *codec, int force)
11190 struct alc_spec *spec = codec->spec;
11193 if (force || !spec->sense_updated) {
11194 unsigned int present;
11195 present = snd_hda_codec_read(codec, 0x14, 0,
11196 AC_VERB_GET_PIN_SENSE, 0);
11197 spec->jack_present = (present & 0x80000000) != 0;
11198 spec->sense_updated = 1;
11200 if (spec->jack_present)
11201 mute = HDA_AMP_MUTE; /* mute internal speaker */
11202 else /* unmute internal speaker if necessary */
11203 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11204 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11205 HDA_AMP_MUTE, mute);
11209 /* bind hp and internal speaker mute (with plug check) */
11210 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11211 struct snd_ctl_elem_value *ucontrol)
11213 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11214 long *valp = ucontrol->value.integer.value;
11217 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11219 valp[0] ? 0 : HDA_AMP_MUTE);
11220 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11222 valp[1] ? 0 : HDA_AMP_MUTE);
11224 alc268_acer_automute(codec, 0);
11228 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11229 /* output mixer control */
11230 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11233 .name = "Master Playback Switch",
11234 .info = snd_hda_mixer_amp_switch_info,
11235 .get = snd_hda_mixer_amp_switch_get,
11236 .put = alc268_acer_master_sw_put,
11237 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11239 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11243 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11244 /* output mixer control */
11245 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11248 .name = "Master Playback Switch",
11249 .info = snd_hda_mixer_amp_switch_info,
11250 .get = snd_hda_mixer_amp_switch_get,
11251 .put = alc268_acer_master_sw_put,
11252 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11255 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11256 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11260 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11261 /* output mixer control */
11262 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11265 .name = "Master Playback Switch",
11266 .info = snd_hda_mixer_amp_switch_info,
11267 .get = snd_hda_mixer_amp_switch_get,
11268 .put = alc268_acer_master_sw_put,
11269 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11271 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11272 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11276 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11277 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11279 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11280 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11281 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11282 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11286 static struct hda_verb alc268_acer_verbs[] = {
11287 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11288 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11291 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11292 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11293 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11297 /* unsolicited event for HP jack sensing */
11298 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11301 if ((res >> 26) != ALC880_HP_EVENT)
11303 alc268_toshiba_automute(codec);
11306 static void alc268_acer_unsol_event(struct hda_codec *codec,
11309 if ((res >> 26) != ALC880_HP_EVENT)
11311 alc268_acer_automute(codec, 1);
11314 static void alc268_acer_init_hook(struct hda_codec *codec)
11316 alc268_acer_automute(codec, 1);
11319 /* toggle speaker-output according to the hp-jack state */
11320 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11322 unsigned int present;
11323 unsigned char bits;
11325 present = snd_hda_codec_read(codec, 0x15, 0,
11326 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11327 bits = present ? AMP_IN_MUTE(0) : 0;
11328 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11329 AMP_IN_MUTE(0), bits);
11330 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11331 AMP_IN_MUTE(0), bits);
11335 static void alc268_acer_mic_automute(struct hda_codec *codec)
11337 unsigned int present;
11339 present = snd_hda_codec_read(codec, 0x18, 0,
11340 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11341 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11342 present ? 0x0 : 0x6);
11345 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11348 if ((res >> 26) == ALC880_HP_EVENT)
11349 alc268_aspire_one_speaker_automute(codec);
11350 if ((res >> 26) == ALC880_MIC_EVENT)
11351 alc268_acer_mic_automute(codec);
11354 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11356 alc268_aspire_one_speaker_automute(codec);
11357 alc268_acer_mic_automute(codec);
11360 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11361 /* output mixer control */
11362 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11364 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11366 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11367 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11371 static struct hda_verb alc268_dell_verbs[] = {
11372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11378 /* mute/unmute internal speaker according to the hp jack and mute state */
11379 static void alc268_dell_automute(struct hda_codec *codec)
11381 unsigned int present;
11384 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11385 if (present & 0x80000000)
11386 mute = HDA_AMP_MUTE;
11388 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11389 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11390 HDA_AMP_MUTE, mute);
11393 static void alc268_dell_unsol_event(struct hda_codec *codec,
11396 if ((res >> 26) != ALC880_HP_EVENT)
11398 alc268_dell_automute(codec);
11401 #define alc268_dell_init_hook alc268_dell_automute
11403 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11404 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11405 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11406 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11407 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11408 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11409 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11410 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11411 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11415 static struct hda_verb alc267_quanta_il1_verbs[] = {
11416 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11417 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11421 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11423 unsigned int present;
11425 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11426 & AC_PINSENSE_PRESENCE;
11427 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11428 present ? 0 : PIN_OUT);
11431 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11433 unsigned int present;
11435 present = snd_hda_codec_read(codec, 0x18, 0,
11436 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11437 snd_hda_codec_write(codec, 0x23, 0,
11438 AC_VERB_SET_CONNECT_SEL,
11439 present ? 0x00 : 0x01);
11442 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11444 alc267_quanta_il1_hp_automute(codec);
11445 alc267_quanta_il1_mic_automute(codec);
11448 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11451 switch (res >> 26) {
11452 case ALC880_HP_EVENT:
11453 alc267_quanta_il1_hp_automute(codec);
11455 case ALC880_MIC_EVENT:
11456 alc267_quanta_il1_mic_automute(codec);
11462 * generic initialization of ADC, input mixers and output mixers
11464 static struct hda_verb alc268_base_init_verbs[] = {
11465 /* Unmute DAC0-1 and set vol = 0 */
11466 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11467 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11470 * Set up output mixers (0x0c - 0x0e)
11472 /* set vol=0 to output mixers */
11473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11474 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11476 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11477 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11481 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11482 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11484 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11485 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11486 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11490 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11492 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11494 /* set PCBEEP vol = 0, mute connections */
11495 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11496 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11497 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11499 /* Unmute Selector 23h,24h and set the default input to mic-in */
11501 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11502 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11503 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11504 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11510 * generic initialization of ADC, input mixers and output mixers
11512 static struct hda_verb alc268_volume_init_verbs[] = {
11513 /* set output DAC */
11514 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11515 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11517 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11518 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11519 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11521 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11524 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11525 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11528 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11530 /* set PCBEEP vol = 0, mute connections */
11531 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11532 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11533 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11538 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11539 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11540 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11543 /* The multiple "Capture Source" controls confuse alsamixer
11544 * So call somewhat different..
11546 /* .name = "Capture Source", */
11547 .name = "Input Source",
11549 .info = alc_mux_enum_info,
11550 .get = alc_mux_enum_get,
11551 .put = alc_mux_enum_put,
11556 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11557 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11559 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11560 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11562 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11563 /* The multiple "Capture Source" controls confuse alsamixer
11564 * So call somewhat different..
11566 /* .name = "Capture Source", */
11567 .name = "Input Source",
11569 .info = alc_mux_enum_info,
11570 .get = alc_mux_enum_get,
11571 .put = alc_mux_enum_put,
11576 static struct hda_input_mux alc268_capture_source = {
11580 { "Front Mic", 0x1 },
11586 static struct hda_input_mux alc268_acer_capture_source = {
11590 { "Internal Mic", 0x1 },
11595 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11599 { "Internal Mic", 0x6 },
11604 #ifdef CONFIG_SND_DEBUG
11605 static struct snd_kcontrol_new alc268_test_mixer[] = {
11606 /* Volume widgets */
11607 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11608 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11609 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11610 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11611 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11612 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11613 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11614 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11615 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11616 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11617 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11618 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11619 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11620 /* The below appears problematic on some hardwares */
11621 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11622 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11623 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11624 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11625 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11627 /* Modes for retasking pin widgets */
11628 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11629 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11630 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11631 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11633 /* Controls for GPIO pins, assuming they are configured as outputs */
11634 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11635 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11636 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11637 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11639 /* Switches to allow the digital SPDIF output pin to be enabled.
11640 * The ALC268 does not have an SPDIF input.
11642 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11644 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11645 * this output to turn on an external amplifier.
11647 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11648 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11654 /* create input playback/capture controls for the given pin */
11655 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11656 const char *ctlname, int idx)
11661 sprintf(name, "%s Playback Volume", ctlname);
11663 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11664 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11668 } else if (nid == 0x15) {
11669 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11670 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11676 sprintf(name, "%s Playback Switch", ctlname);
11677 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11678 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11684 /* add playback controls from the parsed DAC table */
11685 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11686 const struct auto_pin_cfg *cfg)
11691 spec->multiout.num_dacs = 2; /* only use one dac */
11692 spec->multiout.dac_nids = spec->private_dac_nids;
11693 spec->multiout.dac_nids[0] = 2;
11694 spec->multiout.dac_nids[1] = 3;
11696 nid = cfg->line_out_pins[0];
11698 alc268_new_analog_output(spec, nid, "Front", 0);
11700 nid = cfg->speaker_pins[0];
11702 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11703 "Speaker Playback Volume",
11704 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11708 nid = cfg->hp_pins[0];
11710 alc268_new_analog_output(spec, nid, "Headphone", 0);
11712 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11714 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11715 "Mono Playback Switch",
11716 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11723 /* create playback/capture controls for input pins */
11724 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11725 const struct auto_pin_cfg *cfg)
11727 struct hda_input_mux *imux = &spec->private_imux[0];
11730 for (i = 0; i < AUTO_PIN_LAST; i++) {
11731 switch(cfg->input_pins[i]) {
11733 idx1 = 0; /* Mic 1 */
11736 idx1 = 1; /* Mic 2 */
11739 idx1 = 2; /* Line In */
11746 idx1 = 6; /* digital mics */
11751 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11752 imux->items[imux->num_items].index = idx1;
11758 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11760 struct alc_spec *spec = codec->spec;
11761 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11762 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11763 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11764 unsigned int dac_vol1, dac_vol2;
11767 snd_hda_codec_write(codec, speaker_nid, 0,
11768 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11769 snd_hda_codec_write(codec, 0x0f, 0,
11770 AC_VERB_SET_AMP_GAIN_MUTE,
11772 snd_hda_codec_write(codec, 0x10, 0,
11773 AC_VERB_SET_AMP_GAIN_MUTE,
11776 snd_hda_codec_write(codec, 0x0f, 0,
11777 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11778 snd_hda_codec_write(codec, 0x10, 0,
11779 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11782 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11783 if (line_nid == 0x14)
11784 dac_vol2 = AMP_OUT_ZERO;
11785 else if (line_nid == 0x15)
11786 dac_vol1 = AMP_OUT_ZERO;
11787 if (hp_nid == 0x14)
11788 dac_vol2 = AMP_OUT_ZERO;
11789 else if (hp_nid == 0x15)
11790 dac_vol1 = AMP_OUT_ZERO;
11791 if (line_nid != 0x16 || hp_nid != 0x16 ||
11792 spec->autocfg.line_out_pins[1] != 0x16 ||
11793 spec->autocfg.line_out_pins[2] != 0x16)
11794 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11796 snd_hda_codec_write(codec, 0x02, 0,
11797 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11798 snd_hda_codec_write(codec, 0x03, 0,
11799 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11802 /* pcm configuration: identiacal with ALC880 */
11803 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11804 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11805 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11806 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11809 * BIOS auto configuration
11811 static int alc268_parse_auto_config(struct hda_codec *codec)
11813 struct alc_spec *spec = codec->spec;
11815 static hda_nid_t alc268_ignore[] = { 0 };
11817 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11821 if (!spec->autocfg.line_outs)
11822 return 0; /* can't find valid BIOS pin config */
11824 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11827 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11831 spec->multiout.max_channels = 2;
11833 /* digital only support output */
11834 if (spec->autocfg.dig_out_pin)
11835 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11837 if (spec->kctls.list)
11838 add_mixer(spec, spec->kctls.list);
11840 if (spec->autocfg.speaker_pins[0] != 0x1d)
11841 add_mixer(spec, alc268_beep_mixer);
11843 add_verb(spec, alc268_volume_init_verbs);
11844 spec->num_mux_defs = 1;
11845 spec->input_mux = &spec->private_imux[0];
11847 err = alc_auto_add_mic_boost(codec);
11851 store_pin_configs(codec);
11855 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11856 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11857 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11859 /* init callback for auto-configuration model -- overriding the default init */
11860 static void alc268_auto_init(struct hda_codec *codec)
11862 struct alc_spec *spec = codec->spec;
11863 alc268_auto_init_multi_out(codec);
11864 alc268_auto_init_hp_out(codec);
11865 alc268_auto_init_mono_speaker_out(codec);
11866 alc268_auto_init_analog_input(codec);
11867 if (spec->unsol_event)
11868 alc_inithook(codec);
11872 * configuration and preset
11874 static const char *alc268_models[ALC268_MODEL_LAST] = {
11875 [ALC267_QUANTA_IL1] = "quanta-il1",
11876 [ALC268_3ST] = "3stack",
11877 [ALC268_TOSHIBA] = "toshiba",
11878 [ALC268_ACER] = "acer",
11879 [ALC268_ACER_DMIC] = "acer-dmic",
11880 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11881 [ALC268_DELL] = "dell",
11882 [ALC268_ZEPTO] = "zepto",
11883 #ifdef CONFIG_SND_DEBUG
11884 [ALC268_TEST] = "test",
11886 [ALC268_AUTO] = "auto",
11889 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11890 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11891 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11892 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11893 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11894 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11895 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11896 ALC268_ACER_ASPIRE_ONE),
11897 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11898 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
11899 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11900 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11901 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11902 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11903 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11904 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11905 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11906 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11907 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11911 static struct alc_config_preset alc268_presets[] = {
11912 [ALC267_QUANTA_IL1] = {
11913 .mixers = { alc267_quanta_il1_mixer },
11914 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11915 alc267_quanta_il1_verbs },
11916 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11917 .dac_nids = alc268_dac_nids,
11918 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11919 .adc_nids = alc268_adc_nids_alt,
11921 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11922 .channel_mode = alc268_modes,
11923 .input_mux = &alc268_capture_source,
11924 .unsol_event = alc267_quanta_il1_unsol_event,
11925 .init_hook = alc267_quanta_il1_automute,
11928 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11929 alc268_beep_mixer },
11930 .init_verbs = { alc268_base_init_verbs },
11931 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11932 .dac_nids = alc268_dac_nids,
11933 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11934 .adc_nids = alc268_adc_nids_alt,
11935 .capsrc_nids = alc268_capsrc_nids,
11937 .dig_out_nid = ALC268_DIGOUT_NID,
11938 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11939 .channel_mode = alc268_modes,
11940 .input_mux = &alc268_capture_source,
11942 [ALC268_TOSHIBA] = {
11943 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11944 alc268_beep_mixer },
11945 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11946 alc268_toshiba_verbs },
11947 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11948 .dac_nids = alc268_dac_nids,
11949 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11950 .adc_nids = alc268_adc_nids_alt,
11951 .capsrc_nids = alc268_capsrc_nids,
11953 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11954 .channel_mode = alc268_modes,
11955 .input_mux = &alc268_capture_source,
11956 .unsol_event = alc268_toshiba_unsol_event,
11957 .init_hook = alc268_toshiba_automute,
11960 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11961 alc268_beep_mixer },
11962 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11963 alc268_acer_verbs },
11964 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11965 .dac_nids = alc268_dac_nids,
11966 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11967 .adc_nids = alc268_adc_nids_alt,
11968 .capsrc_nids = alc268_capsrc_nids,
11970 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11971 .channel_mode = alc268_modes,
11972 .input_mux = &alc268_acer_capture_source,
11973 .unsol_event = alc268_acer_unsol_event,
11974 .init_hook = alc268_acer_init_hook,
11976 [ALC268_ACER_DMIC] = {
11977 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11978 alc268_beep_mixer },
11979 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11980 alc268_acer_verbs },
11981 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11982 .dac_nids = alc268_dac_nids,
11983 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11984 .adc_nids = alc268_adc_nids_alt,
11985 .capsrc_nids = alc268_capsrc_nids,
11987 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11988 .channel_mode = alc268_modes,
11989 .input_mux = &alc268_acer_dmic_capture_source,
11990 .unsol_event = alc268_acer_unsol_event,
11991 .init_hook = alc268_acer_init_hook,
11993 [ALC268_ACER_ASPIRE_ONE] = {
11994 .mixers = { alc268_acer_aspire_one_mixer,
11995 alc268_capture_alt_mixer },
11996 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11997 alc268_acer_aspire_one_verbs },
11998 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11999 .dac_nids = alc268_dac_nids,
12000 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12001 .adc_nids = alc268_adc_nids_alt,
12002 .capsrc_nids = alc268_capsrc_nids,
12004 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12005 .channel_mode = alc268_modes,
12006 .input_mux = &alc268_acer_lc_capture_source,
12007 .unsol_event = alc268_acer_lc_unsol_event,
12008 .init_hook = alc268_acer_lc_init_hook,
12011 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12012 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12013 alc268_dell_verbs },
12014 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12015 .dac_nids = alc268_dac_nids,
12017 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12018 .channel_mode = alc268_modes,
12019 .unsol_event = alc268_dell_unsol_event,
12020 .init_hook = alc268_dell_init_hook,
12021 .input_mux = &alc268_capture_source,
12024 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12025 alc268_beep_mixer },
12026 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12027 alc268_toshiba_verbs },
12028 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12029 .dac_nids = alc268_dac_nids,
12030 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12031 .adc_nids = alc268_adc_nids_alt,
12032 .capsrc_nids = alc268_capsrc_nids,
12034 .dig_out_nid = ALC268_DIGOUT_NID,
12035 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12036 .channel_mode = alc268_modes,
12037 .input_mux = &alc268_capture_source,
12038 .unsol_event = alc268_toshiba_unsol_event,
12039 .init_hook = alc268_toshiba_automute
12041 #ifdef CONFIG_SND_DEBUG
12043 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12044 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12045 alc268_volume_init_verbs },
12046 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12047 .dac_nids = alc268_dac_nids,
12048 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12049 .adc_nids = alc268_adc_nids_alt,
12050 .capsrc_nids = alc268_capsrc_nids,
12052 .dig_out_nid = ALC268_DIGOUT_NID,
12053 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12054 .channel_mode = alc268_modes,
12055 .input_mux = &alc268_capture_source,
12060 static int patch_alc268(struct hda_codec *codec)
12062 struct alc_spec *spec;
12066 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12070 codec->spec = spec;
12072 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12076 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12077 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12078 "trying auto-probe from BIOS...\n");
12079 board_config = ALC268_AUTO;
12082 if (board_config == ALC268_AUTO) {
12083 /* automatic parse from the BIOS config */
12084 err = alc268_parse_auto_config(codec);
12090 "hda_codec: Cannot set up configuration "
12091 "from BIOS. Using base mode...\n");
12092 board_config = ALC268_3ST;
12096 err = snd_hda_attach_beep_device(codec, 0x1);
12102 if (board_config != ALC268_AUTO)
12103 setup_preset(spec, &alc268_presets[board_config]);
12105 if (codec->vendor_id == 0x10ec0267) {
12106 spec->stream_name_analog = "ALC267 Analog";
12107 spec->stream_name_digital = "ALC267 Digital";
12109 spec->stream_name_analog = "ALC268 Analog";
12110 spec->stream_name_digital = "ALC268 Digital";
12113 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12114 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12115 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12117 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12119 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12120 /* override the amp caps for beep generator */
12121 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12122 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12123 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12124 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12125 (0 << AC_AMPCAP_MUTE_SHIFT));
12127 if (!spec->adc_nids && spec->input_mux) {
12128 /* check whether NID 0x07 is valid */
12129 unsigned int wcap = get_wcaps(codec, 0x07);
12133 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12134 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12135 spec->adc_nids = alc268_adc_nids_alt;
12136 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12137 add_mixer(spec, alc268_capture_alt_mixer);
12139 spec->adc_nids = alc268_adc_nids;
12140 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12141 add_mixer(spec, alc268_capture_mixer);
12143 spec->capsrc_nids = alc268_capsrc_nids;
12144 /* set default input source */
12145 for (i = 0; i < spec->num_adc_nids; i++)
12146 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12147 0, AC_VERB_SET_CONNECT_SEL,
12148 spec->input_mux->items[0].index);
12151 spec->vmaster_nid = 0x02;
12153 codec->patch_ops = alc_patch_ops;
12154 if (board_config == ALC268_AUTO)
12155 spec->init_hook = alc268_auto_init;
12157 codec->proc_widget_hook = print_realtek_coef;
12163 * ALC269 channel source setting (2 channel)
12165 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12167 #define alc269_dac_nids alc260_dac_nids
12169 static hda_nid_t alc269_adc_nids[1] = {
12174 static hda_nid_t alc269_capsrc_nids[1] = {
12178 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12182 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12190 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12198 #define alc269_modes alc260_modes
12199 #define alc269_capture_source alc880_lg_lw_capture_source
12201 static struct snd_kcontrol_new alc269_base_mixer[] = {
12202 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12203 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12204 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12205 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12207 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12208 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
12209 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
12210 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12211 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12212 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12213 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12214 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12215 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12219 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12220 /* output mixer control */
12221 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12223 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12224 .name = "Master Playback Switch",
12225 .info = snd_hda_mixer_amp_switch_info,
12226 .get = snd_hda_mixer_amp_switch_get,
12227 .put = alc268_acer_master_sw_put,
12228 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12232 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12233 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12234 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12235 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12236 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12237 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12241 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12242 /* output mixer control */
12243 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12246 .name = "Master Playback Switch",
12247 .info = snd_hda_mixer_amp_switch_info,
12248 .get = snd_hda_mixer_amp_switch_get,
12249 .put = alc268_acer_master_sw_put,
12250 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12254 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12255 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12256 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12257 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12258 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12259 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12260 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12261 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12262 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12266 /* bind volumes of both NID 0x0c and 0x0d */
12267 static struct hda_bind_ctls alc269_epc_bind_vol = {
12268 .ops = &snd_hda_bind_vol,
12270 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12271 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12276 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12277 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12278 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12279 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12283 /* capture mixer elements */
12284 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12285 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12286 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12287 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12292 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12294 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12295 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12300 static struct snd_kcontrol_new alc269_beep_mixer[] = {
12301 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
12302 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
12306 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12308 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12309 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12310 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12311 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12312 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12316 static struct hda_verb alc269_lifebook_verbs[] = {
12317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12318 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12319 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12320 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12321 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12322 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12323 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12324 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12325 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12326 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12330 /* toggle speaker-output according to the hp-jack state */
12331 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12333 unsigned int present;
12334 unsigned char bits;
12336 present = snd_hda_codec_read(codec, 0x15, 0,
12337 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12338 bits = present ? AMP_IN_MUTE(0) : 0;
12339 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12340 AMP_IN_MUTE(0), bits);
12341 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12342 AMP_IN_MUTE(0), bits);
12344 snd_hda_codec_write(codec, 0x20, 0,
12345 AC_VERB_SET_COEF_INDEX, 0x0c);
12346 snd_hda_codec_write(codec, 0x20, 0,
12347 AC_VERB_SET_PROC_COEF, 0x680);
12349 snd_hda_codec_write(codec, 0x20, 0,
12350 AC_VERB_SET_COEF_INDEX, 0x0c);
12351 snd_hda_codec_write(codec, 0x20, 0,
12352 AC_VERB_SET_PROC_COEF, 0x480);
12355 /* toggle speaker-output according to the hp-jacks state */
12356 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12358 unsigned int present;
12359 unsigned char bits;
12361 /* Check laptop headphone socket */
12362 present = snd_hda_codec_read(codec, 0x15, 0,
12363 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12365 /* Check port replicator headphone socket */
12366 present |= snd_hda_codec_read(codec, 0x1a, 0,
12367 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12369 bits = present ? AMP_IN_MUTE(0) : 0;
12370 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12371 AMP_IN_MUTE(0), bits);
12372 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12373 AMP_IN_MUTE(0), bits);
12375 snd_hda_codec_write(codec, 0x20, 0,
12376 AC_VERB_SET_COEF_INDEX, 0x0c);
12377 snd_hda_codec_write(codec, 0x20, 0,
12378 AC_VERB_SET_PROC_COEF, 0x680);
12380 snd_hda_codec_write(codec, 0x20, 0,
12381 AC_VERB_SET_COEF_INDEX, 0x0c);
12382 snd_hda_codec_write(codec, 0x20, 0,
12383 AC_VERB_SET_PROC_COEF, 0x480);
12386 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12388 unsigned int present;
12390 present = snd_hda_codec_read(codec, 0x18, 0,
12391 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12392 snd_hda_codec_write(codec, 0x23, 0,
12393 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12396 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12398 unsigned int present_laptop;
12399 unsigned int present_dock;
12401 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12402 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12404 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12405 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12407 /* Laptop mic port overrides dock mic port, design decision */
12409 snd_hda_codec_write(codec, 0x23, 0,
12410 AC_VERB_SET_CONNECT_SEL, 0x3);
12411 if (present_laptop)
12412 snd_hda_codec_write(codec, 0x23, 0,
12413 AC_VERB_SET_CONNECT_SEL, 0x0);
12414 if (!present_dock && !present_laptop)
12415 snd_hda_codec_write(codec, 0x23, 0,
12416 AC_VERB_SET_CONNECT_SEL, 0x1);
12419 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12422 if ((res >> 26) == ALC880_HP_EVENT)
12423 alc269_quanta_fl1_speaker_automute(codec);
12424 if ((res >> 26) == ALC880_MIC_EVENT)
12425 alc269_quanta_fl1_mic_automute(codec);
12428 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12431 if ((res >> 26) == ALC880_HP_EVENT)
12432 alc269_lifebook_speaker_automute(codec);
12433 if ((res >> 26) == ALC880_MIC_EVENT)
12434 alc269_lifebook_mic_autoswitch(codec);
12437 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12439 alc269_quanta_fl1_speaker_automute(codec);
12440 alc269_quanta_fl1_mic_automute(codec);
12443 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12445 alc269_lifebook_speaker_automute(codec);
12446 alc269_lifebook_mic_autoswitch(codec);
12449 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12450 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12451 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12453 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12454 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12455 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12460 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12462 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12463 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12466 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12470 /* toggle speaker-output according to the hp-jack state */
12471 static void alc269_speaker_automute(struct hda_codec *codec)
12473 unsigned int present;
12474 unsigned char bits;
12476 present = snd_hda_codec_read(codec, 0x15, 0,
12477 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12478 bits = present ? AMP_IN_MUTE(0) : 0;
12479 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12480 AMP_IN_MUTE(0), bits);
12481 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12482 AMP_IN_MUTE(0), bits);
12485 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12487 unsigned int present;
12489 present = snd_hda_codec_read(codec, 0x18, 0,
12490 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12491 snd_hda_codec_write(codec, 0x23, 0,
12492 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12495 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12497 unsigned int present;
12499 present = snd_hda_codec_read(codec, 0x18, 0,
12500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12501 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12502 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12503 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12504 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12507 /* unsolicited event for HP jack sensing */
12508 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12511 if ((res >> 26) == ALC880_HP_EVENT)
12512 alc269_speaker_automute(codec);
12514 if ((res >> 26) == ALC880_MIC_EVENT)
12515 alc269_eeepc_dmic_automute(codec);
12518 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12520 alc269_speaker_automute(codec);
12521 alc269_eeepc_dmic_automute(codec);
12524 /* unsolicited event for HP jack sensing */
12525 static void alc269_eeepc_amic_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_amic_automute(codec);
12535 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12537 alc269_speaker_automute(codec);
12538 alc269_eeepc_amic_automute(codec);
12542 * generic initialization of ADC, input mixers and output mixers
12544 static struct hda_verb alc269_init_verbs[] = {
12546 * Unmute ADC0 and set the default input to mic-in
12548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12550 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12551 * analog-loopback mixer widget
12552 * Note: PASD motherboards uses the Line In 2 as the input for
12553 * front panel mic (mic 2)
12555 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12563 * Set up output mixers (0x0c - 0x0e)
12565 /* set vol=0 to output mixers */
12566 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12567 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12569 /* set up input amps for analog loopback */
12570 /* Amp Indices: DAC = 0, mixer = 1 */
12571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12578 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12580 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12582 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12587 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12588 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12589 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12590 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12591 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12594 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12597 /* FIXME: use matrix-type input source selection */
12598 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12599 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12600 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12606 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12607 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12611 /* add playback controls from the parsed DAC table */
12612 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12613 const struct auto_pin_cfg *cfg)
12618 spec->multiout.num_dacs = 1; /* only use one dac */
12619 spec->multiout.dac_nids = spec->private_dac_nids;
12620 spec->multiout.dac_nids[0] = 2;
12622 nid = cfg->line_out_pins[0];
12624 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12625 "Front Playback Volume",
12626 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12629 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12630 "Front Playback Switch",
12631 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12636 nid = cfg->speaker_pins[0];
12638 if (!cfg->line_out_pins[0]) {
12639 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12640 "Speaker Playback Volume",
12641 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12647 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12648 "Speaker Playback Switch",
12649 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12654 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12655 "Speaker Playback Switch",
12656 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12662 nid = cfg->hp_pins[0];
12664 /* spec->multiout.hp_nid = 2; */
12665 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12666 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12667 "Headphone Playback Volume",
12668 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12674 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12675 "Headphone Playback Switch",
12676 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12681 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12682 "Headphone Playback Switch",
12683 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12692 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12693 const struct auto_pin_cfg *cfg)
12697 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12700 /* digital-mic input pin is excluded in alc880_auto_create..()
12701 * because it's under 0x18
12703 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12704 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12705 struct hda_input_mux *imux = &spec->private_imux[0];
12706 imux->items[imux->num_items].label = "Int Mic";
12707 imux->items[imux->num_items].index = 0x05;
12713 #ifdef CONFIG_SND_HDA_POWER_SAVE
12714 #define alc269_loopbacks alc880_loopbacks
12717 /* pcm configuration: identiacal with ALC880 */
12718 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12719 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12720 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12721 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12724 * BIOS auto configuration
12726 static int alc269_parse_auto_config(struct hda_codec *codec)
12728 struct alc_spec *spec = codec->spec;
12730 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12732 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12737 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12740 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12744 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12746 if (spec->autocfg.dig_out_pin)
12747 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12749 if (spec->kctls.list)
12750 add_mixer(spec, spec->kctls.list);
12752 /* create a beep mixer control if the pin 0x1d isn't assigned */
12753 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12754 if (spec->autocfg.input_pins[i] == 0x1d)
12756 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12757 add_mixer(spec, alc269_beep_mixer);
12759 add_verb(spec, alc269_init_verbs);
12760 spec->num_mux_defs = 1;
12761 spec->input_mux = &spec->private_imux[0];
12762 /* set default input source */
12763 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12764 0, AC_VERB_SET_CONNECT_SEL,
12765 spec->input_mux->items[0].index);
12767 err = alc_auto_add_mic_boost(codec);
12771 if (!spec->cap_mixer)
12772 set_capture_mixer(spec);
12774 store_pin_configs(codec);
12778 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12779 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12780 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12783 /* init callback for auto-configuration model -- overriding the default init */
12784 static void alc269_auto_init(struct hda_codec *codec)
12786 struct alc_spec *spec = codec->spec;
12787 alc269_auto_init_multi_out(codec);
12788 alc269_auto_init_hp_out(codec);
12789 alc269_auto_init_analog_input(codec);
12790 if (spec->unsol_event)
12791 alc_inithook(codec);
12795 * configuration and preset
12797 static const char *alc269_models[ALC269_MODEL_LAST] = {
12798 [ALC269_BASIC] = "basic",
12799 [ALC269_QUANTA_FL1] = "quanta",
12800 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12801 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12802 [ALC269_FUJITSU] = "fujitsu",
12803 [ALC269_LIFEBOOK] = "lifebook"
12806 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12807 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12808 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12809 ALC269_ASUS_EEEPC_P703),
12810 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12811 ALC269_ASUS_EEEPC_P901),
12812 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12813 ALC269_ASUS_EEEPC_P901),
12814 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12815 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12819 static struct alc_config_preset alc269_presets[] = {
12821 .mixers = { alc269_base_mixer },
12822 .init_verbs = { alc269_init_verbs },
12823 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12824 .dac_nids = alc269_dac_nids,
12826 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12827 .channel_mode = alc269_modes,
12828 .input_mux = &alc269_capture_source,
12830 [ALC269_QUANTA_FL1] = {
12831 .mixers = { alc269_quanta_fl1_mixer },
12832 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12833 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12834 .dac_nids = alc269_dac_nids,
12836 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12837 .channel_mode = alc269_modes,
12838 .input_mux = &alc269_capture_source,
12839 .unsol_event = alc269_quanta_fl1_unsol_event,
12840 .init_hook = alc269_quanta_fl1_init_hook,
12842 [ALC269_ASUS_EEEPC_P703] = {
12843 .mixers = { alc269_eeepc_mixer },
12844 .cap_mixer = alc269_epc_capture_mixer,
12845 .init_verbs = { alc269_init_verbs,
12846 alc269_eeepc_amic_init_verbs },
12847 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12848 .dac_nids = alc269_dac_nids,
12850 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12851 .channel_mode = alc269_modes,
12852 .input_mux = &alc269_eeepc_amic_capture_source,
12853 .unsol_event = alc269_eeepc_amic_unsol_event,
12854 .init_hook = alc269_eeepc_amic_inithook,
12856 [ALC269_ASUS_EEEPC_P901] = {
12857 .mixers = { alc269_eeepc_mixer },
12858 .cap_mixer = alc269_epc_capture_mixer,
12859 .init_verbs = { alc269_init_verbs,
12860 alc269_eeepc_dmic_init_verbs },
12861 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12862 .dac_nids = alc269_dac_nids,
12864 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12865 .channel_mode = alc269_modes,
12866 .input_mux = &alc269_eeepc_dmic_capture_source,
12867 .unsol_event = alc269_eeepc_dmic_unsol_event,
12868 .init_hook = alc269_eeepc_dmic_inithook,
12870 [ALC269_FUJITSU] = {
12871 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12872 .cap_mixer = alc269_epc_capture_mixer,
12873 .init_verbs = { alc269_init_verbs,
12874 alc269_eeepc_dmic_init_verbs },
12875 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12876 .dac_nids = alc269_dac_nids,
12878 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12879 .channel_mode = alc269_modes,
12880 .input_mux = &alc269_eeepc_dmic_capture_source,
12881 .unsol_event = alc269_eeepc_dmic_unsol_event,
12882 .init_hook = alc269_eeepc_dmic_inithook,
12884 [ALC269_LIFEBOOK] = {
12885 .mixers = { alc269_lifebook_mixer },
12886 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12887 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12888 .dac_nids = alc269_dac_nids,
12890 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12891 .channel_mode = alc269_modes,
12892 .input_mux = &alc269_capture_source,
12893 .unsol_event = alc269_lifebook_unsol_event,
12894 .init_hook = alc269_lifebook_init_hook,
12898 static int patch_alc269(struct hda_codec *codec)
12900 struct alc_spec *spec;
12904 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12908 codec->spec = spec;
12910 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12912 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12916 if (board_config < 0) {
12917 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12918 "trying auto-probe from BIOS...\n");
12919 board_config = ALC269_AUTO;
12922 if (board_config == ALC269_AUTO) {
12923 /* automatic parse from the BIOS config */
12924 err = alc269_parse_auto_config(codec);
12930 "hda_codec: Cannot set up configuration "
12931 "from BIOS. Using base mode...\n");
12932 board_config = ALC269_BASIC;
12936 err = snd_hda_attach_beep_device(codec, 0x1);
12942 if (board_config != ALC269_AUTO)
12943 setup_preset(spec, &alc269_presets[board_config]);
12945 spec->stream_name_analog = "ALC269 Analog";
12946 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12947 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12949 spec->stream_name_digital = "ALC269 Digital";
12950 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12951 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12953 spec->adc_nids = alc269_adc_nids;
12954 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12955 spec->capsrc_nids = alc269_capsrc_nids;
12956 if (!spec->cap_mixer)
12957 set_capture_mixer(spec);
12959 codec->patch_ops = alc_patch_ops;
12960 if (board_config == ALC269_AUTO)
12961 spec->init_hook = alc269_auto_init;
12962 #ifdef CONFIG_SND_HDA_POWER_SAVE
12963 if (!spec->loopback.amplist)
12964 spec->loopback.amplist = alc269_loopbacks;
12966 codec->proc_widget_hook = print_realtek_coef;
12972 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12976 * set the path ways for 2 channel output
12977 * need to set the codec line out and mic 1 pin widgets to inputs
12979 static struct hda_verb alc861_threestack_ch2_init[] = {
12980 /* set pin widget 1Ah (line in) for input */
12981 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12982 /* set pin widget 18h (mic1/2) for input, for mic also enable
12985 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12987 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12989 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12990 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12996 * need to set the codec line out and mic 1 pin widgets to outputs
12998 static struct hda_verb alc861_threestack_ch6_init[] = {
12999 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13000 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13001 /* set pin widget 18h (mic1) for output (CLFE)*/
13002 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13004 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13005 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13007 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13009 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13010 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13015 static struct hda_channel_mode alc861_threestack_modes[2] = {
13016 { 2, alc861_threestack_ch2_init },
13017 { 6, alc861_threestack_ch6_init },
13019 /* Set mic1 as input and unmute the mixer */
13020 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13021 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13022 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13025 /* Set mic1 as output and mute mixer */
13026 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13027 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13028 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13032 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13033 { 2, alc861_uniwill_m31_ch2_init },
13034 { 4, alc861_uniwill_m31_ch4_init },
13037 /* Set mic1 and line-in as input and unmute the mixer */
13038 static struct hda_verb alc861_asus_ch2_init[] = {
13039 /* set pin widget 1Ah (line in) for input */
13040 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13041 /* set pin widget 18h (mic1/2) for input, for mic also enable
13044 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13046 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13048 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13049 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13053 /* Set mic1 nad line-in as output and mute mixer */
13054 static struct hda_verb alc861_asus_ch6_init[] = {
13055 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13056 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13057 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13058 /* set pin widget 18h (mic1) for output (CLFE)*/
13059 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13060 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13061 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13062 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13064 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13066 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13067 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13072 static struct hda_channel_mode alc861_asus_modes[2] = {
13073 { 2, alc861_asus_ch2_init },
13074 { 6, alc861_asus_ch6_init },
13079 static struct snd_kcontrol_new alc861_base_mixer[] = {
13080 /* output mixer control */
13081 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13082 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13083 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13084 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13085 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13087 /*Input mixer control */
13088 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13089 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13090 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13091 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13092 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13093 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13095 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13096 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13097 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13102 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13103 /* output mixer control */
13104 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13105 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13106 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13107 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13108 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13110 /* Input mixer control */
13111 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13112 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13113 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13114 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13115 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13116 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13118 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13119 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13124 .name = "Channel Mode",
13125 .info = alc_ch_mode_info,
13126 .get = alc_ch_mode_get,
13127 .put = alc_ch_mode_put,
13128 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13133 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13134 /* output mixer control */
13135 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13137 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13142 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13143 /* output mixer control */
13144 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13145 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13146 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13147 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13148 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13150 /* Input mixer control */
13151 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13152 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13153 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13154 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13155 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13156 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13158 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13159 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13164 .name = "Channel Mode",
13165 .info = alc_ch_mode_info,
13166 .get = alc_ch_mode_get,
13167 .put = alc_ch_mode_put,
13168 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13173 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13174 /* output mixer control */
13175 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13176 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13177 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13178 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13179 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13181 /* Input mixer control */
13182 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13183 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13184 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13185 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13186 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13187 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13189 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13190 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13191 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13195 .name = "Channel Mode",
13196 .info = alc_ch_mode_info,
13197 .get = alc_ch_mode_get,
13198 .put = alc_ch_mode_put,
13199 .private_value = ARRAY_SIZE(alc861_asus_modes),
13204 /* additional mixer */
13205 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13206 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13207 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13208 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
13209 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
13214 * generic initialization of ADC, input mixers and output mixers
13216 static struct hda_verb alc861_base_init_verbs[] = {
13218 * Unmute ADC0 and set the default input to mic-in
13220 /* port-A for surround (rear panel) */
13221 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13222 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13223 /* port-B for mic-in (rear panel) with vref */
13224 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13225 /* port-C for line-in (rear panel) */
13226 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13227 /* port-D for Front */
13228 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13229 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13230 /* port-E for HP out (front panel) */
13231 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13232 /* route front PCM to HP */
13233 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13234 /* port-F for mic-in (front panel) with vref */
13235 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13236 /* port-G for CLFE (rear panel) */
13237 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13238 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13239 /* port-H for side (rear panel) */
13240 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13241 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13243 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13244 /* route front mic to ADC1*/
13245 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13246 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13248 /* Unmute DAC0~3 & spdif out*/
13249 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13250 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13251 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13252 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13255 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13256 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13257 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13258 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13259 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13261 /* Unmute Stereo Mixer 15 */
13262 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13263 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13267 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13268 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13269 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13270 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13271 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13273 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13274 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13275 /* hp used DAC 3 (Front) */
13276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13277 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13282 static struct hda_verb alc861_threestack_init_verbs[] = {
13284 * Unmute ADC0 and set the default input to mic-in
13286 /* port-A for surround (rear panel) */
13287 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13288 /* port-B for mic-in (rear panel) with vref */
13289 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13290 /* port-C for line-in (rear panel) */
13291 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13292 /* port-D for Front */
13293 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13294 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13295 /* port-E for HP out (front panel) */
13296 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13297 /* route front PCM to HP */
13298 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13299 /* port-F for mic-in (front panel) with vref */
13300 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13301 /* port-G for CLFE (rear panel) */
13302 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13303 /* port-H for side (rear panel) */
13304 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13306 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13307 /* route front mic to ADC1*/
13308 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13310 /* Unmute DAC0~3 & spdif out*/
13311 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13312 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13313 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13314 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13315 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13317 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13318 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13319 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13320 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13321 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13323 /* Unmute Stereo Mixer 15 */
13324 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13330 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13331 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13332 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13333 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13335 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13336 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13337 /* hp used DAC 3 (Front) */
13338 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13343 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13345 * Unmute ADC0 and set the default input to mic-in
13347 /* port-A for surround (rear panel) */
13348 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13349 /* port-B for mic-in (rear panel) with vref */
13350 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13351 /* port-C for line-in (rear panel) */
13352 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13353 /* port-D for Front */
13354 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13355 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13356 /* port-E for HP out (front panel) */
13357 /* this has to be set to VREF80 */
13358 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13359 /* route front PCM to HP */
13360 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13361 /* port-F for mic-in (front panel) with vref */
13362 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13363 /* port-G for CLFE (rear panel) */
13364 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13365 /* port-H for side (rear panel) */
13366 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13368 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13369 /* route front mic to ADC1*/
13370 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13372 /* Unmute DAC0~3 & spdif out*/
13373 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13374 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13375 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13376 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13377 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13379 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13380 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13381 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13382 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13383 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13385 /* Unmute Stereo Mixer 15 */
13386 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13389 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13391 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13392 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13393 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13394 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13395 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13397 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13398 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13399 /* hp used DAC 3 (Front) */
13400 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13401 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13405 static struct hda_verb alc861_asus_init_verbs[] = {
13407 * Unmute ADC0 and set the default input to mic-in
13409 /* port-A for surround (rear panel)
13410 * according to codec#0 this is the HP jack
13412 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13413 /* route front PCM to HP */
13414 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13415 /* port-B for mic-in (rear panel) with vref */
13416 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13417 /* port-C for line-in (rear panel) */
13418 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13419 /* port-D for Front */
13420 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13421 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13422 /* port-E for HP out (front panel) */
13423 /* this has to be set to VREF80 */
13424 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13425 /* route front PCM to HP */
13426 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13427 /* port-F for mic-in (front panel) with vref */
13428 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13429 /* port-G for CLFE (rear panel) */
13430 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13431 /* port-H for side (rear panel) */
13432 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13434 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13435 /* route front mic to ADC1*/
13436 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13437 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438 /* Unmute DAC0~3 & spdif out*/
13439 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13440 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13441 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13442 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13444 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13445 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13446 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13447 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13450 /* Unmute Stereo Mixer 15 */
13451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13456 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13462 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13463 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13464 /* hp used DAC 3 (Front) */
13465 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13466 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13470 /* additional init verbs for ASUS laptops */
13471 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13472 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13473 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13478 * generic initialization of ADC, input mixers and output mixers
13480 static struct hda_verb alc861_auto_init_verbs[] = {
13482 * Unmute ADC0 and set the default input to mic-in
13484 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13487 /* Unmute DAC0~3 & spdif out*/
13488 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13489 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13490 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13491 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13492 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13494 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13495 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13496 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13497 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13498 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13500 /* Unmute Stereo Mixer 15 */
13501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13507 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13508 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13509 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13510 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13511 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13513 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13516 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13517 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13520 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13521 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13522 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13524 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13529 static struct hda_verb alc861_toshiba_init_verbs[] = {
13530 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13535 /* toggle speaker-output according to the hp-jack state */
13536 static void alc861_toshiba_automute(struct hda_codec *codec)
13538 unsigned int present;
13540 present = snd_hda_codec_read(codec, 0x0f, 0,
13541 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13542 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13543 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13544 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13545 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13548 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13551 if ((res >> 26) == ALC880_HP_EVENT)
13552 alc861_toshiba_automute(codec);
13555 /* pcm configuration: identiacal with ALC880 */
13556 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13557 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13558 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13559 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13562 #define ALC861_DIGOUT_NID 0x07
13564 static struct hda_channel_mode alc861_8ch_modes[1] = {
13568 static hda_nid_t alc861_dac_nids[4] = {
13569 /* front, surround, clfe, side */
13570 0x03, 0x06, 0x05, 0x04
13573 static hda_nid_t alc660_dac_nids[3] = {
13574 /* front, clfe, surround */
13578 static hda_nid_t alc861_adc_nids[1] = {
13583 static struct hda_input_mux alc861_capture_source = {
13587 { "Front Mic", 0x3 },
13594 /* fill in the dac_nids table from the parsed pin configuration */
13595 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13596 const struct auto_pin_cfg *cfg)
13601 spec->multiout.dac_nids = spec->private_dac_nids;
13602 for (i = 0; i < cfg->line_outs; i++) {
13603 nid = cfg->line_out_pins[i];
13605 if (i >= ARRAY_SIZE(alc861_dac_nids))
13607 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13610 spec->multiout.num_dacs = cfg->line_outs;
13614 /* add playback controls from the parsed DAC table */
13615 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13616 const struct auto_pin_cfg *cfg)
13619 static const char *chname[4] = {
13620 "Front", "Surround", NULL /*CLFE*/, "Side"
13625 for (i = 0; i < cfg->line_outs; i++) {
13626 nid = spec->multiout.dac_nids[i];
13631 err = add_control(spec, ALC_CTL_BIND_MUTE,
13632 "Center Playback Switch",
13633 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13637 err = add_control(spec, ALC_CTL_BIND_MUTE,
13638 "LFE Playback Switch",
13639 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13644 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13646 if (nid == alc861_dac_nids[idx])
13648 sprintf(name, "%s Playback Switch", chname[idx]);
13649 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13650 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13659 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13667 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13669 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13670 "Headphone Playback Switch",
13671 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13674 spec->multiout.hp_nid = nid;
13679 /* create playback/capture controls for input pins */
13680 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13681 const struct auto_pin_cfg *cfg)
13683 struct hda_input_mux *imux = &spec->private_imux[0];
13684 int i, err, idx, idx1;
13686 for (i = 0; i < AUTO_PIN_LAST; i++) {
13687 switch (cfg->input_pins[i]) {
13690 idx = 2; /* Line In */
13694 idx = 2; /* Line In */
13698 idx = 1; /* Mic In */
13702 idx = 1; /* Mic In */
13712 err = new_analog_input(spec, cfg->input_pins[i],
13713 auto_pin_cfg_labels[i], idx, 0x15);
13717 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13718 imux->items[imux->num_items].index = idx1;
13724 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13726 int pin_type, int dac_idx)
13728 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13730 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13734 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13736 struct alc_spec *spec = codec->spec;
13739 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13740 for (i = 0; i < spec->autocfg.line_outs; i++) {
13741 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13742 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13744 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13745 spec->multiout.dac_nids[i]);
13749 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13751 struct alc_spec *spec = codec->spec;
13754 pin = spec->autocfg.hp_pins[0];
13755 if (pin) /* connect to front */
13756 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13757 spec->multiout.dac_nids[0]);
13758 pin = spec->autocfg.speaker_pins[0];
13760 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13763 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13765 struct alc_spec *spec = codec->spec;
13768 for (i = 0; i < AUTO_PIN_LAST; i++) {
13769 hda_nid_t nid = spec->autocfg.input_pins[i];
13770 if (nid >= 0x0c && nid <= 0x11) {
13771 snd_hda_codec_write(codec, nid, 0,
13772 AC_VERB_SET_PIN_WIDGET_CONTROL,
13773 i <= AUTO_PIN_FRONT_MIC ?
13774 PIN_VREF80 : PIN_IN);
13779 /* parse the BIOS configuration and set up the alc_spec */
13780 /* return 1 if successful, 0 if the proper config is not found,
13781 * or a negative error code
13783 static int alc861_parse_auto_config(struct hda_codec *codec)
13785 struct alc_spec *spec = codec->spec;
13787 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13789 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13793 if (!spec->autocfg.line_outs)
13794 return 0; /* can't find valid BIOS pin config */
13796 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13799 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13802 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13805 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13809 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13811 if (spec->autocfg.dig_out_pin)
13812 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13814 if (spec->kctls.list)
13815 add_mixer(spec, spec->kctls.list);
13817 add_verb(spec, alc861_auto_init_verbs);
13819 spec->num_mux_defs = 1;
13820 spec->input_mux = &spec->private_imux[0];
13822 spec->adc_nids = alc861_adc_nids;
13823 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13824 set_capture_mixer(spec);
13826 store_pin_configs(codec);
13830 /* additional initialization for auto-configuration model */
13831 static void alc861_auto_init(struct hda_codec *codec)
13833 struct alc_spec *spec = codec->spec;
13834 alc861_auto_init_multi_out(codec);
13835 alc861_auto_init_hp_out(codec);
13836 alc861_auto_init_analog_input(codec);
13837 if (spec->unsol_event)
13838 alc_inithook(codec);
13841 #ifdef CONFIG_SND_HDA_POWER_SAVE
13842 static struct hda_amp_list alc861_loopbacks[] = {
13843 { 0x15, HDA_INPUT, 0 },
13844 { 0x15, HDA_INPUT, 1 },
13845 { 0x15, HDA_INPUT, 2 },
13846 { 0x15, HDA_INPUT, 3 },
13853 * configuration and preset
13855 static const char *alc861_models[ALC861_MODEL_LAST] = {
13856 [ALC861_3ST] = "3stack",
13857 [ALC660_3ST] = "3stack-660",
13858 [ALC861_3ST_DIG] = "3stack-dig",
13859 [ALC861_6ST_DIG] = "6stack-dig",
13860 [ALC861_UNIWILL_M31] = "uniwill-m31",
13861 [ALC861_TOSHIBA] = "toshiba",
13862 [ALC861_ASUS] = "asus",
13863 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13864 [ALC861_AUTO] = "auto",
13867 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13868 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13869 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13870 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13871 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13872 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13873 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13874 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13875 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13876 * Any other models that need this preset?
13878 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13879 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13880 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13881 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13882 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13883 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13884 /* FIXME: the below seems conflict */
13885 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13886 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13887 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13891 static struct alc_config_preset alc861_presets[] = {
13893 .mixers = { alc861_3ST_mixer },
13894 .init_verbs = { alc861_threestack_init_verbs },
13895 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13896 .dac_nids = alc861_dac_nids,
13897 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13898 .channel_mode = alc861_threestack_modes,
13900 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13901 .adc_nids = alc861_adc_nids,
13902 .input_mux = &alc861_capture_source,
13904 [ALC861_3ST_DIG] = {
13905 .mixers = { alc861_base_mixer },
13906 .init_verbs = { alc861_threestack_init_verbs },
13907 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13908 .dac_nids = alc861_dac_nids,
13909 .dig_out_nid = ALC861_DIGOUT_NID,
13910 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13911 .channel_mode = alc861_threestack_modes,
13913 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13914 .adc_nids = alc861_adc_nids,
13915 .input_mux = &alc861_capture_source,
13917 [ALC861_6ST_DIG] = {
13918 .mixers = { alc861_base_mixer },
13919 .init_verbs = { alc861_base_init_verbs },
13920 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13921 .dac_nids = alc861_dac_nids,
13922 .dig_out_nid = ALC861_DIGOUT_NID,
13923 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13924 .channel_mode = alc861_8ch_modes,
13925 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13926 .adc_nids = alc861_adc_nids,
13927 .input_mux = &alc861_capture_source,
13930 .mixers = { alc861_3ST_mixer },
13931 .init_verbs = { alc861_threestack_init_verbs },
13932 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13933 .dac_nids = alc660_dac_nids,
13934 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13935 .channel_mode = alc861_threestack_modes,
13937 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13938 .adc_nids = alc861_adc_nids,
13939 .input_mux = &alc861_capture_source,
13941 [ALC861_UNIWILL_M31] = {
13942 .mixers = { alc861_uniwill_m31_mixer },
13943 .init_verbs = { alc861_uniwill_m31_init_verbs },
13944 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13945 .dac_nids = alc861_dac_nids,
13946 .dig_out_nid = ALC861_DIGOUT_NID,
13947 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13948 .channel_mode = alc861_uniwill_m31_modes,
13950 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13951 .adc_nids = alc861_adc_nids,
13952 .input_mux = &alc861_capture_source,
13954 [ALC861_TOSHIBA] = {
13955 .mixers = { alc861_toshiba_mixer },
13956 .init_verbs = { alc861_base_init_verbs,
13957 alc861_toshiba_init_verbs },
13958 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13959 .dac_nids = alc861_dac_nids,
13960 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13961 .channel_mode = alc883_3ST_2ch_modes,
13962 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13963 .adc_nids = alc861_adc_nids,
13964 .input_mux = &alc861_capture_source,
13965 .unsol_event = alc861_toshiba_unsol_event,
13966 .init_hook = alc861_toshiba_automute,
13969 .mixers = { alc861_asus_mixer },
13970 .init_verbs = { alc861_asus_init_verbs },
13971 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13972 .dac_nids = alc861_dac_nids,
13973 .dig_out_nid = ALC861_DIGOUT_NID,
13974 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13975 .channel_mode = alc861_asus_modes,
13978 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13979 .adc_nids = alc861_adc_nids,
13980 .input_mux = &alc861_capture_source,
13982 [ALC861_ASUS_LAPTOP] = {
13983 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13984 .init_verbs = { alc861_asus_init_verbs,
13985 alc861_asus_laptop_init_verbs },
13986 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13987 .dac_nids = alc861_dac_nids,
13988 .dig_out_nid = ALC861_DIGOUT_NID,
13989 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13990 .channel_mode = alc883_3ST_2ch_modes,
13992 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13993 .adc_nids = alc861_adc_nids,
13994 .input_mux = &alc861_capture_source,
13999 static int patch_alc861(struct hda_codec *codec)
14001 struct alc_spec *spec;
14005 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14009 codec->spec = spec;
14011 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14015 if (board_config < 0) {
14016 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14017 "trying auto-probe from BIOS...\n");
14018 board_config = ALC861_AUTO;
14021 if (board_config == ALC861_AUTO) {
14022 /* automatic parse from the BIOS config */
14023 err = alc861_parse_auto_config(codec);
14029 "hda_codec: Cannot set up configuration "
14030 "from BIOS. Using base mode...\n");
14031 board_config = ALC861_3ST_DIG;
14035 err = snd_hda_attach_beep_device(codec, 0x23);
14041 if (board_config != ALC861_AUTO)
14042 setup_preset(spec, &alc861_presets[board_config]);
14044 spec->stream_name_analog = "ALC861 Analog";
14045 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14046 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14048 spec->stream_name_digital = "ALC861 Digital";
14049 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14050 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14052 spec->vmaster_nid = 0x03;
14054 codec->patch_ops = alc_patch_ops;
14055 if (board_config == ALC861_AUTO)
14056 spec->init_hook = alc861_auto_init;
14057 #ifdef CONFIG_SND_HDA_POWER_SAVE
14058 if (!spec->loopback.amplist)
14059 spec->loopback.amplist = alc861_loopbacks;
14061 codec->proc_widget_hook = print_realtek_coef;
14067 * ALC861-VD support
14071 * In addition, an independent DAC
14073 #define ALC861VD_DIGOUT_NID 0x06
14075 static hda_nid_t alc861vd_dac_nids[4] = {
14076 /* front, surr, clfe, side surr */
14077 0x02, 0x03, 0x04, 0x05
14080 /* dac_nids for ALC660vd are in a different order - according to
14081 * Realtek's driver.
14082 * This should probably tesult in a different mixer for 6stack models
14083 * of ALC660vd codecs, but for now there is only 3stack mixer
14084 * - and it is the same as in 861vd.
14085 * adc_nids in ALC660vd are (is) the same as in 861vd
14087 static hda_nid_t alc660vd_dac_nids[3] = {
14088 /* front, rear, clfe, rear_surr */
14092 static hda_nid_t alc861vd_adc_nids[1] = {
14097 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14100 /* FIXME: should be a matrix-type input source selection */
14101 static struct hda_input_mux alc861vd_capture_source = {
14105 { "Front Mic", 0x1 },
14111 static struct hda_input_mux alc861vd_dallas_capture_source = {
14114 { "Ext Mic", 0x0 },
14115 { "Int Mic", 0x1 },
14119 static struct hda_input_mux alc861vd_hp_capture_source = {
14122 { "Front Mic", 0x0 },
14123 { "ATAPI Mic", 0x1 },
14130 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14137 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14138 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14139 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14140 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14141 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14148 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14149 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14150 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14151 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14152 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14156 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14157 { 6, alc861vd_6stack_ch6_init },
14158 { 8, alc861vd_6stack_ch8_init },
14161 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14164 .name = "Channel Mode",
14165 .info = alc_ch_mode_info,
14166 .get = alc_ch_mode_get,
14167 .put = alc_ch_mode_put,
14172 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14173 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14175 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14176 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14177 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14179 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14180 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14182 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14184 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14186 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14187 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14189 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14190 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14192 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14194 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14198 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14199 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14200 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14205 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14206 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14208 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14209 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14214 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14215 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14216 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14220 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14221 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14224 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14225 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14226 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14228 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14229 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14234 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14235 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14240 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14241 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14242 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14243 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14245 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14247 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14249 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14251 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14255 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14256 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14261 /* Pin assignment: Speaker=0x14, HP = 0x15,
14262 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14264 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14265 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14266 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14267 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14268 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14269 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14270 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14271 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14272 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14273 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14274 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14275 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
14276 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
14280 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14281 * Front Mic=0x18, ATAPI Mic = 0x19,
14283 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14284 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14285 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14286 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14287 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14288 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14289 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14290 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14291 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14297 * generic initialization of ADC, input mixers and output mixers
14299 static struct hda_verb alc861vd_volume_init_verbs[] = {
14301 * Unmute ADC0 and set the default input to mic-in
14303 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14306 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14307 * the analog-loopback mixer widget
14309 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14310 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14311 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14312 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14313 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14314 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14316 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14323 * Set up output mixers (0x02 - 0x05)
14325 /* set vol=0 to output mixers */
14326 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14327 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14328 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14329 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14331 /* set up input amps for analog loopback */
14332 /* Amp Indices: DAC = 0, mixer = 1 */
14333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14335 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14336 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14337 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14338 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14340 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14346 * 3-stack pin configuration:
14347 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14349 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14351 * Set pin mode and muting
14353 /* set front pin widgets 0x14 for output */
14354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14356 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14358 /* Mic (rear) pin: input vref at 80% */
14359 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14360 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14361 /* Front Mic pin: input vref at 80% */
14362 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14363 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14364 /* Line In pin: input */
14365 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14366 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14367 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14368 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14369 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14370 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14371 /* CD pin widget for input */
14372 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14378 * 6-stack pin configuration:
14380 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14382 * Set pin mode and muting
14384 /* set front pin widgets 0x14 for output */
14385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14386 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14387 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14389 /* Rear Pin: output 1 (0x0d) */
14390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14391 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14392 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14393 /* CLFE Pin: output 2 (0x0e) */
14394 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14395 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14396 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14397 /* Side Pin: output 3 (0x0f) */
14398 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14399 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14400 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14402 /* Mic (rear) pin: input vref at 80% */
14403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14405 /* Front Mic pin: input vref at 80% */
14406 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14407 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14408 /* Line In pin: input */
14409 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14410 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14411 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14413 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14414 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14415 /* CD pin widget for input */
14416 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14421 static struct hda_verb alc861vd_eapd_verbs[] = {
14422 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14426 static struct hda_verb alc660vd_eapd_verbs[] = {
14427 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14428 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14432 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14436 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14437 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14441 /* toggle speaker-output according to the hp-jack state */
14442 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14444 unsigned int present;
14445 unsigned char bits;
14447 present = snd_hda_codec_read(codec, 0x1b, 0,
14448 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14449 bits = present ? HDA_AMP_MUTE : 0;
14450 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14451 HDA_AMP_MUTE, bits);
14454 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14456 unsigned int present;
14457 unsigned char bits;
14459 present = snd_hda_codec_read(codec, 0x18, 0,
14460 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14461 bits = present ? HDA_AMP_MUTE : 0;
14462 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14463 HDA_AMP_MUTE, bits);
14466 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14468 alc861vd_lenovo_hp_automute(codec);
14469 alc861vd_lenovo_mic_automute(codec);
14472 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14475 switch (res >> 26) {
14476 case ALC880_HP_EVENT:
14477 alc861vd_lenovo_hp_automute(codec);
14479 case ALC880_MIC_EVENT:
14480 alc861vd_lenovo_mic_automute(codec);
14485 static struct hda_verb alc861vd_dallas_verbs[] = {
14486 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14487 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14488 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14489 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14491 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14492 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14493 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14494 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14495 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14496 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14497 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14498 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14501 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14502 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14506 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14507 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14509 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14510 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14511 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14513 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14514 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14515 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14516 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14523 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14524 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14525 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14530 /* toggle speaker-output according to the hp-jack state */
14531 static void alc861vd_dallas_automute(struct hda_codec *codec)
14533 unsigned int present;
14535 present = snd_hda_codec_read(codec, 0x15, 0,
14536 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14537 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14538 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14541 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14543 if ((res >> 26) == ALC880_HP_EVENT)
14544 alc861vd_dallas_automute(codec);
14547 #ifdef CONFIG_SND_HDA_POWER_SAVE
14548 #define alc861vd_loopbacks alc880_loopbacks
14551 /* pcm configuration: identiacal with ALC880 */
14552 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14553 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14554 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14555 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14558 * configuration and preset
14560 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14561 [ALC660VD_3ST] = "3stack-660",
14562 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14563 [ALC660VD_ASUS_V1S] = "asus-v1s",
14564 [ALC861VD_3ST] = "3stack",
14565 [ALC861VD_3ST_DIG] = "3stack-digout",
14566 [ALC861VD_6ST_DIG] = "6stack-digout",
14567 [ALC861VD_LENOVO] = "lenovo",
14568 [ALC861VD_DALLAS] = "dallas",
14569 [ALC861VD_HP] = "hp",
14570 [ALC861VD_AUTO] = "auto",
14573 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14574 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14575 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14576 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14577 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14578 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14579 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14580 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14581 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14582 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14583 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14584 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14585 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14586 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14587 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14588 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14589 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14590 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14594 static struct alc_config_preset alc861vd_presets[] = {
14596 .mixers = { alc861vd_3st_mixer },
14597 .init_verbs = { alc861vd_volume_init_verbs,
14598 alc861vd_3stack_init_verbs },
14599 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14600 .dac_nids = alc660vd_dac_nids,
14601 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14602 .channel_mode = alc861vd_3stack_2ch_modes,
14603 .input_mux = &alc861vd_capture_source,
14605 [ALC660VD_3ST_DIG] = {
14606 .mixers = { alc861vd_3st_mixer },
14607 .init_verbs = { alc861vd_volume_init_verbs,
14608 alc861vd_3stack_init_verbs },
14609 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14610 .dac_nids = alc660vd_dac_nids,
14611 .dig_out_nid = ALC861VD_DIGOUT_NID,
14612 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14613 .channel_mode = alc861vd_3stack_2ch_modes,
14614 .input_mux = &alc861vd_capture_source,
14617 .mixers = { alc861vd_3st_mixer },
14618 .init_verbs = { alc861vd_volume_init_verbs,
14619 alc861vd_3stack_init_verbs },
14620 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14621 .dac_nids = alc861vd_dac_nids,
14622 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14623 .channel_mode = alc861vd_3stack_2ch_modes,
14624 .input_mux = &alc861vd_capture_source,
14626 [ALC861VD_3ST_DIG] = {
14627 .mixers = { alc861vd_3st_mixer },
14628 .init_verbs = { alc861vd_volume_init_verbs,
14629 alc861vd_3stack_init_verbs },
14630 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14631 .dac_nids = alc861vd_dac_nids,
14632 .dig_out_nid = ALC861VD_DIGOUT_NID,
14633 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14634 .channel_mode = alc861vd_3stack_2ch_modes,
14635 .input_mux = &alc861vd_capture_source,
14637 [ALC861VD_6ST_DIG] = {
14638 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14639 .init_verbs = { alc861vd_volume_init_verbs,
14640 alc861vd_6stack_init_verbs },
14641 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14642 .dac_nids = alc861vd_dac_nids,
14643 .dig_out_nid = ALC861VD_DIGOUT_NID,
14644 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14645 .channel_mode = alc861vd_6stack_modes,
14646 .input_mux = &alc861vd_capture_source,
14648 [ALC861VD_LENOVO] = {
14649 .mixers = { alc861vd_lenovo_mixer },
14650 .init_verbs = { alc861vd_volume_init_verbs,
14651 alc861vd_3stack_init_verbs,
14652 alc861vd_eapd_verbs,
14653 alc861vd_lenovo_unsol_verbs },
14654 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14655 .dac_nids = alc660vd_dac_nids,
14656 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14657 .channel_mode = alc861vd_3stack_2ch_modes,
14658 .input_mux = &alc861vd_capture_source,
14659 .unsol_event = alc861vd_lenovo_unsol_event,
14660 .init_hook = alc861vd_lenovo_automute,
14662 [ALC861VD_DALLAS] = {
14663 .mixers = { alc861vd_dallas_mixer },
14664 .init_verbs = { alc861vd_dallas_verbs },
14665 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14666 .dac_nids = alc861vd_dac_nids,
14667 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14668 .channel_mode = alc861vd_3stack_2ch_modes,
14669 .input_mux = &alc861vd_dallas_capture_source,
14670 .unsol_event = alc861vd_dallas_unsol_event,
14671 .init_hook = alc861vd_dallas_automute,
14674 .mixers = { alc861vd_hp_mixer },
14675 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14676 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14677 .dac_nids = alc861vd_dac_nids,
14678 .dig_out_nid = ALC861VD_DIGOUT_NID,
14679 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14680 .channel_mode = alc861vd_3stack_2ch_modes,
14681 .input_mux = &alc861vd_hp_capture_source,
14682 .unsol_event = alc861vd_dallas_unsol_event,
14683 .init_hook = alc861vd_dallas_automute,
14685 [ALC660VD_ASUS_V1S] = {
14686 .mixers = { alc861vd_lenovo_mixer },
14687 .init_verbs = { alc861vd_volume_init_verbs,
14688 alc861vd_3stack_init_verbs,
14689 alc861vd_eapd_verbs,
14690 alc861vd_lenovo_unsol_verbs },
14691 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14692 .dac_nids = alc660vd_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_capture_source,
14697 .unsol_event = alc861vd_lenovo_unsol_event,
14698 .init_hook = alc861vd_lenovo_automute,
14703 * BIOS auto configuration
14705 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14706 hda_nid_t nid, int pin_type, int dac_idx)
14708 alc_set_pin_output(codec, nid, pin_type);
14711 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14713 struct alc_spec *spec = codec->spec;
14716 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14717 for (i = 0; i <= HDA_SIDE; i++) {
14718 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14719 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14721 alc861vd_auto_set_output_and_unmute(codec, nid,
14727 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14729 struct alc_spec *spec = codec->spec;
14732 pin = spec->autocfg.hp_pins[0];
14733 if (pin) /* connect to front and use dac 0 */
14734 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14735 pin = spec->autocfg.speaker_pins[0];
14737 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14740 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14741 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14743 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14745 struct alc_spec *spec = codec->spec;
14748 for (i = 0; i < AUTO_PIN_LAST; i++) {
14749 hda_nid_t nid = spec->autocfg.input_pins[i];
14750 if (alc861vd_is_input_pin(nid)) {
14751 snd_hda_codec_write(codec, nid, 0,
14752 AC_VERB_SET_PIN_WIDGET_CONTROL,
14753 i <= AUTO_PIN_FRONT_MIC ?
14754 PIN_VREF80 : PIN_IN);
14755 if (nid != ALC861VD_PIN_CD_NID)
14756 snd_hda_codec_write(codec, nid, 0,
14757 AC_VERB_SET_AMP_GAIN_MUTE,
14763 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14765 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14766 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14768 /* add playback controls from the parsed DAC table */
14769 /* Based on ALC880 version. But ALC861VD has separate,
14770 * different NIDs for mute/unmute switch and volume control */
14771 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14772 const struct auto_pin_cfg *cfg)
14775 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14776 hda_nid_t nid_v, nid_s;
14779 for (i = 0; i < cfg->line_outs; i++) {
14780 if (!spec->multiout.dac_nids[i])
14782 nid_v = alc861vd_idx_to_mixer_vol(
14784 spec->multiout.dac_nids[i]));
14785 nid_s = alc861vd_idx_to_mixer_switch(
14787 spec->multiout.dac_nids[i]));
14791 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14792 "Center Playback Volume",
14793 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14797 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14798 "LFE Playback Volume",
14799 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14803 err = add_control(spec, ALC_CTL_BIND_MUTE,
14804 "Center Playback Switch",
14805 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14809 err = add_control(spec, ALC_CTL_BIND_MUTE,
14810 "LFE Playback Switch",
14811 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14816 sprintf(name, "%s Playback Volume", chname[i]);
14817 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14818 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14822 sprintf(name, "%s Playback Switch", chname[i]);
14823 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14824 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14833 /* add playback controls for speaker and HP outputs */
14834 /* Based on ALC880 version. But ALC861VD has separate,
14835 * different NIDs for mute/unmute switch and volume control */
14836 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14837 hda_nid_t pin, const char *pfx)
14839 hda_nid_t nid_v, nid_s;
14846 if (alc880_is_fixed_pin(pin)) {
14847 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14848 /* specify the DAC as the extra output */
14849 if (!spec->multiout.hp_nid)
14850 spec->multiout.hp_nid = nid_v;
14852 spec->multiout.extra_out_nid[0] = nid_v;
14853 /* control HP volume/switch on the output mixer amp */
14854 nid_v = alc861vd_idx_to_mixer_vol(
14855 alc880_fixed_pin_idx(pin));
14856 nid_s = alc861vd_idx_to_mixer_switch(
14857 alc880_fixed_pin_idx(pin));
14859 sprintf(name, "%s Playback Volume", pfx);
14860 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14861 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14864 sprintf(name, "%s Playback Switch", pfx);
14865 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14866 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14869 } else if (alc880_is_multi_pin(pin)) {
14870 /* set manual connection */
14871 /* we have only a switch on HP-out PIN */
14872 sprintf(name, "%s Playback Switch", pfx);
14873 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14874 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14881 /* parse the BIOS configuration and set up the alc_spec
14882 * return 1 if successful, 0 if the proper config is not found,
14883 * or a negative error code
14884 * Based on ALC880 version - had to change it to override
14885 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14886 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14888 struct alc_spec *spec = codec->spec;
14890 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14892 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14896 if (!spec->autocfg.line_outs)
14897 return 0; /* can't find valid BIOS pin config */
14899 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14902 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14905 err = alc861vd_auto_create_extra_out(spec,
14906 spec->autocfg.speaker_pins[0],
14910 err = alc861vd_auto_create_extra_out(spec,
14911 spec->autocfg.hp_pins[0],
14915 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14919 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14921 if (spec->autocfg.dig_out_pin)
14922 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14924 if (spec->kctls.list)
14925 add_mixer(spec, spec->kctls.list);
14927 add_verb(spec, alc861vd_volume_init_verbs);
14929 spec->num_mux_defs = 1;
14930 spec->input_mux = &spec->private_imux[0];
14932 err = alc_auto_add_mic_boost(codec);
14936 store_pin_configs(codec);
14940 /* additional initialization for auto-configuration model */
14941 static void alc861vd_auto_init(struct hda_codec *codec)
14943 struct alc_spec *spec = codec->spec;
14944 alc861vd_auto_init_multi_out(codec);
14945 alc861vd_auto_init_hp_out(codec);
14946 alc861vd_auto_init_analog_input(codec);
14947 alc861vd_auto_init_input_src(codec);
14948 if (spec->unsol_event)
14949 alc_inithook(codec);
14952 static int patch_alc861vd(struct hda_codec *codec)
14954 struct alc_spec *spec;
14955 int err, board_config;
14957 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14961 codec->spec = spec;
14963 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14967 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14968 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14969 "ALC861VD, trying auto-probe from BIOS...\n");
14970 board_config = ALC861VD_AUTO;
14973 if (board_config == ALC861VD_AUTO) {
14974 /* automatic parse from the BIOS config */
14975 err = alc861vd_parse_auto_config(codec);
14981 "hda_codec: Cannot set up configuration "
14982 "from BIOS. Using base mode...\n");
14983 board_config = ALC861VD_3ST;
14987 err = snd_hda_attach_beep_device(codec, 0x23);
14993 if (board_config != ALC861VD_AUTO)
14994 setup_preset(spec, &alc861vd_presets[board_config]);
14996 if (codec->vendor_id == 0x10ec0660) {
14997 spec->stream_name_analog = "ALC660-VD Analog";
14998 spec->stream_name_digital = "ALC660-VD Digital";
14999 /* always turn on EAPD */
15000 add_verb(spec, alc660vd_eapd_verbs);
15002 spec->stream_name_analog = "ALC861VD Analog";
15003 spec->stream_name_digital = "ALC861VD Digital";
15006 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15007 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15009 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15010 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15012 spec->adc_nids = alc861vd_adc_nids;
15013 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15014 spec->capsrc_nids = alc861vd_capsrc_nids;
15015 spec->capture_style = CAPT_MIX;
15017 set_capture_mixer(spec);
15019 spec->vmaster_nid = 0x02;
15021 codec->patch_ops = alc_patch_ops;
15023 if (board_config == ALC861VD_AUTO)
15024 spec->init_hook = alc861vd_auto_init;
15025 #ifdef CONFIG_SND_HDA_POWER_SAVE
15026 if (!spec->loopback.amplist)
15027 spec->loopback.amplist = alc861vd_loopbacks;
15029 codec->proc_widget_hook = print_realtek_coef;
15037 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15038 * configuration. Each pin widget can choose any input DACs and a mixer.
15039 * Each ADC is connected from a mixer of all inputs. This makes possible
15040 * 6-channel independent captures.
15042 * In addition, an independent DAC for the multi-playback (not used in this
15045 #define ALC662_DIGOUT_NID 0x06
15046 #define ALC662_DIGIN_NID 0x0a
15048 static hda_nid_t alc662_dac_nids[4] = {
15049 /* front, rear, clfe, rear_surr */
15053 static hda_nid_t alc662_adc_nids[1] = {
15058 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15061 /* FIXME: should be a matrix-type input source selection */
15062 static struct hda_input_mux alc662_capture_source = {
15066 { "Front Mic", 0x1 },
15072 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15080 static struct hda_input_mux alc662_eeepc_capture_source = {
15088 static struct hda_input_mux alc663_capture_source = {
15092 { "Front Mic", 0x1 },
15097 static struct hda_input_mux alc663_m51va_capture_source = {
15100 { "Ext-Mic", 0x0 },
15108 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15115 static struct hda_verb alc662_3ST_ch2_init[] = {
15116 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15117 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15118 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15119 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15126 static struct hda_verb alc662_3ST_ch6_init[] = {
15127 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15128 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15129 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15130 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15131 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15132 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15136 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15137 { 2, alc662_3ST_ch2_init },
15138 { 6, alc662_3ST_ch6_init },
15144 static struct hda_verb alc662_sixstack_ch6_init[] = {
15145 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15146 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15147 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15154 static struct hda_verb alc662_sixstack_ch8_init[] = {
15155 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15156 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15157 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15161 static struct hda_channel_mode alc662_5stack_modes[2] = {
15162 { 2, alc662_sixstack_ch6_init },
15163 { 6, alc662_sixstack_ch8_init },
15166 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15167 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15170 static struct snd_kcontrol_new alc662_base_mixer[] = {
15171 /* output mixer control */
15172 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15173 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15174 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15175 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15176 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15177 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15178 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15179 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15182 /*Input mixer control */
15183 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15184 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15185 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15186 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15187 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15188 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15189 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15190 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15194 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15195 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15196 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15198 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15199 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15200 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15201 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15204 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15205 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15206 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
15207 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
15211 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15212 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15213 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15214 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15215 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15216 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15217 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15218 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15219 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15221 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15222 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15229 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
15230 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
15234 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15235 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15236 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15237 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15238 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15240 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15241 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15243 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15247 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15250 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15251 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15253 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15254 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15255 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15257 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15258 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15259 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15263 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15264 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15265 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15266 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15267 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15268 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15269 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15270 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15271 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15272 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15273 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15274 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15275 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15281 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15282 .ops = &snd_hda_bind_vol,
15284 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15285 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15290 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15291 .ops = &snd_hda_bind_sw,
15293 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15294 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15299 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15300 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15301 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15307 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15308 .ops = &snd_hda_bind_sw,
15310 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15311 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15312 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15317 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15318 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15319 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15322 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15323 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15328 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15329 .ops = &snd_hda_bind_sw,
15331 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15332 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15333 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15338 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15339 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15340 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15342 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15343 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15344 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15348 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15349 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15350 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15352 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15354 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15355 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15359 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15360 .ops = &snd_hda_bind_vol,
15362 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15363 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15368 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15369 .ops = &snd_hda_bind_sw,
15371 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15372 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15377 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15378 HDA_BIND_VOL("Master Playback Volume",
15379 &alc663_asus_two_bind_master_vol),
15380 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15381 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15388 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15389 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15390 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15391 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15392 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15394 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15398 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15399 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15401 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15402 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15407 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15408 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15412 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15419 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15420 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15426 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15429 .name = "Channel Mode",
15430 .info = alc_ch_mode_info,
15431 .get = alc_ch_mode_get,
15432 .put = alc_ch_mode_put,
15437 static struct hda_verb alc662_init_verbs[] = {
15438 /* ADC: mute amp left and right */
15439 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15440 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15441 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15443 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15451 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15453 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15454 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15456 /* Front Pin: output 0 (0x0c) */
15457 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15460 /* Rear Pin: output 1 (0x0d) */
15461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15462 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15464 /* CLFE Pin: output 2 (0x0e) */
15465 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15466 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15468 /* Mic (rear) pin: input vref at 80% */
15469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15471 /* Front Mic pin: input vref at 80% */
15472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15473 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15474 /* Line In pin: input */
15475 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15477 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15480 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15481 /* CD pin widget for input */
15482 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15484 /* FIXME: use matrix-type input source selection */
15485 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15487 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15488 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15489 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15493 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15495 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15497 /* always trun on EAPD */
15498 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15499 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15504 static struct hda_verb alc662_sue_init_verbs[] = {
15505 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15506 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15510 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15511 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15512 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15516 /* Set Unsolicited Event*/
15517 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15519 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15524 * generic initialization of ADC, input mixers and output mixers
15526 static struct hda_verb alc662_auto_init_verbs[] = {
15528 * Unmute ADC and set the default input to mic-in
15530 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15533 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15535 * Note: PASD motherboards uses the Line In 2 as the input for front
15536 * panel mic (mic 2)
15538 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15546 * Set up output mixers (0x0c - 0x0f)
15548 /* set vol=0 to output mixers */
15549 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15550 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15551 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15553 /* set up input amps for analog loopback */
15554 /* Amp Indices: DAC = 0, mixer = 1 */
15555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15557 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15559 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15563 /* FIXME: use matrix-type input source selection */
15564 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15571 /* additional verbs for ALC663 */
15572 static struct hda_verb alc663_auto_init_verbs[] = {
15573 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15574 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15578 static struct hda_verb alc663_m51va_init_verbs[] = {
15579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15580 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15581 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15582 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15583 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15586 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15587 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15591 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15592 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15593 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15594 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15595 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15597 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15598 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15602 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15603 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15604 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15605 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15606 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15609 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15610 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15614 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15615 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15617 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15620 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15621 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15625 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15626 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15627 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15628 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15629 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15630 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15632 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15634 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15635 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15636 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15637 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15641 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15642 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15644 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15645 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15648 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15649 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15651 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15652 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15653 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15657 static struct hda_verb alc663_g71v_init_verbs[] = {
15658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15659 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15660 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15662 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15663 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15664 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15666 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15667 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15668 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15672 static struct hda_verb alc663_g50v_init_verbs[] = {
15673 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15674 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15675 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15677 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15678 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15682 static struct hda_verb alc662_ecs_init_verbs[] = {
15683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15684 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15685 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15690 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15691 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15692 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15696 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15698 unsigned int present;
15699 unsigned char bits;
15701 present = snd_hda_codec_read(codec, 0x14, 0,
15702 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15703 bits = present ? HDA_AMP_MUTE : 0;
15704 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15705 HDA_AMP_MUTE, bits);
15708 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15710 unsigned int present;
15711 unsigned char bits;
15713 present = snd_hda_codec_read(codec, 0x1b, 0,
15714 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15715 bits = present ? HDA_AMP_MUTE : 0;
15716 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15717 HDA_AMP_MUTE, bits);
15718 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15719 HDA_AMP_MUTE, bits);
15722 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15725 if ((res >> 26) == ALC880_HP_EVENT)
15726 alc662_lenovo_101e_all_automute(codec);
15727 if ((res >> 26) == ALC880_FRONT_EVENT)
15728 alc662_lenovo_101e_ispeaker_automute(codec);
15731 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15733 unsigned int present;
15735 present = snd_hda_codec_read(codec, 0x18, 0,
15736 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15737 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15738 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15739 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15740 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15741 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15742 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15743 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15744 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15747 /* unsolicited event for HP jack sensing */
15748 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15751 if ((res >> 26) == ALC880_HP_EVENT)
15752 alc262_hippo1_automute( codec );
15754 if ((res >> 26) == ALC880_MIC_EVENT)
15755 alc662_eeepc_mic_automute(codec);
15758 static void alc662_eeepc_inithook(struct hda_codec *codec)
15760 alc262_hippo1_automute( codec );
15761 alc662_eeepc_mic_automute(codec);
15764 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15767 unsigned int present;
15769 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15770 present = snd_hda_codec_read(codec, 0x14, 0,
15771 AC_VERB_GET_PIN_SENSE, 0);
15772 present = (present & 0x80000000) != 0;
15774 /* mute internal speaker */
15775 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15776 HDA_AMP_MUTE, HDA_AMP_MUTE);
15778 /* unmute internal speaker if necessary */
15779 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15780 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15781 HDA_AMP_MUTE, mute);
15785 /* unsolicited event for HP jack sensing */
15786 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15789 if ((res >> 26) == ALC880_HP_EVENT)
15790 alc662_eeepc_ep20_automute(codec);
15793 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15795 alc662_eeepc_ep20_automute(codec);
15798 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15800 unsigned int present;
15801 unsigned char bits;
15803 present = snd_hda_codec_read(codec, 0x21, 0,
15804 AC_VERB_GET_PIN_SENSE, 0)
15805 & AC_PINSENSE_PRESENCE;
15806 bits = present ? HDA_AMP_MUTE : 0;
15807 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15808 AMP_IN_MUTE(0), bits);
15809 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15810 AMP_IN_MUTE(0), bits);
15813 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15815 unsigned int present;
15816 unsigned char bits;
15818 present = snd_hda_codec_read(codec, 0x21, 0,
15819 AC_VERB_GET_PIN_SENSE, 0)
15820 & AC_PINSENSE_PRESENCE;
15821 bits = present ? HDA_AMP_MUTE : 0;
15822 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15823 AMP_IN_MUTE(0), bits);
15824 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15825 AMP_IN_MUTE(0), bits);
15826 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15827 AMP_IN_MUTE(0), bits);
15828 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15829 AMP_IN_MUTE(0), bits);
15832 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15834 unsigned int present;
15835 unsigned char bits;
15837 present = snd_hda_codec_read(codec, 0x15, 0,
15838 AC_VERB_GET_PIN_SENSE, 0)
15839 & AC_PINSENSE_PRESENCE;
15840 bits = present ? HDA_AMP_MUTE : 0;
15841 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15842 AMP_IN_MUTE(0), bits);
15843 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15844 AMP_IN_MUTE(0), bits);
15845 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15846 AMP_IN_MUTE(0), bits);
15847 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15848 AMP_IN_MUTE(0), bits);
15851 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15853 unsigned int present;
15854 unsigned char bits;
15856 present = snd_hda_codec_read(codec, 0x1b, 0,
15857 AC_VERB_GET_PIN_SENSE, 0)
15858 & AC_PINSENSE_PRESENCE;
15859 bits = present ? 0 : PIN_OUT;
15860 snd_hda_codec_write(codec, 0x14, 0,
15861 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15864 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15866 unsigned int present1, present2;
15868 present1 = snd_hda_codec_read(codec, 0x21, 0,
15869 AC_VERB_GET_PIN_SENSE, 0)
15870 & AC_PINSENSE_PRESENCE;
15871 present2 = snd_hda_codec_read(codec, 0x15, 0,
15872 AC_VERB_GET_PIN_SENSE, 0)
15873 & AC_PINSENSE_PRESENCE;
15875 if (present1 || present2) {
15876 snd_hda_codec_write_cache(codec, 0x14, 0,
15877 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15879 snd_hda_codec_write_cache(codec, 0x14, 0,
15880 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15884 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15886 unsigned int present1, present2;
15888 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15889 AC_VERB_GET_PIN_SENSE, 0)
15890 & AC_PINSENSE_PRESENCE;
15891 present2 = snd_hda_codec_read(codec, 0x15, 0,
15892 AC_VERB_GET_PIN_SENSE, 0)
15893 & AC_PINSENSE_PRESENCE;
15895 if (present1 || present2) {
15896 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15897 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15898 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15899 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15901 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15902 AMP_IN_MUTE(0), 0);
15903 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15904 AMP_IN_MUTE(0), 0);
15908 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15910 unsigned int present;
15912 present = snd_hda_codec_read(codec, 0x18, 0,
15913 AC_VERB_GET_PIN_SENSE, 0)
15914 & AC_PINSENSE_PRESENCE;
15915 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15916 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15917 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15918 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15919 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15920 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15921 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15922 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15925 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15928 switch (res >> 26) {
15929 case ALC880_HP_EVENT:
15930 alc663_m51va_speaker_automute(codec);
15932 case ALC880_MIC_EVENT:
15933 alc663_m51va_mic_automute(codec);
15938 static void alc663_m51va_inithook(struct hda_codec *codec)
15940 alc663_m51va_speaker_automute(codec);
15941 alc663_m51va_mic_automute(codec);
15944 /* ***************** Mode1 ******************************/
15945 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15948 switch (res >> 26) {
15949 case ALC880_HP_EVENT:
15950 alc663_m51va_speaker_automute(codec);
15952 case ALC880_MIC_EVENT:
15953 alc662_eeepc_mic_automute(codec);
15958 static void alc663_mode1_inithook(struct hda_codec *codec)
15960 alc663_m51va_speaker_automute(codec);
15961 alc662_eeepc_mic_automute(codec);
15963 /* ***************** Mode2 ******************************/
15964 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15967 switch (res >> 26) {
15968 case ALC880_HP_EVENT:
15969 alc662_f5z_speaker_automute(codec);
15971 case ALC880_MIC_EVENT:
15972 alc662_eeepc_mic_automute(codec);
15977 static void alc662_mode2_inithook(struct hda_codec *codec)
15979 alc662_f5z_speaker_automute(codec);
15980 alc662_eeepc_mic_automute(codec);
15982 /* ***************** Mode3 ******************************/
15983 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15986 switch (res >> 26) {
15987 case ALC880_HP_EVENT:
15988 alc663_two_hp_m1_speaker_automute(codec);
15990 case ALC880_MIC_EVENT:
15991 alc662_eeepc_mic_automute(codec);
15996 static void alc663_mode3_inithook(struct hda_codec *codec)
15998 alc663_two_hp_m1_speaker_automute(codec);
15999 alc662_eeepc_mic_automute(codec);
16001 /* ***************** Mode4 ******************************/
16002 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16005 switch (res >> 26) {
16006 case ALC880_HP_EVENT:
16007 alc663_21jd_two_speaker_automute(codec);
16009 case ALC880_MIC_EVENT:
16010 alc662_eeepc_mic_automute(codec);
16015 static void alc663_mode4_inithook(struct hda_codec *codec)
16017 alc663_21jd_two_speaker_automute(codec);
16018 alc662_eeepc_mic_automute(codec);
16020 /* ***************** Mode5 ******************************/
16021 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16024 switch (res >> 26) {
16025 case ALC880_HP_EVENT:
16026 alc663_15jd_two_speaker_automute(codec);
16028 case ALC880_MIC_EVENT:
16029 alc662_eeepc_mic_automute(codec);
16034 static void alc663_mode5_inithook(struct hda_codec *codec)
16036 alc663_15jd_two_speaker_automute(codec);
16037 alc662_eeepc_mic_automute(codec);
16039 /* ***************** Mode6 ******************************/
16040 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16043 switch (res >> 26) {
16044 case ALC880_HP_EVENT:
16045 alc663_two_hp_m2_speaker_automute(codec);
16047 case ALC880_MIC_EVENT:
16048 alc662_eeepc_mic_automute(codec);
16053 static void alc663_mode6_inithook(struct hda_codec *codec)
16055 alc663_two_hp_m2_speaker_automute(codec);
16056 alc662_eeepc_mic_automute(codec);
16059 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16061 unsigned int present;
16062 unsigned char bits;
16064 present = snd_hda_codec_read(codec, 0x21, 0,
16065 AC_VERB_GET_PIN_SENSE, 0)
16066 & AC_PINSENSE_PRESENCE;
16067 bits = present ? HDA_AMP_MUTE : 0;
16068 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16069 HDA_AMP_MUTE, bits);
16070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16071 HDA_AMP_MUTE, bits);
16074 static void alc663_g71v_front_automute(struct hda_codec *codec)
16076 unsigned int present;
16077 unsigned char bits;
16079 present = snd_hda_codec_read(codec, 0x15, 0,
16080 AC_VERB_GET_PIN_SENSE, 0)
16081 & AC_PINSENSE_PRESENCE;
16082 bits = present ? HDA_AMP_MUTE : 0;
16083 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16084 HDA_AMP_MUTE, bits);
16087 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16090 switch (res >> 26) {
16091 case ALC880_HP_EVENT:
16092 alc663_g71v_hp_automute(codec);
16094 case ALC880_FRONT_EVENT:
16095 alc663_g71v_front_automute(codec);
16097 case ALC880_MIC_EVENT:
16098 alc662_eeepc_mic_automute(codec);
16103 static void alc663_g71v_inithook(struct hda_codec *codec)
16105 alc663_g71v_front_automute(codec);
16106 alc663_g71v_hp_automute(codec);
16107 alc662_eeepc_mic_automute(codec);
16110 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16113 switch (res >> 26) {
16114 case ALC880_HP_EVENT:
16115 alc663_m51va_speaker_automute(codec);
16117 case ALC880_MIC_EVENT:
16118 alc662_eeepc_mic_automute(codec);
16123 static void alc663_g50v_inithook(struct hda_codec *codec)
16125 alc663_m51va_speaker_automute(codec);
16126 alc662_eeepc_mic_automute(codec);
16129 /* bind hp and internal speaker mute (with plug check) */
16130 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16131 struct snd_ctl_elem_value *ucontrol)
16133 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16134 long *valp = ucontrol->value.integer.value;
16137 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16139 valp[0] ? 0 : HDA_AMP_MUTE);
16140 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16142 valp[1] ? 0 : HDA_AMP_MUTE);
16144 alc262_hippo1_automute(codec);
16148 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16149 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16152 .name = "Master Playback Switch",
16153 .info = snd_hda_mixer_amp_switch_info,
16154 .get = snd_hda_mixer_amp_switch_get,
16155 .put = alc662_ecs_master_sw_put,
16156 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16159 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16160 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16161 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16163 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16164 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16165 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16169 #ifdef CONFIG_SND_HDA_POWER_SAVE
16170 #define alc662_loopbacks alc880_loopbacks
16174 /* pcm configuration: identiacal with ALC880 */
16175 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16176 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16177 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16178 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16181 * configuration and preset
16183 static const char *alc662_models[ALC662_MODEL_LAST] = {
16184 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16185 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16186 [ALC662_3ST_6ch] = "3stack-6ch",
16187 [ALC662_5ST_DIG] = "6stack-dig",
16188 [ALC662_LENOVO_101E] = "lenovo-101e",
16189 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16190 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16191 [ALC662_ECS] = "ecs",
16192 [ALC663_ASUS_M51VA] = "m51va",
16193 [ALC663_ASUS_G71V] = "g71v",
16194 [ALC663_ASUS_H13] = "h13",
16195 [ALC663_ASUS_G50V] = "g50v",
16196 [ALC663_ASUS_MODE1] = "asus-mode1",
16197 [ALC662_ASUS_MODE2] = "asus-mode2",
16198 [ALC663_ASUS_MODE3] = "asus-mode3",
16199 [ALC663_ASUS_MODE4] = "asus-mode4",
16200 [ALC663_ASUS_MODE5] = "asus-mode5",
16201 [ALC663_ASUS_MODE6] = "asus-mode6",
16202 [ALC662_AUTO] = "auto",
16205 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16206 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16207 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16208 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16209 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16210 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16211 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16212 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
16213 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16214 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16215 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16216 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
16217 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16218 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16219 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16220 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16221 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16222 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16223 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16224 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16225 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16226 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16227 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16228 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16229 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16230 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16231 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16232 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16233 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16234 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16235 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16236 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16237 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16238 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16239 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16240 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16241 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16242 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16243 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16244 ALC662_3ST_6ch_DIG),
16245 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16246 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16247 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16248 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16249 ALC662_3ST_6ch_DIG),
16250 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16251 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16252 ALC662_3ST_6ch_DIG),
16253 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
16254 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
16255 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
16259 static struct alc_config_preset alc662_presets[] = {
16260 [ALC662_3ST_2ch_DIG] = {
16261 .mixers = { alc662_3ST_2ch_mixer },
16262 .init_verbs = { alc662_init_verbs },
16263 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16264 .dac_nids = alc662_dac_nids,
16265 .dig_out_nid = ALC662_DIGOUT_NID,
16266 .dig_in_nid = ALC662_DIGIN_NID,
16267 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16268 .channel_mode = alc662_3ST_2ch_modes,
16269 .input_mux = &alc662_capture_source,
16271 [ALC662_3ST_6ch_DIG] = {
16272 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16273 .init_verbs = { alc662_init_verbs },
16274 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16275 .dac_nids = alc662_dac_nids,
16276 .dig_out_nid = ALC662_DIGOUT_NID,
16277 .dig_in_nid = ALC662_DIGIN_NID,
16278 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16279 .channel_mode = alc662_3ST_6ch_modes,
16281 .input_mux = &alc662_capture_source,
16283 [ALC662_3ST_6ch] = {
16284 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16285 .init_verbs = { alc662_init_verbs },
16286 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16287 .dac_nids = alc662_dac_nids,
16288 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16289 .channel_mode = alc662_3ST_6ch_modes,
16291 .input_mux = &alc662_capture_source,
16293 [ALC662_5ST_DIG] = {
16294 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16295 .init_verbs = { alc662_init_verbs },
16296 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16297 .dac_nids = alc662_dac_nids,
16298 .dig_out_nid = ALC662_DIGOUT_NID,
16299 .dig_in_nid = ALC662_DIGIN_NID,
16300 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16301 .channel_mode = alc662_5stack_modes,
16302 .input_mux = &alc662_capture_source,
16304 [ALC662_LENOVO_101E] = {
16305 .mixers = { alc662_lenovo_101e_mixer },
16306 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16307 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16308 .dac_nids = alc662_dac_nids,
16309 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16310 .channel_mode = alc662_3ST_2ch_modes,
16311 .input_mux = &alc662_lenovo_101e_capture_source,
16312 .unsol_event = alc662_lenovo_101e_unsol_event,
16313 .init_hook = alc662_lenovo_101e_all_automute,
16315 [ALC662_ASUS_EEEPC_P701] = {
16316 .mixers = { alc662_eeepc_p701_mixer },
16317 .init_verbs = { alc662_init_verbs,
16318 alc662_eeepc_sue_init_verbs },
16319 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16320 .dac_nids = alc662_dac_nids,
16321 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16322 .channel_mode = alc662_3ST_2ch_modes,
16323 .input_mux = &alc662_eeepc_capture_source,
16324 .unsol_event = alc662_eeepc_unsol_event,
16325 .init_hook = alc662_eeepc_inithook,
16327 [ALC662_ASUS_EEEPC_EP20] = {
16328 .mixers = { alc662_eeepc_ep20_mixer,
16329 alc662_chmode_mixer },
16330 .init_verbs = { alc662_init_verbs,
16331 alc662_eeepc_ep20_sue_init_verbs },
16332 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16333 .dac_nids = alc662_dac_nids,
16334 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16335 .channel_mode = alc662_3ST_6ch_modes,
16336 .input_mux = &alc662_lenovo_101e_capture_source,
16337 .unsol_event = alc662_eeepc_ep20_unsol_event,
16338 .init_hook = alc662_eeepc_ep20_inithook,
16341 .mixers = { alc662_ecs_mixer },
16342 .init_verbs = { alc662_init_verbs,
16343 alc662_ecs_init_verbs },
16344 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16345 .dac_nids = alc662_dac_nids,
16346 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16347 .channel_mode = alc662_3ST_2ch_modes,
16348 .input_mux = &alc662_eeepc_capture_source,
16349 .unsol_event = alc662_eeepc_unsol_event,
16350 .init_hook = alc662_eeepc_inithook,
16352 [ALC663_ASUS_M51VA] = {
16353 .mixers = { alc663_m51va_mixer },
16354 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16355 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16356 .dac_nids = alc662_dac_nids,
16357 .dig_out_nid = ALC662_DIGOUT_NID,
16358 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16359 .channel_mode = alc662_3ST_2ch_modes,
16360 .input_mux = &alc663_m51va_capture_source,
16361 .unsol_event = alc663_m51va_unsol_event,
16362 .init_hook = alc663_m51va_inithook,
16364 [ALC663_ASUS_G71V] = {
16365 .mixers = { alc663_g71v_mixer },
16366 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16367 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16368 .dac_nids = alc662_dac_nids,
16369 .dig_out_nid = ALC662_DIGOUT_NID,
16370 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16371 .channel_mode = alc662_3ST_2ch_modes,
16372 .input_mux = &alc662_eeepc_capture_source,
16373 .unsol_event = alc663_g71v_unsol_event,
16374 .init_hook = alc663_g71v_inithook,
16376 [ALC663_ASUS_H13] = {
16377 .mixers = { alc663_m51va_mixer },
16378 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16379 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16380 .dac_nids = alc662_dac_nids,
16381 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16382 .channel_mode = alc662_3ST_2ch_modes,
16383 .input_mux = &alc663_m51va_capture_source,
16384 .unsol_event = alc663_m51va_unsol_event,
16385 .init_hook = alc663_m51va_inithook,
16387 [ALC663_ASUS_G50V] = {
16388 .mixers = { alc663_g50v_mixer },
16389 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16390 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16391 .dac_nids = alc662_dac_nids,
16392 .dig_out_nid = ALC662_DIGOUT_NID,
16393 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16394 .channel_mode = alc662_3ST_6ch_modes,
16395 .input_mux = &alc663_capture_source,
16396 .unsol_event = alc663_g50v_unsol_event,
16397 .init_hook = alc663_g50v_inithook,
16399 [ALC663_ASUS_MODE1] = {
16400 .mixers = { alc663_m51va_mixer },
16401 .cap_mixer = alc662_auto_capture_mixer,
16402 .init_verbs = { alc662_init_verbs,
16403 alc663_21jd_amic_init_verbs },
16404 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16406 .dac_nids = alc662_dac_nids,
16407 .dig_out_nid = ALC662_DIGOUT_NID,
16408 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16409 .channel_mode = alc662_3ST_2ch_modes,
16410 .input_mux = &alc662_eeepc_capture_source,
16411 .unsol_event = alc663_mode1_unsol_event,
16412 .init_hook = alc663_mode1_inithook,
16414 [ALC662_ASUS_MODE2] = {
16415 .mixers = { alc662_1bjd_mixer },
16416 .cap_mixer = alc662_auto_capture_mixer,
16417 .init_verbs = { alc662_init_verbs,
16418 alc662_1bjd_amic_init_verbs },
16419 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16420 .dac_nids = alc662_dac_nids,
16421 .dig_out_nid = ALC662_DIGOUT_NID,
16422 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16423 .channel_mode = alc662_3ST_2ch_modes,
16424 .input_mux = &alc662_eeepc_capture_source,
16425 .unsol_event = alc662_mode2_unsol_event,
16426 .init_hook = alc662_mode2_inithook,
16428 [ALC663_ASUS_MODE3] = {
16429 .mixers = { alc663_two_hp_m1_mixer },
16430 .cap_mixer = alc662_auto_capture_mixer,
16431 .init_verbs = { alc662_init_verbs,
16432 alc663_two_hp_amic_m1_init_verbs },
16433 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16435 .dac_nids = alc662_dac_nids,
16436 .dig_out_nid = ALC662_DIGOUT_NID,
16437 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16438 .channel_mode = alc662_3ST_2ch_modes,
16439 .input_mux = &alc662_eeepc_capture_source,
16440 .unsol_event = alc663_mode3_unsol_event,
16441 .init_hook = alc663_mode3_inithook,
16443 [ALC663_ASUS_MODE4] = {
16444 .mixers = { alc663_asus_21jd_clfe_mixer },
16445 .cap_mixer = alc662_auto_capture_mixer,
16446 .init_verbs = { alc662_init_verbs,
16447 alc663_21jd_amic_init_verbs},
16448 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16450 .dac_nids = alc662_dac_nids,
16451 .dig_out_nid = ALC662_DIGOUT_NID,
16452 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16453 .channel_mode = alc662_3ST_2ch_modes,
16454 .input_mux = &alc662_eeepc_capture_source,
16455 .unsol_event = alc663_mode4_unsol_event,
16456 .init_hook = alc663_mode4_inithook,
16458 [ALC663_ASUS_MODE5] = {
16459 .mixers = { alc663_asus_15jd_clfe_mixer },
16460 .cap_mixer = alc662_auto_capture_mixer,
16461 .init_verbs = { alc662_init_verbs,
16462 alc663_15jd_amic_init_verbs },
16463 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16465 .dac_nids = alc662_dac_nids,
16466 .dig_out_nid = ALC662_DIGOUT_NID,
16467 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16468 .channel_mode = alc662_3ST_2ch_modes,
16469 .input_mux = &alc662_eeepc_capture_source,
16470 .unsol_event = alc663_mode5_unsol_event,
16471 .init_hook = alc663_mode5_inithook,
16473 [ALC663_ASUS_MODE6] = {
16474 .mixers = { alc663_two_hp_m2_mixer },
16475 .cap_mixer = alc662_auto_capture_mixer,
16476 .init_verbs = { alc662_init_verbs,
16477 alc663_two_hp_amic_m2_init_verbs },
16478 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16480 .dac_nids = alc662_dac_nids,
16481 .dig_out_nid = ALC662_DIGOUT_NID,
16482 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16483 .channel_mode = alc662_3ST_2ch_modes,
16484 .input_mux = &alc662_eeepc_capture_source,
16485 .unsol_event = alc663_mode6_unsol_event,
16486 .init_hook = alc663_mode6_inithook,
16492 * BIOS auto configuration
16495 /* add playback controls from the parsed DAC table */
16496 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16497 const struct auto_pin_cfg *cfg)
16500 static const char *chname[4] = {
16501 "Front", "Surround", NULL /*CLFE*/, "Side"
16506 for (i = 0; i < cfg->line_outs; i++) {
16507 if (!spec->multiout.dac_nids[i])
16509 nid = alc880_idx_to_dac(i);
16512 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16513 "Center Playback Volume",
16514 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16518 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16519 "LFE Playback Volume",
16520 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16524 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16525 "Center Playback Switch",
16526 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16530 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16531 "LFE Playback Switch",
16532 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16537 sprintf(name, "%s Playback Volume", chname[i]);
16538 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16539 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16543 sprintf(name, "%s Playback Switch", chname[i]);
16544 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16545 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16554 /* add playback controls for speaker and HP outputs */
16555 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16566 /* ALC663 has a mono output pin on 0x17 */
16567 sprintf(name, "%s Playback Switch", pfx);
16568 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16569 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16573 if (alc880_is_fixed_pin(pin)) {
16574 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16575 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16576 /* specify the DAC as the extra output */
16577 if (!spec->multiout.hp_nid)
16578 spec->multiout.hp_nid = nid;
16580 spec->multiout.extra_out_nid[0] = nid;
16581 /* control HP volume/switch on the output mixer amp */
16582 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16583 sprintf(name, "%s Playback Volume", pfx);
16584 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16585 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16588 sprintf(name, "%s Playback Switch", pfx);
16589 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16590 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16593 } else if (alc880_is_multi_pin(pin)) {
16594 /* set manual connection */
16595 /* we have only a switch on HP-out PIN */
16596 sprintf(name, "%s Playback Switch", pfx);
16597 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16598 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16605 /* create playback/capture controls for input pins */
16606 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16607 const struct auto_pin_cfg *cfg)
16609 struct hda_input_mux *imux = &spec->private_imux[0];
16612 for (i = 0; i < AUTO_PIN_LAST; i++) {
16613 if (alc880_is_input_pin(cfg->input_pins[i])) {
16614 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16615 err = new_analog_input(spec, cfg->input_pins[i],
16616 auto_pin_cfg_labels[i],
16620 imux->items[imux->num_items].label =
16621 auto_pin_cfg_labels[i];
16622 imux->items[imux->num_items].index =
16623 alc880_input_pin_idx(cfg->input_pins[i]);
16630 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16631 hda_nid_t nid, int pin_type,
16634 alc_set_pin_output(codec, nid, pin_type);
16635 /* need the manual connection? */
16636 if (alc880_is_multi_pin(nid)) {
16637 struct alc_spec *spec = codec->spec;
16638 int idx = alc880_multi_pin_idx(nid);
16639 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16640 AC_VERB_SET_CONNECT_SEL,
16641 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16645 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16647 struct alc_spec *spec = codec->spec;
16650 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16651 for (i = 0; i <= HDA_SIDE; i++) {
16652 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16653 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16655 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16660 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16662 struct alc_spec *spec = codec->spec;
16665 pin = spec->autocfg.hp_pins[0];
16666 if (pin) /* connect to front */
16668 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16669 pin = spec->autocfg.speaker_pins[0];
16671 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16674 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16675 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16677 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16679 struct alc_spec *spec = codec->spec;
16682 for (i = 0; i < AUTO_PIN_LAST; i++) {
16683 hda_nid_t nid = spec->autocfg.input_pins[i];
16684 if (alc662_is_input_pin(nid)) {
16685 snd_hda_codec_write(codec, nid, 0,
16686 AC_VERB_SET_PIN_WIDGET_CONTROL,
16687 (i <= AUTO_PIN_FRONT_MIC ?
16688 PIN_VREF80 : PIN_IN));
16689 if (nid != ALC662_PIN_CD_NID)
16690 snd_hda_codec_write(codec, nid, 0,
16691 AC_VERB_SET_AMP_GAIN_MUTE,
16697 #define alc662_auto_init_input_src alc882_auto_init_input_src
16699 static int alc662_parse_auto_config(struct hda_codec *codec)
16701 struct alc_spec *spec = codec->spec;
16703 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16705 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16709 if (!spec->autocfg.line_outs)
16710 return 0; /* can't find valid BIOS pin config */
16712 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16715 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16718 err = alc662_auto_create_extra_out(spec,
16719 spec->autocfg.speaker_pins[0],
16723 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16727 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16731 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16733 if (spec->autocfg.dig_out_pin)
16734 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16736 if (spec->kctls.list)
16737 add_mixer(spec, spec->kctls.list);
16739 spec->num_mux_defs = 1;
16740 spec->input_mux = &spec->private_imux[0];
16742 add_verb(spec, alc662_auto_init_verbs);
16743 if (codec->vendor_id == 0x10ec0663)
16744 add_verb(spec, alc663_auto_init_verbs);
16746 err = alc_auto_add_mic_boost(codec);
16750 store_pin_configs(codec);
16754 /* additional initialization for auto-configuration model */
16755 static void alc662_auto_init(struct hda_codec *codec)
16757 struct alc_spec *spec = codec->spec;
16758 alc662_auto_init_multi_out(codec);
16759 alc662_auto_init_hp_out(codec);
16760 alc662_auto_init_analog_input(codec);
16761 alc662_auto_init_input_src(codec);
16762 if (spec->unsol_event)
16763 alc_inithook(codec);
16766 static int patch_alc662(struct hda_codec *codec)
16768 struct alc_spec *spec;
16769 int err, board_config;
16771 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16775 codec->spec = spec;
16777 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16779 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16782 if (board_config < 0) {
16783 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16784 "trying auto-probe from BIOS...\n");
16785 board_config = ALC662_AUTO;
16788 if (board_config == ALC662_AUTO) {
16789 /* automatic parse from the BIOS config */
16790 err = alc662_parse_auto_config(codec);
16796 "hda_codec: Cannot set up configuration "
16797 "from BIOS. Using base mode...\n");
16798 board_config = ALC662_3ST_2ch_DIG;
16802 err = snd_hda_attach_beep_device(codec, 0x1);
16808 if (board_config != ALC662_AUTO)
16809 setup_preset(spec, &alc662_presets[board_config]);
16811 if (codec->vendor_id == 0x10ec0663) {
16812 spec->stream_name_analog = "ALC663 Analog";
16813 spec->stream_name_digital = "ALC663 Digital";
16814 } else if (codec->vendor_id == 0x10ec0272) {
16815 spec->stream_name_analog = "ALC272 Analog";
16816 spec->stream_name_digital = "ALC272 Digital";
16818 spec->stream_name_analog = "ALC662 Analog";
16819 spec->stream_name_digital = "ALC662 Digital";
16822 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16823 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16825 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16826 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16828 spec->adc_nids = alc662_adc_nids;
16829 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16830 spec->capsrc_nids = alc662_capsrc_nids;
16831 spec->capture_style = CAPT_MIX;
16833 if (!spec->cap_mixer)
16834 set_capture_mixer(spec);
16836 spec->vmaster_nid = 0x02;
16838 codec->patch_ops = alc_patch_ops;
16839 if (board_config == ALC662_AUTO)
16840 spec->init_hook = alc662_auto_init;
16841 #ifdef CONFIG_SND_HDA_POWER_SAVE
16842 if (!spec->loopback.amplist)
16843 spec->loopback.amplist = alc662_loopbacks;
16845 codec->proc_widget_hook = print_realtek_coef;
16853 static struct hda_codec_preset snd_hda_preset_realtek[] = {
16854 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16855 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16856 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16857 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16858 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16859 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16860 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16861 .patch = patch_alc861 },
16862 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16863 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16864 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16865 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16866 .patch = patch_alc883 },
16867 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16868 .patch = patch_alc662 },
16869 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16870 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16871 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16872 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16873 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16874 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16875 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16876 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16877 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16878 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16879 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16880 .patch = patch_alc883 },
16881 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16882 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16883 {} /* terminator */
16886 MODULE_ALIAS("snd-hda-codec-id:10ec*");
16888 MODULE_LICENSE("GPL");
16889 MODULE_DESCRIPTION("Realtek HD-audio codec");
16891 static struct hda_codec_preset_list realtek_list = {
16892 .preset = snd_hda_preset_realtek,
16893 .owner = THIS_MODULE,
16896 static int __init patch_realtek_init(void)
16898 return snd_hda_add_codec_preset(&realtek_list);
16901 static void __exit patch_realtek_exit(void)
16903 snd_hda_delete_codec_preset(&realtek_list);
16906 module_init(patch_realtek_init)
16907 module_exit(patch_realtek_exit)