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"
33 #include "hda_patch.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,
108 ALC262_MODEL_LAST /* last tag */
117 ALC268_ACER_ASPIRE_ONE,
120 #ifdef CONFIG_SND_DEBUG
124 ALC268_MODEL_LAST /* last tag */
131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901,
134 ALC269_MODEL_LAST /* last tag */
151 /* ALC861-VD models */
172 ALC662_ASUS_EEEPC_P701,
173 ALC662_ASUS_EEEPC_EP20,
212 ALC883_TARGA_2ch_DIG,
218 ALC883_LENOVO_101E_2ch,
219 ALC883_LENOVO_NB0763,
220 ALC888_LENOVO_MS7195_DIG,
227 ALC883_FUJITSU_PI2515,
228 ALC883_3ST_6ch_INTEL,
236 #define GPIO_MASK 0x03
239 /* codec parameterization */
240 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
241 unsigned int num_mixers;
243 const struct hda_verb *init_verbs[5]; /* initialization verbs
247 unsigned int num_init_verbs;
249 char *stream_name_analog; /* analog PCM stream */
250 struct hda_pcm_stream *stream_analog_playback;
251 struct hda_pcm_stream *stream_analog_capture;
252 struct hda_pcm_stream *stream_analog_alt_playback;
253 struct hda_pcm_stream *stream_analog_alt_capture;
255 char *stream_name_digital; /* digital PCM stream */
256 struct hda_pcm_stream *stream_digital_playback;
257 struct hda_pcm_stream *stream_digital_capture;
260 struct hda_multi_out multiout; /* playback set-up
261 * max_channels, dacs must be set
262 * dig_out_nid and hp_nid are optional
264 hda_nid_t alt_dac_nid;
267 unsigned int num_adc_nids;
269 hda_nid_t *capsrc_nids;
270 hda_nid_t dig_in_nid; /* digital-in NID; optional */
273 unsigned int num_mux_defs;
274 const struct hda_input_mux *input_mux;
275 unsigned int cur_mux[3];
278 const struct hda_channel_mode *channel_mode;
279 int num_channel_mode;
282 /* PCM information */
283 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
285 /* dynamic controls, init_verbs and input_mux */
286 struct auto_pin_cfg autocfg;
287 struct snd_array kctls;
288 struct hda_input_mux private_imux;
289 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
292 void (*init_hook)(struct hda_codec *codec);
293 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
295 /* for pin sensing */
296 unsigned int sense_updated: 1;
297 unsigned int jack_present: 1;
298 unsigned int master_sw: 1;
300 /* for virtual master */
301 hda_nid_t vmaster_nid;
302 #ifdef CONFIG_SND_HDA_POWER_SAVE
303 struct hda_loopback_check loopback;
308 unsigned int pll_coef_idx, pll_coef_bit;
312 * configuration template - to be copied to the spec instance
314 struct alc_config_preset {
315 struct snd_kcontrol_new *mixers[5]; /* should be identical size
318 const struct hda_verb *init_verbs[5];
319 unsigned int num_dacs;
321 hda_nid_t dig_out_nid; /* optional */
322 hda_nid_t hp_nid; /* optional */
323 unsigned int num_adc_nids;
325 hda_nid_t *capsrc_nids;
326 hda_nid_t dig_in_nid;
327 unsigned int num_channel_mode;
328 const struct hda_channel_mode *channel_mode;
330 unsigned int num_mux_defs;
331 const struct hda_input_mux *input_mux;
332 void (*unsol_event)(struct hda_codec *, unsigned int);
333 void (*init_hook)(struct hda_codec *);
334 #ifdef CONFIG_SND_HDA_POWER_SAVE
335 struct hda_amp_list *loopbacks;
343 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_info *uinfo)
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct alc_spec *spec = codec->spec;
348 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
349 if (mux_idx >= spec->num_mux_defs)
351 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
354 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct alc_spec *spec = codec->spec;
359 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
361 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
365 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct alc_spec *spec = codec->spec;
370 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
371 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
372 hda_nid_t nid = spec->capsrc_nids ?
373 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
374 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
375 nid, &spec->cur_mux[adc_idx]);
380 * channel mode setting
382 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_info *uinfo)
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
387 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
388 spec->num_channel_mode);
391 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
392 struct snd_ctl_elem_value *ucontrol)
394 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
395 struct alc_spec *spec = codec->spec;
396 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
397 spec->num_channel_mode,
398 spec->multiout.max_channels);
401 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405 struct alc_spec *spec = codec->spec;
406 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
407 spec->num_channel_mode,
408 &spec->multiout.max_channels);
409 if (err >= 0 && spec->need_dac_fix)
410 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
415 * Control the mode of pin widget settings via the mixer. "pc" is used
416 * instead of "%" to avoid consequences of accidently treating the % as
417 * being part of a format specifier. Maximum allowed length of a value is
418 * 63 characters plus NULL terminator.
420 * Note: some retasking pin complexes seem to ignore requests for input
421 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
422 * are requested. Therefore order this list so that this behaviour will not
423 * cause problems when mixer clients move through the enum sequentially.
424 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
427 static char *alc_pin_mode_names[] = {
428 "Mic 50pc bias", "Mic 80pc bias",
429 "Line in", "Line out", "Headphone out",
431 static unsigned char alc_pin_mode_values[] = {
432 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
434 /* The control can present all 5 options, or it can limit the options based
435 * in the pin being assumed to be exclusively an input or an output pin. In
436 * addition, "input" pins may or may not process the mic bias option
437 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
438 * accept requests for bias as of chip versions up to March 2006) and/or
439 * wiring in the computer.
441 #define ALC_PIN_DIR_IN 0x00
442 #define ALC_PIN_DIR_OUT 0x01
443 #define ALC_PIN_DIR_INOUT 0x02
444 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
445 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
447 /* Info about the pin modes supported by the different pin direction modes.
448 * For each direction the minimum and maximum values are given.
450 static signed char alc_pin_mode_dir_info[5][2] = {
451 { 0, 2 }, /* ALC_PIN_DIR_IN */
452 { 3, 4 }, /* ALC_PIN_DIR_OUT */
453 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
454 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
455 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
457 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
458 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
459 #define alc_pin_mode_n_items(_dir) \
460 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
462 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
463 struct snd_ctl_elem_info *uinfo)
465 unsigned int item_num = uinfo->value.enumerated.item;
466 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
468 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
470 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
472 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
473 item_num = alc_pin_mode_min(dir);
474 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
478 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
479 struct snd_ctl_elem_value *ucontrol)
482 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
483 hda_nid_t nid = kcontrol->private_value & 0xffff;
484 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
485 long *valp = ucontrol->value.integer.value;
486 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
487 AC_VERB_GET_PIN_WIDGET_CONTROL,
490 /* Find enumerated value for current pinctl setting */
491 i = alc_pin_mode_min(dir);
492 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
494 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
498 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
502 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503 hda_nid_t nid = kcontrol->private_value & 0xffff;
504 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
505 long val = *ucontrol->value.integer.value;
506 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
507 AC_VERB_GET_PIN_WIDGET_CONTROL,
510 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
511 val = alc_pin_mode_min(dir);
513 change = pinctl != alc_pin_mode_values[val];
515 /* Set pin mode to that requested */
516 snd_hda_codec_write_cache(codec, nid, 0,
517 AC_VERB_SET_PIN_WIDGET_CONTROL,
518 alc_pin_mode_values[val]);
520 /* Also enable the retasking pin's input/output as required
521 * for the requested pin mode. Enum values of 2 or less are
524 * Dynamically switching the input/output buffers probably
525 * reduces noise slightly (particularly on input) so we'll
526 * do it. However, having both input and output buffers
527 * enabled simultaneously doesn't seem to be problematic if
528 * this turns out to be necessary in the future.
531 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
532 HDA_AMP_MUTE, HDA_AMP_MUTE);
533 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
536 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
537 HDA_AMP_MUTE, HDA_AMP_MUTE);
538 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
545 #define ALC_PIN_MODE(xname, nid, dir) \
546 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
547 .info = alc_pin_mode_info, \
548 .get = alc_pin_mode_get, \
549 .put = alc_pin_mode_put, \
550 .private_value = nid | (dir<<16) }
552 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
553 * together using a mask with more than one bit set. This control is
554 * currently used only by the ALC260 test model. At this stage they are not
555 * needed for any "production" models.
557 #ifdef CONFIG_SND_DEBUG
558 #define alc_gpio_data_info snd_ctl_boolean_mono_info
560 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564 hda_nid_t nid = kcontrol->private_value & 0xffff;
565 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
566 long *valp = ucontrol->value.integer.value;
567 unsigned int val = snd_hda_codec_read(codec, nid, 0,
568 AC_VERB_GET_GPIO_DATA, 0x00);
570 *valp = (val & mask) != 0;
573 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
577 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
578 hda_nid_t nid = kcontrol->private_value & 0xffff;
579 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
580 long val = *ucontrol->value.integer.value;
581 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
582 AC_VERB_GET_GPIO_DATA,
585 /* Set/unset the masked GPIO bit(s) as needed */
586 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
591 snd_hda_codec_write_cache(codec, nid, 0,
592 AC_VERB_SET_GPIO_DATA, gpio_data);
596 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
597 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
598 .info = alc_gpio_data_info, \
599 .get = alc_gpio_data_get, \
600 .put = alc_gpio_data_put, \
601 .private_value = nid | (mask<<16) }
602 #endif /* CONFIG_SND_DEBUG */
604 /* A switch control to allow the enabling of the digital IO pins on the
605 * ALC260. This is incredibly simplistic; the intention of this control is
606 * to provide something in the test model allowing digital outputs to be
607 * identified if present. If models are found which can utilise these
608 * outputs a more complete mixer control can be devised for those models if
611 #ifdef CONFIG_SND_DEBUG
612 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
614 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620 long *valp = ucontrol->value.integer.value;
621 unsigned int val = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
624 *valp = (val & mask) != 0;
627 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632 hda_nid_t nid = kcontrol->private_value & 0xffff;
633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634 long val = *ucontrol->value.integer.value;
635 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
636 AC_VERB_GET_DIGI_CONVERT_1,
639 /* Set/unset the masked control bit(s) as needed */
640 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
645 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
650 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
652 .info = alc_spdif_ctrl_info, \
653 .get = alc_spdif_ctrl_get, \
654 .put = alc_spdif_ctrl_put, \
655 .private_value = nid | (mask<<16) }
656 #endif /* CONFIG_SND_DEBUG */
658 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
659 * Again, this is only used in the ALC26x test models to help identify when
660 * the EAPD line must be asserted for features to work.
662 #ifdef CONFIG_SND_DEBUG
663 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
665 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
666 struct snd_ctl_elem_value *ucontrol)
668 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
669 hda_nid_t nid = kcontrol->private_value & 0xffff;
670 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
671 long *valp = ucontrol->value.integer.value;
672 unsigned int val = snd_hda_codec_read(codec, nid, 0,
673 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
675 *valp = (val & mask) != 0;
679 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684 hda_nid_t nid = kcontrol->private_value & 0xffff;
685 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686 long val = *ucontrol->value.integer.value;
687 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
688 AC_VERB_GET_EAPD_BTLENABLE,
691 /* Set/unset the masked control bit(s) as needed */
692 change = (!val ? 0 : mask) != (ctrl_data & mask);
697 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
703 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
704 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
705 .info = alc_eapd_ctrl_info, \
706 .get = alc_eapd_ctrl_get, \
707 .put = alc_eapd_ctrl_put, \
708 .private_value = nid | (mask<<16) }
709 #endif /* CONFIG_SND_DEBUG */
712 * set up from the preset table
714 static void setup_preset(struct alc_spec *spec,
715 const struct alc_config_preset *preset)
719 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
720 spec->mixers[spec->num_mixers++] = preset->mixers[i];
721 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
723 spec->init_verbs[spec->num_init_verbs++] =
724 preset->init_verbs[i];
726 spec->channel_mode = preset->channel_mode;
727 spec->num_channel_mode = preset->num_channel_mode;
728 spec->need_dac_fix = preset->need_dac_fix;
730 spec->multiout.max_channels = spec->channel_mode[0].channels;
732 spec->multiout.num_dacs = preset->num_dacs;
733 spec->multiout.dac_nids = preset->dac_nids;
734 spec->multiout.dig_out_nid = preset->dig_out_nid;
735 spec->multiout.hp_nid = preset->hp_nid;
737 spec->num_mux_defs = preset->num_mux_defs;
738 if (!spec->num_mux_defs)
739 spec->num_mux_defs = 1;
740 spec->input_mux = preset->input_mux;
742 spec->num_adc_nids = preset->num_adc_nids;
743 spec->adc_nids = preset->adc_nids;
744 spec->capsrc_nids = preset->capsrc_nids;
745 spec->dig_in_nid = preset->dig_in_nid;
747 spec->unsol_event = preset->unsol_event;
748 spec->init_hook = preset->init_hook;
749 #ifdef CONFIG_SND_HDA_POWER_SAVE
750 spec->loopback.amplist = preset->loopbacks;
754 /* Enable GPIO mask and set output */
755 static struct hda_verb alc_gpio1_init_verbs[] = {
756 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
757 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
758 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
762 static struct hda_verb alc_gpio2_init_verbs[] = {
763 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
764 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
765 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
769 static struct hda_verb alc_gpio3_init_verbs[] = {
770 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
771 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
772 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
777 * Fix hardware PLL issue
778 * On some codecs, the analog PLL gating control must be off while
779 * the default value is 1.
781 static void alc_fix_pll(struct hda_codec *codec)
783 struct alc_spec *spec = codec->spec;
788 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
790 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
791 AC_VERB_GET_PROC_COEF, 0);
792 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
794 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
795 val & ~(1 << spec->pll_coef_bit));
798 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
799 unsigned int coef_idx, unsigned int coef_bit)
801 struct alc_spec *spec = codec->spec;
803 spec->pll_coef_idx = coef_idx;
804 spec->pll_coef_bit = coef_bit;
808 static void alc_sku_automute(struct hda_codec *codec)
810 struct alc_spec *spec = codec->spec;
811 unsigned int present;
812 unsigned int hp_nid = spec->autocfg.hp_pins[0];
813 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
815 /* need to execute and sync at first */
816 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
817 present = snd_hda_codec_read(codec, hp_nid, 0,
818 AC_VERB_GET_PIN_SENSE, 0);
819 spec->jack_present = (present & 0x80000000) != 0;
820 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
821 spec->jack_present ? 0 : PIN_OUT);
824 static void alc_mic_automute(struct hda_codec *codec)
826 struct alc_spec *spec = codec->spec;
827 unsigned int present;
828 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
829 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
830 unsigned int mix_nid = spec->capsrc_nids[0];
831 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
833 capsrc_idx_mic = mic_nid - 0x18;
834 capsrc_idx_fmic = fmic_nid - 0x18;
835 present = snd_hda_codec_read(codec, mic_nid, 0,
836 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
837 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
838 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
839 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
840 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
841 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
842 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
845 /* unsolicited event for HP jack sensing */
846 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
848 if (codec->vendor_id == 0x10ec0880)
852 if (res == ALC880_HP_EVENT)
853 alc_sku_automute(codec);
855 if (res == ALC880_MIC_EVENT)
856 alc_mic_automute(codec);
859 static void alc_inithook(struct hda_codec *codec)
861 alc_sku_automute(codec);
862 alc_mic_automute(codec);
865 /* additional initialization for ALC888 variants */
866 static void alc888_coef_init(struct hda_codec *codec)
870 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
871 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
872 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
873 if ((tmp & 0xf0) == 2)
875 snd_hda_codec_read(codec, 0x20, 0,
876 AC_VERB_SET_PROC_COEF, 0x830);
879 snd_hda_codec_read(codec, 0x20, 0,
880 AC_VERB_SET_PROC_COEF, 0x3030);
883 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
884 * 31 ~ 16 : Manufacture ID
886 * 7 ~ 0 : Assembly ID
887 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
889 static void alc_subsystem_id(struct hda_codec *codec,
890 unsigned int porta, unsigned int porte,
893 unsigned int ass, tmp, i;
895 struct alc_spec *spec = codec->spec;
897 ass = codec->subsystem_id & 0xffff;
898 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
902 * 31~30 : port conetcivity
905 * 19~16 : Check sum (15:1)
910 if (codec->vendor_id == 0x10ec0260)
912 ass = snd_hda_codec_read(codec, nid, 0,
913 AC_VERB_GET_CONFIG_DEFAULT, 0);
914 if (!(ass & 1) && !(ass & 0x100000))
916 if ((ass >> 30) != 1) /* no physical connection */
921 for (i = 1; i < 16; i++) {
925 if (((ass >> 16) & 0xf) != tmp)
931 * 2 : 0 --> Desktop, 1 --> Laptop
932 * 3~5 : External Amplifier control
935 tmp = (ass & 0x38) >> 3; /* external Amp control */
938 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
941 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
944 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
946 case 5: /* set EAPD output high */
947 switch (codec->vendor_id) {
949 snd_hda_codec_write(codec, 0x0f, 0,
950 AC_VERB_SET_EAPD_BTLENABLE, 2);
951 snd_hda_codec_write(codec, 0x10, 0,
952 AC_VERB_SET_EAPD_BTLENABLE, 2);
963 snd_hda_codec_write(codec, 0x14, 0,
964 AC_VERB_SET_EAPD_BTLENABLE, 2);
965 snd_hda_codec_write(codec, 0x15, 0,
966 AC_VERB_SET_EAPD_BTLENABLE, 2);
969 switch (codec->vendor_id) {
971 snd_hda_codec_write(codec, 0x1a, 0,
972 AC_VERB_SET_COEF_INDEX, 7);
973 tmp = snd_hda_codec_read(codec, 0x1a, 0,
974 AC_VERB_GET_PROC_COEF, 0);
975 snd_hda_codec_write(codec, 0x1a, 0,
976 AC_VERB_SET_COEF_INDEX, 7);
977 snd_hda_codec_write(codec, 0x1a, 0,
978 AC_VERB_SET_PROC_COEF,
987 snd_hda_codec_write(codec, 0x20, 0,
988 AC_VERB_SET_COEF_INDEX, 7);
989 tmp = snd_hda_codec_read(codec, 0x20, 0,
990 AC_VERB_GET_PROC_COEF, 0);
991 snd_hda_codec_write(codec, 0x20, 0,
992 AC_VERB_SET_COEF_INDEX, 7);
993 snd_hda_codec_write(codec, 0x20, 0,
994 AC_VERB_SET_PROC_COEF,
998 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1002 snd_hda_codec_write(codec, 0x20, 0,
1003 AC_VERB_SET_COEF_INDEX, 7);
1004 tmp = snd_hda_codec_read(codec, 0x20, 0,
1005 AC_VERB_GET_PROC_COEF, 0);
1006 snd_hda_codec_write(codec, 0x20, 0,
1007 AC_VERB_SET_COEF_INDEX, 7);
1008 snd_hda_codec_write(codec, 0x20, 0,
1009 AC_VERB_SET_PROC_COEF,
1017 /* is laptop or Desktop and enable the function "Mute internal speaker
1018 * when the external headphone out jack is plugged"
1020 if (!(ass & 0x8000))
1023 * 10~8 : Jack location
1024 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1026 * 15 : 1 --> enable the function "Mute internal speaker
1027 * when the external headphone out jack is plugged"
1029 if (!spec->autocfg.speaker_pins[0]) {
1030 if (spec->autocfg.line_out_pins[0])
1031 spec->autocfg.speaker_pins[0] =
1032 spec->autocfg.line_out_pins[0];
1037 if (!spec->autocfg.hp_pins[0]) {
1038 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1040 spec->autocfg.hp_pins[0] = porta;
1042 spec->autocfg.hp_pins[0] = porte;
1044 spec->autocfg.hp_pins[0] = portd;
1048 if (spec->autocfg.hp_pins[0])
1049 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1050 AC_VERB_SET_UNSOLICITED_ENABLE,
1051 AC_USRSP_EN | ALC880_HP_EVENT);
1053 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1054 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1055 snd_hda_codec_write(codec,
1056 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1057 AC_VERB_SET_UNSOLICITED_ENABLE,
1058 AC_USRSP_EN | ALC880_MIC_EVENT);
1060 spec->unsol_event = alc_sku_unsol_event;
1064 * Fix-up pin default configurations
1072 static void alc_fix_pincfg(struct hda_codec *codec,
1073 const struct snd_pci_quirk *quirk,
1074 const struct alc_pincfg **pinfix)
1076 const struct alc_pincfg *cfg;
1078 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1082 cfg = pinfix[quirk->value];
1083 for (; cfg->nid; cfg++) {
1086 for (i = 0; i < 4; i++) {
1087 snd_hda_codec_write(codec, cfg->nid, 0,
1088 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1096 * ALC880 3-stack model
1098 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1099 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1100 * F-Mic = 0x1b, HP = 0x19
1103 static hda_nid_t alc880_dac_nids[4] = {
1104 /* front, rear, clfe, rear_surr */
1105 0x02, 0x05, 0x04, 0x03
1108 static hda_nid_t alc880_adc_nids[3] = {
1113 /* The datasheet says the node 0x07 is connected from inputs,
1114 * but it shows zero connection in the real implementation on some devices.
1115 * Note: this is a 915GAV bug, fixed on 915GLV
1117 static hda_nid_t alc880_adc_nids_alt[2] = {
1122 #define ALC880_DIGOUT_NID 0x06
1123 #define ALC880_DIGIN_NID 0x0a
1125 static struct hda_input_mux alc880_capture_source = {
1129 { "Front Mic", 0x3 },
1135 /* channel source setting (2/6 channel selection for 3-stack) */
1137 static struct hda_verb alc880_threestack_ch2_init[] = {
1138 /* set line-in to input, mute it */
1139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1141 /* set mic-in to input vref 80%, mute it */
1142 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1143 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1148 static struct hda_verb alc880_threestack_ch6_init[] = {
1149 /* set line-in to output, unmute it */
1150 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1151 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1152 /* set mic-in to output, unmute it */
1153 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1154 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1158 static struct hda_channel_mode alc880_threestack_modes[2] = {
1159 { 2, alc880_threestack_ch2_init },
1160 { 6, alc880_threestack_ch6_init },
1163 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1166 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1167 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1168 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1169 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1170 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1171 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1172 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1173 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1175 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1178 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1179 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1180 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1181 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1182 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1185 .name = "Channel Mode",
1186 .info = alc_ch_mode_info,
1187 .get = alc_ch_mode_get,
1188 .put = alc_ch_mode_put,
1193 /* capture mixer elements */
1194 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1195 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1196 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1197 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1198 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1199 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1200 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1202 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1203 /* The multiple "Capture Source" controls confuse alsamixer
1204 * So call somewhat different..
1206 /* .name = "Capture Source", */
1207 .name = "Input Source",
1209 .info = alc_mux_enum_info,
1210 .get = alc_mux_enum_get,
1211 .put = alc_mux_enum_put,
1216 /* capture mixer elements (in case NID 0x07 not available) */
1217 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1218 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1219 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1220 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1221 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1223 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1224 /* The multiple "Capture Source" controls confuse alsamixer
1225 * So call somewhat different..
1227 /* .name = "Capture Source", */
1228 .name = "Input Source",
1230 .info = alc_mux_enum_info,
1231 .get = alc_mux_enum_get,
1232 .put = alc_mux_enum_put,
1240 * ALC880 5-stack model
1242 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1244 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1245 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1248 /* additional mixers to alc880_three_stack_mixer */
1249 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1250 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1251 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1255 /* channel source setting (6/8 channel selection for 5-stack) */
1257 static struct hda_verb alc880_fivestack_ch6_init[] = {
1258 /* set line-in to input, mute it */
1259 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1260 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1265 static struct hda_verb alc880_fivestack_ch8_init[] = {
1266 /* set line-in to output, unmute it */
1267 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1268 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1272 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1273 { 6, alc880_fivestack_ch6_init },
1274 { 8, alc880_fivestack_ch8_init },
1279 * ALC880 6-stack model
1281 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1282 * Side = 0x05 (0x0f)
1283 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1284 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1287 static hda_nid_t alc880_6st_dac_nids[4] = {
1288 /* front, rear, clfe, rear_surr */
1289 0x02, 0x03, 0x04, 0x05
1292 static struct hda_input_mux alc880_6stack_capture_source = {
1296 { "Front Mic", 0x1 },
1302 /* fixed 8-channels */
1303 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1307 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1309 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1310 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1311 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1312 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1313 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1314 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1315 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1316 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1317 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1318 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1319 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1320 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1321 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1323 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1324 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1325 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1326 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1327 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1329 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1330 .name = "Channel Mode",
1331 .info = alc_ch_mode_info,
1332 .get = alc_ch_mode_get,
1333 .put = alc_ch_mode_put,
1342 * W810 has rear IO for:
1345 * Center/LFE (DAC 04)
1348 * The system also has a pair of internal speakers, and a headphone jack.
1349 * These are both connected to Line2 on the codec, hence to DAC 02.
1351 * There is a variable resistor to control the speaker or headphone
1352 * volume. This is a hardware-only device without a software API.
1354 * Plugging headphones in will disable the internal speakers. This is
1355 * implemented in hardware, not via the driver using jack sense. In
1356 * a similar fashion, plugging into the rear socket marked "front" will
1357 * disable both the speakers and headphones.
1359 * For input, there's a microphone jack, and an "audio in" jack.
1360 * These may not do anything useful with this driver yet, because I
1361 * haven't setup any initialization verbs for these yet...
1364 static hda_nid_t alc880_w810_dac_nids[3] = {
1365 /* front, rear/surround, clfe */
1369 /* fixed 6 channels */
1370 static struct hda_channel_mode alc880_w810_modes[1] = {
1374 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1375 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1376 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1377 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1378 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1379 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1380 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1381 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1382 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1383 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1392 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1393 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1397 static hda_nid_t alc880_z71v_dac_nids[1] = {
1400 #define ALC880_Z71V_HP_DAC 0x03
1402 /* fixed 2 channels */
1403 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1407 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1408 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1409 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1410 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1411 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1412 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1413 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1414 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1415 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1421 * ALC880 F1734 model
1423 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1424 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1427 static hda_nid_t alc880_f1734_dac_nids[1] = {
1430 #define ALC880_F1734_HP_DAC 0x02
1432 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1433 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1434 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1436 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1437 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1438 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1444 static struct hda_input_mux alc880_f1734_capture_source = {
1456 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1457 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1458 * Mic = 0x18, Line = 0x1a
1461 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1462 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1464 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1465 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1466 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1468 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1471 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1473 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1474 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1475 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1476 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1481 .name = "Channel Mode",
1482 .info = alc_ch_mode_info,
1483 .get = alc_ch_mode_get,
1484 .put = alc_ch_mode_put,
1490 * ALC880 ASUS W1V model
1492 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1493 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1494 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1497 /* additional mixers to alc880_asus_mixer */
1498 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1499 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1500 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1504 /* additional mixers to alc880_asus_mixer */
1505 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1506 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1507 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1512 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1514 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1515 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1516 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1517 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1518 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1519 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1520 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1521 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1524 /* The multiple "Capture Source" controls confuse alsamixer
1525 * So call somewhat different..
1527 /* .name = "Capture Source", */
1528 .name = "Input Source",
1530 .info = alc_mux_enum_info,
1531 .get = alc_mux_enum_get,
1532 .put = alc_mux_enum_put,
1538 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1539 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1540 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1541 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1542 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1543 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1544 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1545 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1546 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1547 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1548 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1549 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1550 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1553 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1554 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1555 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1556 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1559 .name = "Channel Mode",
1560 .info = alc_ch_mode_info,
1561 .get = alc_ch_mode_get,
1562 .put = alc_ch_mode_put,
1567 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1568 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1569 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1570 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1571 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1572 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1574 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1575 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1576 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1577 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1581 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1582 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1583 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1584 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1585 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1592 * virtual master controls
1596 * slave controls for virtual master
1598 static const char *alc_slave_vols[] = {
1599 "Front Playback Volume",
1600 "Surround Playback Volume",
1601 "Center Playback Volume",
1602 "LFE Playback Volume",
1603 "Side Playback Volume",
1604 "Headphone Playback Volume",
1605 "Speaker Playback Volume",
1606 "Mono Playback Volume",
1607 "Line-Out Playback Volume",
1611 static const char *alc_slave_sws[] = {
1612 "Front Playback Switch",
1613 "Surround Playback Switch",
1614 "Center Playback Switch",
1615 "LFE Playback Switch",
1616 "Side Playback Switch",
1617 "Headphone Playback Switch",
1618 "Speaker Playback Switch",
1619 "Mono Playback Switch",
1620 "IEC958 Playback Switch",
1625 * build control elements
1628 static void alc_free_kctls(struct hda_codec *codec);
1630 static int alc_build_controls(struct hda_codec *codec)
1632 struct alc_spec *spec = codec->spec;
1636 for (i = 0; i < spec->num_mixers; i++) {
1637 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1642 if (spec->multiout.dig_out_nid) {
1643 err = snd_hda_create_spdif_out_ctls(codec,
1644 spec->multiout.dig_out_nid);
1647 err = snd_hda_create_spdif_share_sw(codec,
1651 spec->multiout.share_spdif = 1;
1653 if (spec->dig_in_nid) {
1654 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1659 /* if we have no master control, let's create it */
1660 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1661 unsigned int vmaster_tlv[4];
1662 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1663 HDA_OUTPUT, vmaster_tlv);
1664 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1665 vmaster_tlv, alc_slave_vols);
1669 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1670 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1671 NULL, alc_slave_sws);
1676 alc_free_kctls(codec); /* no longer needed */
1682 * initialize the codec volumes, etc
1686 * generic initialization of ADC, input mixers and output mixers
1688 static struct hda_verb alc880_volume_init_verbs[] = {
1690 * Unmute ADC0-2 and set the default input to mic-in
1692 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1694 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1695 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1696 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1697 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1699 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1701 * Note: PASD motherboards uses the Line In 2 as the input for front
1704 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1714 * Set up output mixers (0x0c - 0x0f)
1716 /* set vol=0 to output mixers */
1717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1718 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1719 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1720 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1721 /* set up input amps for analog loopback */
1722 /* Amp Indices: DAC = 0, mixer = 1 */
1723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1729 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1730 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1736 * 3-stack pin configuration:
1737 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1739 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1741 * preset connection lists of input pins
1742 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1744 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1745 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1746 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1749 * Set pin mode and muting
1751 /* set front pin widgets 0x14 for output */
1752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1754 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1755 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757 /* Mic2 (as headphone out) for HP output */
1758 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1760 /* Line In pin widget for input */
1761 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1763 /* Line2 (as front mic) pin widget for input and vref at 80% */
1764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1765 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1766 /* CD pin widget for input */
1767 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1773 * 5-stack pin configuration:
1774 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1775 * line-in/side = 0x1a, f-mic = 0x1b
1777 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1779 * preset connection lists of input pins
1780 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1782 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1783 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1786 * Set pin mode and muting
1788 /* set pin widgets 0x14-0x17 for output */
1789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1790 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1791 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1792 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1793 /* unmute pins for output (no gain on this amp) */
1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1799 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1800 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1801 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1802 /* Mic2 (as headphone out) for HP output */
1803 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1804 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1805 /* Line In pin widget for input */
1806 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1807 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1808 /* Line2 (as front mic) pin widget for input and vref at 80% */
1809 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1810 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1811 /* CD pin widget for input */
1812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1818 * W810 pin configuration:
1819 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1821 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1822 /* hphone/speaker input selector: front DAC */
1823 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1826 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1827 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1829 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1832 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1833 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1839 * Z71V pin configuration:
1840 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1842 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1849 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1850 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1851 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1857 * 6-stack pin configuration:
1858 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1859 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1861 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1862 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1864 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1869 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1871 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1874 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1875 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1876 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1877 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1879 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1880 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1887 * Uniwill pin configuration:
1888 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1891 static struct hda_verb alc880_uniwill_init_verbs[] = {
1892 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1894 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1895 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1898 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1899 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1900 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1901 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1904 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1905 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1906 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1907 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1910 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1911 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1912 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1915 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1916 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1917 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1919 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1920 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1927 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1929 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1930 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1933 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1935 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1936 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1937 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1939 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1940 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1941 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1942 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1943 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1945 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1946 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1947 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1948 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1949 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1950 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1952 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1953 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1958 static struct hda_verb alc880_beep_init_verbs[] = {
1959 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1963 /* toggle speaker-output according to the hp-jack state */
1964 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1966 unsigned int present;
1969 present = snd_hda_codec_read(codec, 0x14, 0,
1970 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1971 bits = present ? HDA_AMP_MUTE : 0;
1972 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1973 HDA_AMP_MUTE, bits);
1974 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1975 HDA_AMP_MUTE, bits);
1978 /* auto-toggle front mic */
1979 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1981 unsigned int present;
1984 present = snd_hda_codec_read(codec, 0x18, 0,
1985 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1986 bits = present ? HDA_AMP_MUTE : 0;
1987 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1990 static void alc880_uniwill_automute(struct hda_codec *codec)
1992 alc880_uniwill_hp_automute(codec);
1993 alc880_uniwill_mic_automute(codec);
1996 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1999 /* Looks like the unsol event is incompatible with the standard
2000 * definition. 4bit tag is placed at 28 bit!
2002 switch (res >> 28) {
2003 case ALC880_HP_EVENT:
2004 alc880_uniwill_hp_automute(codec);
2006 case ALC880_MIC_EVENT:
2007 alc880_uniwill_mic_automute(codec);
2012 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2014 unsigned int present;
2017 present = snd_hda_codec_read(codec, 0x14, 0,
2018 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2019 bits = present ? HDA_AMP_MUTE : 0;
2020 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2023 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2025 unsigned int present;
2027 present = snd_hda_codec_read(codec, 0x21, 0,
2028 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2029 present &= HDA_AMP_VOLMASK;
2030 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2031 HDA_AMP_VOLMASK, present);
2032 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2033 HDA_AMP_VOLMASK, present);
2036 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2039 /* Looks like the unsol event is incompatible with the standard
2040 * definition. 4bit tag is placed at 28 bit!
2042 if ((res >> 28) == ALC880_HP_EVENT)
2043 alc880_uniwill_p53_hp_automute(codec);
2044 if ((res >> 28) == ALC880_DCVOL_EVENT)
2045 alc880_uniwill_p53_dcvol_automute(codec);
2049 * F1734 pin configuration:
2050 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2052 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2053 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2054 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2055 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2056 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2057 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2064 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2065 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2066 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2067 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2068 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2069 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2070 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2071 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2072 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2074 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2081 * ASUS pin configuration:
2082 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2084 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2085 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2086 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2087 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2088 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2092 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2093 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2094 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2095 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2096 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2097 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2099 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2100 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2102 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2105 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2112 /* Enable GPIO mask and set output */
2113 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2114 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2116 /* Clevo m520g init */
2117 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2118 /* headphone output */
2119 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2121 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2122 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2124 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2125 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2127 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2128 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2129 /* Mic1 (rear panel) */
2130 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2131 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2132 /* Mic2 (front panel) */
2133 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2134 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2136 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2138 /* change to EAPD mode */
2139 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2140 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2145 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2146 /* change to EAPD mode */
2147 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2148 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2150 /* Headphone output */
2151 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2156 /* Line In pin widget for input */
2157 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2158 /* CD pin widget for input */
2159 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2160 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2161 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2163 /* change to EAPD mode */
2164 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2165 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2171 * LG m1 express dual
2174 * Rear Line-In/Out (blue): 0x14
2175 * Build-in Mic-In: 0x15
2177 * HP-Out (green): 0x1b
2178 * Mic-In/Out (red): 0x19
2182 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2183 static hda_nid_t alc880_lg_dac_nids[3] = {
2187 /* seems analog CD is not working */
2188 static struct hda_input_mux alc880_lg_capture_source = {
2193 { "Internal Mic", 0x6 },
2197 /* 2,4,6 channel modes */
2198 static struct hda_verb alc880_lg_ch2_init[] = {
2199 /* set line-in and mic-in to input */
2200 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2201 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2205 static struct hda_verb alc880_lg_ch4_init[] = {
2206 /* set line-in to out and mic-in to input */
2207 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2208 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2212 static struct hda_verb alc880_lg_ch6_init[] = {
2213 /* set line-in and mic-in to output */
2214 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2215 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2219 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2220 { 2, alc880_lg_ch2_init },
2221 { 4, alc880_lg_ch4_init },
2222 { 6, alc880_lg_ch6_init },
2225 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2226 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2228 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2229 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2230 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2231 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2232 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2233 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2234 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2236 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2237 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2238 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2239 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2242 .name = "Channel Mode",
2243 .info = alc_ch_mode_info,
2244 .get = alc_ch_mode_get,
2245 .put = alc_ch_mode_put,
2250 static struct hda_verb alc880_lg_init_verbs[] = {
2251 /* set capture source to mic-in */
2252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2253 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2254 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2255 /* mute all amp mixer inputs */
2256 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2257 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2258 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2259 /* line-in to input */
2260 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2261 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2267 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2268 /* mic-in to input */
2269 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2270 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2271 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2274 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2275 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2281 /* toggle speaker-output according to the hp-jack state */
2282 static void alc880_lg_automute(struct hda_codec *codec)
2284 unsigned int present;
2287 present = snd_hda_codec_read(codec, 0x1b, 0,
2288 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2289 bits = present ? HDA_AMP_MUTE : 0;
2290 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2291 HDA_AMP_MUTE, bits);
2294 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2296 /* Looks like the unsol event is incompatible with the standard
2297 * definition. 4bit tag is placed at 28 bit!
2299 if ((res >> 28) == 0x01)
2300 alc880_lg_automute(codec);
2309 * Built-in Mic-In: 0x19
2315 static struct hda_input_mux alc880_lg_lw_capture_source = {
2319 { "Internal Mic", 0x1 },
2324 #define alc880_lg_lw_modes alc880_threestack_modes
2326 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2328 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2329 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2330 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2331 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2332 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2333 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2334 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2335 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2336 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2339 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2340 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2342 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2343 .name = "Channel Mode",
2344 .info = alc_ch_mode_info,
2345 .get = alc_ch_mode_get,
2346 .put = alc_ch_mode_put,
2351 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2352 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2353 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2354 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2356 /* set capture source to mic-in */
2357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2358 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2359 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2360 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2362 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2363 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367 /* mic-in to input */
2368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2372 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2374 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2378 /* toggle speaker-output according to the hp-jack state */
2379 static void alc880_lg_lw_automute(struct hda_codec *codec)
2381 unsigned int present;
2384 present = snd_hda_codec_read(codec, 0x1b, 0,
2385 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2386 bits = present ? HDA_AMP_MUTE : 0;
2387 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2388 HDA_AMP_MUTE, bits);
2391 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2393 /* Looks like the unsol event is incompatible with the standard
2394 * definition. 4bit tag is placed at 28 bit!
2396 if ((res >> 28) == 0x01)
2397 alc880_lg_lw_automute(codec);
2400 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2401 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2402 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2405 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2406 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2410 static struct hda_input_mux alc880_medion_rim_capture_source = {
2414 { "Internal Mic", 0x1 },
2418 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2419 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2422 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2424 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2425 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2426 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2427 /* Mic2 (as headphone out) for HP output */
2428 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2429 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2430 /* Internal Speaker */
2431 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2432 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2434 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2435 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2437 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2441 /* toggle speaker-output according to the hp-jack state */
2442 static void alc880_medion_rim_automute(struct hda_codec *codec)
2444 unsigned int present;
2447 present = snd_hda_codec_read(codec, 0x14, 0,
2448 AC_VERB_GET_PIN_SENSE, 0)
2449 & AC_PINSENSE_PRESENCE;
2450 bits = present ? HDA_AMP_MUTE : 0;
2451 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2452 HDA_AMP_MUTE, bits);
2454 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2456 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2459 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2462 /* Looks like the unsol event is incompatible with the standard
2463 * definition. 4bit tag is placed at 28 bit!
2465 if ((res >> 28) == ALC880_HP_EVENT)
2466 alc880_medion_rim_automute(codec);
2469 #ifdef CONFIG_SND_HDA_POWER_SAVE
2470 static struct hda_amp_list alc880_loopbacks[] = {
2471 { 0x0b, HDA_INPUT, 0 },
2472 { 0x0b, HDA_INPUT, 1 },
2473 { 0x0b, HDA_INPUT, 2 },
2474 { 0x0b, HDA_INPUT, 3 },
2475 { 0x0b, HDA_INPUT, 4 },
2479 static struct hda_amp_list alc880_lg_loopbacks[] = {
2480 { 0x0b, HDA_INPUT, 1 },
2481 { 0x0b, HDA_INPUT, 6 },
2482 { 0x0b, HDA_INPUT, 7 },
2491 static int alc_init(struct hda_codec *codec)
2493 struct alc_spec *spec = codec->spec;
2497 if (codec->vendor_id == 0x10ec0888)
2498 alc888_coef_init(codec);
2500 for (i = 0; i < spec->num_init_verbs; i++)
2501 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2503 if (spec->init_hook)
2504 spec->init_hook(codec);
2509 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2511 struct alc_spec *spec = codec->spec;
2513 if (spec->unsol_event)
2514 spec->unsol_event(codec, res);
2517 #ifdef CONFIG_SND_HDA_POWER_SAVE
2518 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2520 struct alc_spec *spec = codec->spec;
2521 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2526 * Analog playback callbacks
2528 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2529 struct hda_codec *codec,
2530 struct snd_pcm_substream *substream)
2532 struct alc_spec *spec = codec->spec;
2533 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2537 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2538 struct hda_codec *codec,
2539 unsigned int stream_tag,
2540 unsigned int format,
2541 struct snd_pcm_substream *substream)
2543 struct alc_spec *spec = codec->spec;
2544 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2545 stream_tag, format, substream);
2548 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2549 struct hda_codec *codec,
2550 struct snd_pcm_substream *substream)
2552 struct alc_spec *spec = codec->spec;
2553 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2559 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2560 struct hda_codec *codec,
2561 struct snd_pcm_substream *substream)
2563 struct alc_spec *spec = codec->spec;
2564 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2567 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2568 struct hda_codec *codec,
2569 unsigned int stream_tag,
2570 unsigned int format,
2571 struct snd_pcm_substream *substream)
2573 struct alc_spec *spec = codec->spec;
2574 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2575 stream_tag, format, substream);
2578 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2579 struct hda_codec *codec,
2580 struct snd_pcm_substream *substream)
2582 struct alc_spec *spec = codec->spec;
2583 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2589 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2590 struct hda_codec *codec,
2591 unsigned int stream_tag,
2592 unsigned int format,
2593 struct snd_pcm_substream *substream)
2595 struct alc_spec *spec = codec->spec;
2597 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2598 stream_tag, 0, format);
2602 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2603 struct hda_codec *codec,
2604 struct snd_pcm_substream *substream)
2606 struct alc_spec *spec = codec->spec;
2608 snd_hda_codec_cleanup_stream(codec,
2609 spec->adc_nids[substream->number + 1]);
2616 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2620 /* NID is set in alc_build_pcms */
2622 .open = alc880_playback_pcm_open,
2623 .prepare = alc880_playback_pcm_prepare,
2624 .cleanup = alc880_playback_pcm_cleanup
2628 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2632 /* NID is set in alc_build_pcms */
2635 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2639 /* NID is set in alc_build_pcms */
2642 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2643 .substreams = 2, /* can be overridden */
2646 /* NID is set in alc_build_pcms */
2648 .prepare = alc880_alt_capture_pcm_prepare,
2649 .cleanup = alc880_alt_capture_pcm_cleanup
2653 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2657 /* NID is set in alc_build_pcms */
2659 .open = alc880_dig_playback_pcm_open,
2660 .close = alc880_dig_playback_pcm_close,
2661 .prepare = alc880_dig_playback_pcm_prepare
2665 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2669 /* NID is set in alc_build_pcms */
2672 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2673 static struct hda_pcm_stream alc_pcm_null_stream = {
2679 static int alc_build_pcms(struct hda_codec *codec)
2681 struct alc_spec *spec = codec->spec;
2682 struct hda_pcm *info = spec->pcm_rec;
2685 codec->num_pcms = 1;
2686 codec->pcm_info = info;
2688 info->name = spec->stream_name_analog;
2689 if (spec->stream_analog_playback) {
2690 if (snd_BUG_ON(!spec->multiout.dac_nids))
2692 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2693 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2695 if (spec->stream_analog_capture) {
2696 if (snd_BUG_ON(!spec->adc_nids))
2698 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2699 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2702 if (spec->channel_mode) {
2703 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2704 for (i = 0; i < spec->num_channel_mode; i++) {
2705 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2706 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2711 /* SPDIF for stream index #1 */
2712 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2713 codec->num_pcms = 2;
2714 info = spec->pcm_rec + 1;
2715 info->name = spec->stream_name_digital;
2716 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2717 if (spec->multiout.dig_out_nid &&
2718 spec->stream_digital_playback) {
2719 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2720 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2722 if (spec->dig_in_nid &&
2723 spec->stream_digital_capture) {
2724 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2725 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2727 /* FIXME: do we need this for all Realtek codec models? */
2728 codec->spdif_status_reset = 1;
2731 /* If the use of more than one ADC is requested for the current
2732 * model, configure a second analog capture-only PCM.
2734 /* Additional Analaog capture for index #2 */
2735 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2736 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2737 codec->num_pcms = 3;
2738 info = spec->pcm_rec + 2;
2739 info->name = spec->stream_name_analog;
2740 if (spec->alt_dac_nid) {
2741 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2742 *spec->stream_analog_alt_playback;
2743 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2746 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2747 alc_pcm_null_stream;
2748 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2750 if (spec->num_adc_nids > 1) {
2751 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2752 *spec->stream_analog_alt_capture;
2753 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2755 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2756 spec->num_adc_nids - 1;
2758 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2759 alc_pcm_null_stream;
2760 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2767 static void alc_free_kctls(struct hda_codec *codec)
2769 struct alc_spec *spec = codec->spec;
2771 if (spec->kctls.list) {
2772 struct snd_kcontrol_new *kctl = spec->kctls.list;
2774 for (i = 0; i < spec->kctls.used; i++)
2775 kfree(kctl[i].name);
2777 snd_array_free(&spec->kctls);
2780 static void alc_free(struct hda_codec *codec)
2782 struct alc_spec *spec = codec->spec;
2787 alc_free_kctls(codec);
2789 codec->spec = NULL; /* to be sure */
2794 static struct hda_codec_ops alc_patch_ops = {
2795 .build_controls = alc_build_controls,
2796 .build_pcms = alc_build_pcms,
2799 .unsol_event = alc_unsol_event,
2800 #ifdef CONFIG_SND_HDA_POWER_SAVE
2801 .check_power_status = alc_check_power_status,
2807 * Test configuration for debugging
2809 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2812 #ifdef CONFIG_SND_DEBUG
2813 static hda_nid_t alc880_test_dac_nids[4] = {
2814 0x02, 0x03, 0x04, 0x05
2817 static struct hda_input_mux alc880_test_capture_source = {
2826 { "Surround", 0x6 },
2830 static struct hda_channel_mode alc880_test_modes[4] = {
2837 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2838 struct snd_ctl_elem_info *uinfo)
2840 static char *texts[] = {
2841 "N/A", "Line Out", "HP Out",
2842 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2844 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2846 uinfo->value.enumerated.items = 8;
2847 if (uinfo->value.enumerated.item >= 8)
2848 uinfo->value.enumerated.item = 7;
2849 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2853 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2854 struct snd_ctl_elem_value *ucontrol)
2856 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2857 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2858 unsigned int pin_ctl, item = 0;
2860 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2861 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2862 if (pin_ctl & AC_PINCTL_OUT_EN) {
2863 if (pin_ctl & AC_PINCTL_HP_EN)
2867 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2868 switch (pin_ctl & AC_PINCTL_VREFEN) {
2869 case AC_PINCTL_VREF_HIZ: item = 3; break;
2870 case AC_PINCTL_VREF_50: item = 4; break;
2871 case AC_PINCTL_VREF_GRD: item = 5; break;
2872 case AC_PINCTL_VREF_80: item = 6; break;
2873 case AC_PINCTL_VREF_100: item = 7; break;
2876 ucontrol->value.enumerated.item[0] = item;
2880 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2881 struct snd_ctl_elem_value *ucontrol)
2883 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2884 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2885 static unsigned int ctls[] = {
2886 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2887 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2888 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2889 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2890 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2891 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2893 unsigned int old_ctl, new_ctl;
2895 old_ctl = snd_hda_codec_read(codec, nid, 0,
2896 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2897 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2898 if (old_ctl != new_ctl) {
2900 snd_hda_codec_write_cache(codec, nid, 0,
2901 AC_VERB_SET_PIN_WIDGET_CONTROL,
2903 val = ucontrol->value.enumerated.item[0] >= 3 ?
2905 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2912 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2913 struct snd_ctl_elem_info *uinfo)
2915 static char *texts[] = {
2916 "Front", "Surround", "CLFE", "Side"
2918 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2920 uinfo->value.enumerated.items = 4;
2921 if (uinfo->value.enumerated.item >= 4)
2922 uinfo->value.enumerated.item = 3;
2923 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2927 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2928 struct snd_ctl_elem_value *ucontrol)
2930 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2931 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2934 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2935 ucontrol->value.enumerated.item[0] = sel & 3;
2939 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2940 struct snd_ctl_elem_value *ucontrol)
2942 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2943 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2946 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2947 if (ucontrol->value.enumerated.item[0] != sel) {
2948 sel = ucontrol->value.enumerated.item[0] & 3;
2949 snd_hda_codec_write_cache(codec, nid, 0,
2950 AC_VERB_SET_CONNECT_SEL, sel);
2956 #define PIN_CTL_TEST(xname,nid) { \
2957 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2959 .info = alc_test_pin_ctl_info, \
2960 .get = alc_test_pin_ctl_get, \
2961 .put = alc_test_pin_ctl_put, \
2962 .private_value = nid \
2965 #define PIN_SRC_TEST(xname,nid) { \
2966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2968 .info = alc_test_pin_src_info, \
2969 .get = alc_test_pin_src_get, \
2970 .put = alc_test_pin_src_put, \
2971 .private_value = nid \
2974 static struct snd_kcontrol_new alc880_test_mixer[] = {
2975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2976 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2977 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2978 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2980 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2981 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2983 PIN_CTL_TEST("Front Pin Mode", 0x14),
2984 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2985 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2986 PIN_CTL_TEST("Side Pin Mode", 0x17),
2987 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2988 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2989 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2990 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2991 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2992 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2993 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2994 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2995 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2996 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2997 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2998 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2999 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3000 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3001 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3002 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3007 .name = "Channel Mode",
3008 .info = alc_ch_mode_info,
3009 .get = alc_ch_mode_get,
3010 .put = alc_ch_mode_put,
3015 static struct hda_verb alc880_test_init_verbs[] = {
3016 /* Unmute inputs of 0x0c - 0x0f */
3017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3020 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3023 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3024 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3025 /* Vol output for 0x0c-0x0f */
3026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3029 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3030 /* Set output pins 0x14-0x17 */
3031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3033 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3034 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3035 /* Unmute output pins 0x14-0x17 */
3036 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3038 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3039 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3040 /* Set input pins 0x18-0x1c */
3041 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3042 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3043 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3044 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3045 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3046 /* Mute input pins 0x18-0x1b */
3047 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3048 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3050 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3053 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3054 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3055 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3056 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3058 /* Analog input/passthru */
3059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3071 static const char *alc880_models[ALC880_MODEL_LAST] = {
3072 [ALC880_3ST] = "3stack",
3073 [ALC880_TCL_S700] = "tcl",
3074 [ALC880_3ST_DIG] = "3stack-digout",
3075 [ALC880_CLEVO] = "clevo",
3076 [ALC880_5ST] = "5stack",
3077 [ALC880_5ST_DIG] = "5stack-digout",
3078 [ALC880_W810] = "w810",
3079 [ALC880_Z71V] = "z71v",
3080 [ALC880_6ST] = "6stack",
3081 [ALC880_6ST_DIG] = "6stack-digout",
3082 [ALC880_ASUS] = "asus",
3083 [ALC880_ASUS_W1V] = "asus-w1v",
3084 [ALC880_ASUS_DIG] = "asus-dig",
3085 [ALC880_ASUS_DIG2] = "asus-dig2",
3086 [ALC880_UNIWILL_DIG] = "uniwill",
3087 [ALC880_UNIWILL_P53] = "uniwill-p53",
3088 [ALC880_FUJITSU] = "fujitsu",
3089 [ALC880_F1734] = "F1734",
3091 [ALC880_LG_LW] = "lg-lw",
3092 [ALC880_MEDION_RIM] = "medion",
3093 #ifdef CONFIG_SND_DEBUG
3094 [ALC880_TEST] = "test",
3096 [ALC880_AUTO] = "auto",
3099 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3100 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3101 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3102 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3103 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3104 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3105 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3106 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3107 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3108 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3109 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3110 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3111 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3112 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3113 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3114 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3115 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3116 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3117 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3118 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3119 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3120 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3121 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3122 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3123 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3124 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3125 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3126 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3127 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3128 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3129 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3130 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3131 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3132 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3133 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3134 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3135 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3136 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3137 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3138 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3139 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3140 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3141 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3142 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3143 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3144 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3145 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3146 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3147 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3148 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3149 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3150 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3151 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3152 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3153 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3154 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3155 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3156 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3157 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3158 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3159 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3160 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3161 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3162 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3163 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3164 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3165 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3166 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3167 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3168 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3169 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3170 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3175 * ALC880 codec presets
3177 static struct alc_config_preset alc880_presets[] = {
3179 .mixers = { alc880_three_stack_mixer },
3180 .init_verbs = { alc880_volume_init_verbs,
3181 alc880_pin_3stack_init_verbs },
3182 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3183 .dac_nids = alc880_dac_nids,
3184 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3185 .channel_mode = alc880_threestack_modes,
3187 .input_mux = &alc880_capture_source,
3189 [ALC880_3ST_DIG] = {
3190 .mixers = { alc880_three_stack_mixer },
3191 .init_verbs = { alc880_volume_init_verbs,
3192 alc880_pin_3stack_init_verbs },
3193 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3194 .dac_nids = alc880_dac_nids,
3195 .dig_out_nid = ALC880_DIGOUT_NID,
3196 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3197 .channel_mode = alc880_threestack_modes,
3199 .input_mux = &alc880_capture_source,
3201 [ALC880_TCL_S700] = {
3202 .mixers = { alc880_tcl_s700_mixer },
3203 .init_verbs = { alc880_volume_init_verbs,
3204 alc880_pin_tcl_S700_init_verbs,
3205 alc880_gpio2_init_verbs },
3206 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3207 .dac_nids = alc880_dac_nids,
3209 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3210 .channel_mode = alc880_2_jack_modes,
3211 .input_mux = &alc880_capture_source,
3214 .mixers = { alc880_three_stack_mixer,
3215 alc880_five_stack_mixer},
3216 .init_verbs = { alc880_volume_init_verbs,
3217 alc880_pin_5stack_init_verbs },
3218 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3219 .dac_nids = alc880_dac_nids,
3220 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3221 .channel_mode = alc880_fivestack_modes,
3222 .input_mux = &alc880_capture_source,
3224 [ALC880_5ST_DIG] = {
3225 .mixers = { alc880_three_stack_mixer,
3226 alc880_five_stack_mixer },
3227 .init_verbs = { alc880_volume_init_verbs,
3228 alc880_pin_5stack_init_verbs },
3229 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3230 .dac_nids = alc880_dac_nids,
3231 .dig_out_nid = ALC880_DIGOUT_NID,
3232 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3233 .channel_mode = alc880_fivestack_modes,
3234 .input_mux = &alc880_capture_source,
3237 .mixers = { alc880_six_stack_mixer },
3238 .init_verbs = { alc880_volume_init_verbs,
3239 alc880_pin_6stack_init_verbs },
3240 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3241 .dac_nids = alc880_6st_dac_nids,
3242 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3243 .channel_mode = alc880_sixstack_modes,
3244 .input_mux = &alc880_6stack_capture_source,
3246 [ALC880_6ST_DIG] = {
3247 .mixers = { alc880_six_stack_mixer },
3248 .init_verbs = { alc880_volume_init_verbs,
3249 alc880_pin_6stack_init_verbs },
3250 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3251 .dac_nids = alc880_6st_dac_nids,
3252 .dig_out_nid = ALC880_DIGOUT_NID,
3253 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3254 .channel_mode = alc880_sixstack_modes,
3255 .input_mux = &alc880_6stack_capture_source,
3258 .mixers = { alc880_w810_base_mixer },
3259 .init_verbs = { alc880_volume_init_verbs,
3260 alc880_pin_w810_init_verbs,
3261 alc880_gpio2_init_verbs },
3262 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3263 .dac_nids = alc880_w810_dac_nids,
3264 .dig_out_nid = ALC880_DIGOUT_NID,
3265 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3266 .channel_mode = alc880_w810_modes,
3267 .input_mux = &alc880_capture_source,
3270 .mixers = { alc880_z71v_mixer },
3271 .init_verbs = { alc880_volume_init_verbs,
3272 alc880_pin_z71v_init_verbs },
3273 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3274 .dac_nids = alc880_z71v_dac_nids,
3275 .dig_out_nid = ALC880_DIGOUT_NID,
3277 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3278 .channel_mode = alc880_2_jack_modes,
3279 .input_mux = &alc880_capture_source,
3282 .mixers = { alc880_f1734_mixer },
3283 .init_verbs = { alc880_volume_init_verbs,
3284 alc880_pin_f1734_init_verbs },
3285 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3286 .dac_nids = alc880_f1734_dac_nids,
3288 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3289 .channel_mode = alc880_2_jack_modes,
3290 .input_mux = &alc880_f1734_capture_source,
3291 .unsol_event = alc880_uniwill_p53_unsol_event,
3292 .init_hook = alc880_uniwill_p53_hp_automute,
3295 .mixers = { alc880_asus_mixer },
3296 .init_verbs = { alc880_volume_init_verbs,
3297 alc880_pin_asus_init_verbs,
3298 alc880_gpio1_init_verbs },
3299 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3300 .dac_nids = alc880_asus_dac_nids,
3301 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3302 .channel_mode = alc880_asus_modes,
3304 .input_mux = &alc880_capture_source,
3306 [ALC880_ASUS_DIG] = {
3307 .mixers = { alc880_asus_mixer },
3308 .init_verbs = { alc880_volume_init_verbs,
3309 alc880_pin_asus_init_verbs,
3310 alc880_gpio1_init_verbs },
3311 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3312 .dac_nids = alc880_asus_dac_nids,
3313 .dig_out_nid = ALC880_DIGOUT_NID,
3314 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3315 .channel_mode = alc880_asus_modes,
3317 .input_mux = &alc880_capture_source,
3319 [ALC880_ASUS_DIG2] = {
3320 .mixers = { alc880_asus_mixer },
3321 .init_verbs = { alc880_volume_init_verbs,
3322 alc880_pin_asus_init_verbs,
3323 alc880_gpio2_init_verbs }, /* use GPIO2 */
3324 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3325 .dac_nids = alc880_asus_dac_nids,
3326 .dig_out_nid = ALC880_DIGOUT_NID,
3327 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3328 .channel_mode = alc880_asus_modes,
3330 .input_mux = &alc880_capture_source,
3332 [ALC880_ASUS_W1V] = {
3333 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3334 .init_verbs = { alc880_volume_init_verbs,
3335 alc880_pin_asus_init_verbs,
3336 alc880_gpio1_init_verbs },
3337 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3338 .dac_nids = alc880_asus_dac_nids,
3339 .dig_out_nid = ALC880_DIGOUT_NID,
3340 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3341 .channel_mode = alc880_asus_modes,
3343 .input_mux = &alc880_capture_source,
3345 [ALC880_UNIWILL_DIG] = {
3346 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3347 .init_verbs = { alc880_volume_init_verbs,
3348 alc880_pin_asus_init_verbs },
3349 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3350 .dac_nids = alc880_asus_dac_nids,
3351 .dig_out_nid = ALC880_DIGOUT_NID,
3352 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3353 .channel_mode = alc880_asus_modes,
3355 .input_mux = &alc880_capture_source,
3357 [ALC880_UNIWILL] = {
3358 .mixers = { alc880_uniwill_mixer },
3359 .init_verbs = { alc880_volume_init_verbs,
3360 alc880_uniwill_init_verbs },
3361 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3362 .dac_nids = alc880_asus_dac_nids,
3363 .dig_out_nid = ALC880_DIGOUT_NID,
3364 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3365 .channel_mode = alc880_threestack_modes,
3367 .input_mux = &alc880_capture_source,
3368 .unsol_event = alc880_uniwill_unsol_event,
3369 .init_hook = alc880_uniwill_automute,
3371 [ALC880_UNIWILL_P53] = {
3372 .mixers = { alc880_uniwill_p53_mixer },
3373 .init_verbs = { alc880_volume_init_verbs,
3374 alc880_uniwill_p53_init_verbs },
3375 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3376 .dac_nids = alc880_asus_dac_nids,
3377 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3378 .channel_mode = alc880_threestack_modes,
3379 .input_mux = &alc880_capture_source,
3380 .unsol_event = alc880_uniwill_p53_unsol_event,
3381 .init_hook = alc880_uniwill_p53_hp_automute,
3383 [ALC880_FUJITSU] = {
3384 .mixers = { alc880_fujitsu_mixer,
3385 alc880_pcbeep_mixer, },
3386 .init_verbs = { alc880_volume_init_verbs,
3387 alc880_uniwill_p53_init_verbs,
3388 alc880_beep_init_verbs },
3389 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3390 .dac_nids = alc880_dac_nids,
3391 .dig_out_nid = ALC880_DIGOUT_NID,
3392 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3393 .channel_mode = alc880_2_jack_modes,
3394 .input_mux = &alc880_capture_source,
3395 .unsol_event = alc880_uniwill_p53_unsol_event,
3396 .init_hook = alc880_uniwill_p53_hp_automute,
3399 .mixers = { alc880_three_stack_mixer },
3400 .init_verbs = { alc880_volume_init_verbs,
3401 alc880_pin_clevo_init_verbs },
3402 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3403 .dac_nids = alc880_dac_nids,
3405 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3406 .channel_mode = alc880_threestack_modes,
3408 .input_mux = &alc880_capture_source,
3411 .mixers = { alc880_lg_mixer },
3412 .init_verbs = { alc880_volume_init_verbs,
3413 alc880_lg_init_verbs },
3414 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3415 .dac_nids = alc880_lg_dac_nids,
3416 .dig_out_nid = ALC880_DIGOUT_NID,
3417 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3418 .channel_mode = alc880_lg_ch_modes,
3420 .input_mux = &alc880_lg_capture_source,
3421 .unsol_event = alc880_lg_unsol_event,
3422 .init_hook = alc880_lg_automute,
3423 #ifdef CONFIG_SND_HDA_POWER_SAVE
3424 .loopbacks = alc880_lg_loopbacks,
3428 .mixers = { alc880_lg_lw_mixer },
3429 .init_verbs = { alc880_volume_init_verbs,
3430 alc880_lg_lw_init_verbs },
3431 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3432 .dac_nids = alc880_dac_nids,
3433 .dig_out_nid = ALC880_DIGOUT_NID,
3434 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3435 .channel_mode = alc880_lg_lw_modes,
3436 .input_mux = &alc880_lg_lw_capture_source,
3437 .unsol_event = alc880_lg_lw_unsol_event,
3438 .init_hook = alc880_lg_lw_automute,
3440 [ALC880_MEDION_RIM] = {
3441 .mixers = { alc880_medion_rim_mixer },
3442 .init_verbs = { alc880_volume_init_verbs,
3443 alc880_medion_rim_init_verbs,
3444 alc_gpio2_init_verbs },
3445 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3446 .dac_nids = alc880_dac_nids,
3447 .dig_out_nid = ALC880_DIGOUT_NID,
3448 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3449 .channel_mode = alc880_2_jack_modes,
3450 .input_mux = &alc880_medion_rim_capture_source,
3451 .unsol_event = alc880_medion_rim_unsol_event,
3452 .init_hook = alc880_medion_rim_automute,
3454 #ifdef CONFIG_SND_DEBUG
3456 .mixers = { alc880_test_mixer },
3457 .init_verbs = { alc880_test_init_verbs },
3458 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3459 .dac_nids = alc880_test_dac_nids,
3460 .dig_out_nid = ALC880_DIGOUT_NID,
3461 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3462 .channel_mode = alc880_test_modes,
3463 .input_mux = &alc880_test_capture_source,
3469 * Automatic parse of I/O pins from the BIOS configuration
3474 ALC_CTL_WIDGET_MUTE,
3477 static struct snd_kcontrol_new alc880_control_templates[] = {
3478 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3479 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3480 HDA_BIND_MUTE(NULL, 0, 0, 0),
3483 /* add dynamic controls */
3484 static int add_control(struct alc_spec *spec, int type, const char *name,
3487 struct snd_kcontrol_new *knew;
3489 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3490 knew = snd_array_new(&spec->kctls);
3493 *knew = alc880_control_templates[type];
3494 knew->name = kstrdup(name, GFP_KERNEL);
3497 knew->private_value = val;
3501 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3502 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3503 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3504 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3505 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3506 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3507 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3508 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3509 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3510 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3511 #define ALC880_PIN_CD_NID 0x1c
3513 /* fill in the dac_nids table from the parsed pin configuration */
3514 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3515 const struct auto_pin_cfg *cfg)
3521 memset(assigned, 0, sizeof(assigned));
3522 spec->multiout.dac_nids = spec->private_dac_nids;
3524 /* check the pins hardwired to audio widget */
3525 for (i = 0; i < cfg->line_outs; i++) {
3526 nid = cfg->line_out_pins[i];
3527 if (alc880_is_fixed_pin(nid)) {
3528 int idx = alc880_fixed_pin_idx(nid);
3529 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3533 /* left pins can be connect to any audio widget */
3534 for (i = 0; i < cfg->line_outs; i++) {
3535 nid = cfg->line_out_pins[i];
3536 if (alc880_is_fixed_pin(nid))
3538 /* search for an empty channel */
3539 for (j = 0; j < cfg->line_outs; j++) {
3541 spec->multiout.dac_nids[i] =
3542 alc880_idx_to_dac(j);
3548 spec->multiout.num_dacs = cfg->line_outs;
3552 /* add playback controls from the parsed DAC table */
3553 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3554 const struct auto_pin_cfg *cfg)
3557 static const char *chname[4] = {
3558 "Front", "Surround", NULL /*CLFE*/, "Side"
3563 for (i = 0; i < cfg->line_outs; i++) {
3564 if (!spec->multiout.dac_nids[i])
3566 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3569 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3570 "Center Playback Volume",
3571 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3575 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3576 "LFE Playback Volume",
3577 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3581 err = add_control(spec, ALC_CTL_BIND_MUTE,
3582 "Center Playback Switch",
3583 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3587 err = add_control(spec, ALC_CTL_BIND_MUTE,
3588 "LFE Playback Switch",
3589 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3594 sprintf(name, "%s Playback Volume", chname[i]);
3595 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3596 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3600 sprintf(name, "%s Playback Switch", chname[i]);
3601 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3602 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3611 /* add playback controls for speaker and HP outputs */
3612 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3622 if (alc880_is_fixed_pin(pin)) {
3623 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3624 /* specify the DAC as the extra output */
3625 if (!spec->multiout.hp_nid)
3626 spec->multiout.hp_nid = nid;
3628 spec->multiout.extra_out_nid[0] = nid;
3629 /* control HP volume/switch on the output mixer amp */
3630 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3631 sprintf(name, "%s Playback Volume", pfx);
3632 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3633 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3636 sprintf(name, "%s Playback Switch", pfx);
3637 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3638 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3641 } else if (alc880_is_multi_pin(pin)) {
3642 /* set manual connection */
3643 /* we have only a switch on HP-out PIN */
3644 sprintf(name, "%s Playback Switch", pfx);
3645 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3646 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3653 /* create input playback/capture controls for the given pin */
3654 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3655 const char *ctlname,
3656 int idx, hda_nid_t mix_nid)
3661 sprintf(name, "%s Playback Volume", ctlname);
3662 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3663 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3666 sprintf(name, "%s Playback Switch", ctlname);
3667 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3668 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3674 /* create playback/capture controls for input pins */
3675 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3676 const struct auto_pin_cfg *cfg)
3678 struct hda_input_mux *imux = &spec->private_imux;
3681 for (i = 0; i < AUTO_PIN_LAST; i++) {
3682 if (alc880_is_input_pin(cfg->input_pins[i])) {
3683 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3684 err = new_analog_input(spec, cfg->input_pins[i],
3685 auto_pin_cfg_labels[i],
3689 imux->items[imux->num_items].label =
3690 auto_pin_cfg_labels[i];
3691 imux->items[imux->num_items].index =
3692 alc880_input_pin_idx(cfg->input_pins[i]);
3699 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3700 unsigned int pin_type)
3702 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3705 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3709 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3710 hda_nid_t nid, int pin_type,
3713 alc_set_pin_output(codec, nid, pin_type);
3714 /* need the manual connection? */
3715 if (alc880_is_multi_pin(nid)) {
3716 struct alc_spec *spec = codec->spec;
3717 int idx = alc880_multi_pin_idx(nid);
3718 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3719 AC_VERB_SET_CONNECT_SEL,
3720 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3724 static int get_pin_type(int line_out_type)
3726 if (line_out_type == AUTO_PIN_HP_OUT)
3732 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3734 struct alc_spec *spec = codec->spec;
3737 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3738 for (i = 0; i < spec->autocfg.line_outs; i++) {
3739 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3740 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3741 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3745 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3747 struct alc_spec *spec = codec->spec;
3750 pin = spec->autocfg.speaker_pins[0];
3751 if (pin) /* connect to front */
3752 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3753 pin = spec->autocfg.hp_pins[0];
3754 if (pin) /* connect to front */
3755 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3758 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3760 struct alc_spec *spec = codec->spec;
3763 for (i = 0; i < AUTO_PIN_LAST; i++) {
3764 hda_nid_t nid = spec->autocfg.input_pins[i];
3765 if (alc880_is_input_pin(nid)) {
3766 snd_hda_codec_write(codec, nid, 0,
3767 AC_VERB_SET_PIN_WIDGET_CONTROL,
3768 i <= AUTO_PIN_FRONT_MIC ?
3769 PIN_VREF80 : PIN_IN);
3770 if (nid != ALC880_PIN_CD_NID)
3771 snd_hda_codec_write(codec, nid, 0,
3772 AC_VERB_SET_AMP_GAIN_MUTE,
3778 /* parse the BIOS configuration and set up the alc_spec */
3779 /* return 1 if successful, 0 if the proper config is not found,
3780 * or a negative error code
3782 static int alc880_parse_auto_config(struct hda_codec *codec)
3784 struct alc_spec *spec = codec->spec;
3786 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3788 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3792 if (!spec->autocfg.line_outs)
3793 return 0; /* can't find valid BIOS pin config */
3795 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3798 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3801 err = alc880_auto_create_extra_out(spec,
3802 spec->autocfg.speaker_pins[0],
3806 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3810 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3814 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3816 if (spec->autocfg.dig_out_pin)
3817 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3818 if (spec->autocfg.dig_in_pin)
3819 spec->dig_in_nid = ALC880_DIGIN_NID;
3821 if (spec->kctls.list)
3822 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3824 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3826 spec->num_mux_defs = 1;
3827 spec->input_mux = &spec->private_imux;
3832 /* additional initialization for auto-configuration model */
3833 static void alc880_auto_init(struct hda_codec *codec)
3835 struct alc_spec *spec = codec->spec;
3836 alc880_auto_init_multi_out(codec);
3837 alc880_auto_init_extra_out(codec);
3838 alc880_auto_init_analog_input(codec);
3839 if (spec->unsol_event)
3840 alc_inithook(codec);
3844 * OK, here we have finally the patch for ALC880
3847 static int patch_alc880(struct hda_codec *codec)
3849 struct alc_spec *spec;
3853 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3859 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3862 if (board_config < 0) {
3863 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3864 "trying auto-probe from BIOS...\n");
3865 board_config = ALC880_AUTO;
3868 if (board_config == ALC880_AUTO) {
3869 /* automatic parse from the BIOS config */
3870 err = alc880_parse_auto_config(codec);
3876 "hda_codec: Cannot set up configuration "
3877 "from BIOS. Using 3-stack mode...\n");
3878 board_config = ALC880_3ST;
3882 if (board_config != ALC880_AUTO)
3883 setup_preset(spec, &alc880_presets[board_config]);
3885 spec->stream_name_analog = "ALC880 Analog";
3886 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3887 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3888 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3890 spec->stream_name_digital = "ALC880 Digital";
3891 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3892 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3894 if (!spec->adc_nids && spec->input_mux) {
3895 /* check whether NID 0x07 is valid */
3896 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3898 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3899 if (wcap != AC_WID_AUD_IN) {
3900 spec->adc_nids = alc880_adc_nids_alt;
3901 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3902 spec->mixers[spec->num_mixers] =
3903 alc880_capture_alt_mixer;
3906 spec->adc_nids = alc880_adc_nids;
3907 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3908 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3913 spec->vmaster_nid = 0x0c;
3915 codec->patch_ops = alc_patch_ops;
3916 if (board_config == ALC880_AUTO)
3917 spec->init_hook = alc880_auto_init;
3918 #ifdef CONFIG_SND_HDA_POWER_SAVE
3919 if (!spec->loopback.amplist)
3920 spec->loopback.amplist = alc880_loopbacks;
3931 static hda_nid_t alc260_dac_nids[1] = {
3936 static hda_nid_t alc260_adc_nids[1] = {
3941 static hda_nid_t alc260_adc_nids_alt[1] = {
3946 static hda_nid_t alc260_hp_adc_nids[2] = {
3951 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3952 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3954 static hda_nid_t alc260_dual_adc_nids[2] = {
3959 #define ALC260_DIGOUT_NID 0x03
3960 #define ALC260_DIGIN_NID 0x06
3962 static struct hda_input_mux alc260_capture_source = {
3966 { "Front Mic", 0x1 },
3972 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3973 * headphone jack and the internal CD lines since these are the only pins at
3974 * which audio can appear. For flexibility, also allow the option of
3975 * recording the mixer output on the second ADC (ADC0 doesn't have a
3976 * connection to the mixer output).
3978 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3982 { "Mic/Line", 0x0 },
3984 { "Headphone", 0x2 },
3990 { "Mic/Line", 0x0 },
3992 { "Headphone", 0x2 },
3999 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4000 * the Fujitsu S702x, but jacks are marked differently.
4002 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4009 { "Headphone", 0x5 },
4018 { "Headphone", 0x6 },
4024 * This is just place-holder, so there's something for alc_build_pcms to look
4025 * at when it calculates the maximum number of channels. ALC260 has no mixer
4026 * element which allows changing the channel mode, so the verb list is
4029 static struct hda_channel_mode alc260_modes[1] = {
4034 /* Mixer combinations
4036 * basic: base_output + input + pc_beep + capture
4037 * HP: base_output + input + capture_alt
4038 * HP_3013: hp_3013 + input + capture
4039 * fujitsu: fujitsu + capture
4040 * acer: acer + capture
4043 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4044 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4045 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4046 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4047 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4048 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4049 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4053 static struct snd_kcontrol_new alc260_input_mixer[] = {
4054 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4055 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4056 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4057 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4058 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4059 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4060 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4061 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4065 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4066 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4067 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4071 /* update HP, line and mono out pins according to the master switch */
4072 static void alc260_hp_master_update(struct hda_codec *codec,
4073 hda_nid_t hp, hda_nid_t line,
4076 struct alc_spec *spec = codec->spec;
4077 unsigned int val = spec->master_sw ? PIN_HP : 0;
4078 /* change HP and line-out pins */
4079 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4081 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4083 /* mono (speaker) depending on the HP jack sense */
4084 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4085 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4089 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4090 struct snd_ctl_elem_value *ucontrol)
4092 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4093 struct alc_spec *spec = codec->spec;
4094 *ucontrol->value.integer.value = spec->master_sw;
4098 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4099 struct snd_ctl_elem_value *ucontrol)
4101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4102 struct alc_spec *spec = codec->spec;
4103 int val = !!*ucontrol->value.integer.value;
4104 hda_nid_t hp, line, mono;
4106 if (val == spec->master_sw)
4108 spec->master_sw = val;
4109 hp = (kcontrol->private_value >> 16) & 0xff;
4110 line = (kcontrol->private_value >> 8) & 0xff;
4111 mono = kcontrol->private_value & 0xff;
4112 alc260_hp_master_update(codec, hp, line, mono);
4116 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4119 .name = "Master Playback Switch",
4120 .info = snd_ctl_boolean_mono_info,
4121 .get = alc260_hp_master_sw_get,
4122 .put = alc260_hp_master_sw_put,
4123 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4125 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4126 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4127 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4128 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4129 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4131 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4135 static struct hda_verb alc260_hp_unsol_verbs[] = {
4136 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4140 static void alc260_hp_automute(struct hda_codec *codec)
4142 struct alc_spec *spec = codec->spec;
4143 unsigned int present;
4145 present = snd_hda_codec_read(codec, 0x10, 0,
4146 AC_VERB_GET_PIN_SENSE, 0);
4147 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4148 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4151 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4153 if ((res >> 26) == ALC880_HP_EVENT)
4154 alc260_hp_automute(codec);
4157 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4160 .name = "Master Playback Switch",
4161 .info = snd_ctl_boolean_mono_info,
4162 .get = alc260_hp_master_sw_get,
4163 .put = alc260_hp_master_sw_put,
4164 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4166 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4167 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4168 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4169 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4170 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4172 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4173 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4177 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4178 .ops = &snd_hda_bind_vol,
4180 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4181 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4182 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4187 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4188 .ops = &snd_hda_bind_sw,
4190 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4191 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4196 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4197 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4198 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4199 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4200 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4204 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4205 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4209 static void alc260_hp_3013_automute(struct hda_codec *codec)
4211 struct alc_spec *spec = codec->spec;
4212 unsigned int present;
4214 present = snd_hda_codec_read(codec, 0x15, 0,
4215 AC_VERB_GET_PIN_SENSE, 0);
4216 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4217 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4220 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4223 if ((res >> 26) == ALC880_HP_EVENT)
4224 alc260_hp_3013_automute(codec);
4227 static void alc260_hp_3012_automute(struct hda_codec *codec)
4229 unsigned int present, bits;
4231 present = snd_hda_codec_read(codec, 0x10, 0,
4232 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4234 bits = present ? 0 : PIN_OUT;
4235 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4237 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4239 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4243 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4246 if ((res >> 26) == ALC880_HP_EVENT)
4247 alc260_hp_3012_automute(codec);
4250 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4251 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4253 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4254 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4255 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4256 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4257 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4258 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4259 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4260 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4261 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4262 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4263 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4264 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4265 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4269 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4270 * versions of the ALC260 don't act on requests to enable mic bias from NID
4271 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4272 * datasheet doesn't mention this restriction. At this stage it's not clear
4273 * whether this behaviour is intentional or is a hardware bug in chip
4274 * revisions available in early 2006. Therefore for now allow the
4275 * "Headphone Jack Mode" control to span all choices, but if it turns out
4276 * that the lack of mic bias for this NID is intentional we could change the
4277 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4279 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4280 * don't appear to make the mic bias available from the "line" jack, even
4281 * though the NID used for this jack (0x14) can supply it. The theory is
4282 * that perhaps Acer have included blocking capacitors between the ALC260
4283 * and the output jack. If this turns out to be the case for all such
4284 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4285 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4287 * The C20x Tablet series have a mono internal speaker which is controlled
4288 * via the chip's Mono sum widget and pin complex, so include the necessary
4289 * controls for such models. On models without a "mono speaker" the control
4290 * won't do anything.
4292 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4293 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4294 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4295 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4296 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4298 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4300 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4301 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4303 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4304 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4305 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4306 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4307 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4308 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4309 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4313 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4314 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4316 static struct snd_kcontrol_new alc260_will_mixer[] = {
4317 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4318 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4320 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4321 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4322 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4323 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4324 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4325 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4326 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4327 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4328 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4332 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4333 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4335 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4336 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4337 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4338 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4339 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4340 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4341 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4342 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4343 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4344 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4345 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4349 /* capture mixer elements */
4350 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4351 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4352 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4353 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4354 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4357 /* The multiple "Capture Source" controls confuse alsamixer
4358 * So call somewhat different..
4360 /* .name = "Capture Source", */
4361 .name = "Input Source",
4363 .info = alc_mux_enum_info,
4364 .get = alc_mux_enum_get,
4365 .put = alc_mux_enum_put,
4370 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4371 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4372 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4374 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4375 /* The multiple "Capture Source" controls confuse alsamixer
4376 * So call somewhat different..
4378 /* .name = "Capture Source", */
4379 .name = "Input Source",
4381 .info = alc_mux_enum_info,
4382 .get = alc_mux_enum_get,
4383 .put = alc_mux_enum_put,
4389 * initialization verbs
4391 static struct hda_verb alc260_init_verbs[] = {
4392 /* Line In pin widget for input */
4393 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4394 /* CD pin widget for input */
4395 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4396 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4397 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4398 /* Mic2 (front panel) pin widget for input and vref at 80% */
4399 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4400 /* LINE-2 is used for line-out in rear */
4401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4402 /* select line-out */
4403 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4405 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4409 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4410 /* mute capture amp left and right */
4411 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4412 /* set connection select to line in (default select for this ADC) */
4413 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4414 /* mute capture amp left and right */
4415 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4416 /* set connection select to line in (default select for this ADC) */
4417 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4418 /* set vol=0 Line-Out mixer amp left and right */
4419 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4420 /* unmute pin widget amp left and right (no gain on this amp) */
4421 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4422 /* set vol=0 HP mixer amp left and right */
4423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4424 /* unmute pin widget amp left and right (no gain on this amp) */
4425 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4426 /* set vol=0 Mono mixer amp left and right */
4427 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4428 /* unmute pin widget amp left and right (no gain on this amp) */
4429 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4430 /* unmute LINE-2 out pin */
4431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4432 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4435 /* mute analog inputs */
4436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4438 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4440 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4441 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4442 /* mute Front out path */
4443 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4444 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4445 /* mute Headphone out path */
4446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4448 /* mute Mono out path */
4449 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4450 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4454 #if 0 /* should be identical with alc260_init_verbs? */
4455 static struct hda_verb alc260_hp_init_verbs[] = {
4456 /* Headphone and output */
4457 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4459 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4460 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4461 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4462 /* Mic2 (front panel) pin widget for input and vref at 80% */
4463 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4464 /* Line In pin widget for input */
4465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4466 /* Line-2 pin widget for output */
4467 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4468 /* CD pin widget for input */
4469 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4470 /* unmute amp left and right */
4471 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4472 /* set connection select to line in (default select for this ADC) */
4473 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4474 /* unmute Line-Out mixer amp left and right (volume = 0) */
4475 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4476 /* mute pin widget amp left and right (no gain on this amp) */
4477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4478 /* unmute HP mixer amp left and right (volume = 0) */
4479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4480 /* mute pin widget amp left and right (no gain on this amp) */
4481 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4482 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4485 /* mute analog inputs */
4486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4491 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4492 /* Unmute Front out path */
4493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4495 /* Unmute Headphone out path */
4496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4498 /* Unmute Mono out path */
4499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4505 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4506 /* Line out and output */
4507 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4509 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4510 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4511 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4512 /* Mic2 (front panel) pin widget for input and vref at 80% */
4513 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4514 /* Line In pin widget for input */
4515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4516 /* Headphone pin widget for output */
4517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4518 /* CD pin widget for input */
4519 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4520 /* unmute amp left and right */
4521 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4522 /* set connection select to line in (default select for this ADC) */
4523 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4524 /* unmute Line-Out mixer amp left and right (volume = 0) */
4525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4526 /* mute pin widget amp left and right (no gain on this amp) */
4527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4528 /* unmute HP mixer amp left and right (volume = 0) */
4529 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4530 /* mute pin widget amp left and right (no gain on this amp) */
4531 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4532 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4535 /* mute analog inputs */
4536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4541 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4542 /* Unmute Front out path */
4543 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4544 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4545 /* Unmute Headphone out path */
4546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4547 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4548 /* Unmute Mono out path */
4549 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4550 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4554 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4555 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4556 * audio = 0x16, internal speaker = 0x10.
4558 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4559 /* Disable all GPIOs */
4560 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4561 /* Internal speaker is connected to headphone pin */
4562 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4563 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4565 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4566 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4567 /* Ensure all other unused pins are disabled and muted. */
4568 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4569 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4570 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4571 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4572 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4573 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4574 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4577 /* Disable digital (SPDIF) pins */
4578 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4579 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4581 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4582 * when acting as an output.
4584 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4586 /* Start with output sum widgets muted and their output gains at min */
4587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4588 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4589 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4590 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4593 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4594 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4595 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4597 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4598 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4599 /* Unmute Line1 pin widget output buffer since it starts as an output.
4600 * If the pin mode is changed by the user the pin mode control will
4601 * take care of enabling the pin's input/output buffers as needed.
4602 * Therefore there's no need to enable the input buffer at this
4605 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4606 /* Unmute input buffer of pin widget used for Line-in (no equiv
4609 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4611 /* Mute capture amp left and right */
4612 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4613 /* Set ADC connection select to match default mixer setting - line
4616 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4618 /* Do the same for the second ADC: mute capture input amp and
4619 * set ADC connection to line in (on mic1 pin)
4621 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4624 /* Mute all inputs to mixer widget (even unconnected ones) */
4625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4627 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4628 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4629 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4630 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4631 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4632 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4637 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4638 * similar laptops (adapted from Fujitsu init verbs).
4640 static struct hda_verb alc260_acer_init_verbs[] = {
4641 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4642 * the headphone jack. Turn this on and rely on the standard mute
4643 * methods whenever the user wants to turn these outputs off.
4645 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4646 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4647 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4648 /* Internal speaker/Headphone jack is connected to Line-out pin */
4649 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4650 /* Internal microphone/Mic jack is connected to Mic1 pin */
4651 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4652 /* Line In jack is connected to Line1 pin */
4653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4654 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4655 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4656 /* Ensure all other unused pins are disabled and muted. */
4657 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4658 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4659 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4660 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4661 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4663 /* Disable digital (SPDIF) pins */
4664 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4665 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4667 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4668 * bus when acting as outputs.
4670 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4671 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4673 /* Start with output sum widgets muted and their output gains at min */
4674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4676 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4679 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4680 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4681 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4682 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4684 /* Unmute Line-out pin widget amp left and right
4685 * (no equiv mixer ctrl)
4687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4688 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4689 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4690 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4691 * inputs. If the pin mode is changed by the user the pin mode control
4692 * will take care of enabling the pin's input/output buffers as needed.
4693 * Therefore there's no need to enable the input buffer at this
4696 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4699 /* Mute capture amp left and right */
4700 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4701 /* Set ADC connection select to match default mixer setting - mic
4704 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4706 /* Do similar with the second ADC: mute capture input amp and
4707 * set ADC connection to mic to match ALSA's default state.
4709 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4710 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4712 /* Mute all inputs to mixer widget (even unconnected ones) */
4713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4720 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4725 static struct hda_verb alc260_will_verbs[] = {
4726 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4727 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4728 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4729 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4730 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4731 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4735 static struct hda_verb alc260_replacer_672v_verbs[] = {
4736 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4737 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4738 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4740 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4741 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4742 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4744 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4748 /* toggle speaker-output according to the hp-jack state */
4749 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4751 unsigned int present;
4753 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4754 present = snd_hda_codec_read(codec, 0x0f, 0,
4755 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4757 snd_hda_codec_write_cache(codec, 0x01, 0,
4758 AC_VERB_SET_GPIO_DATA, 1);
4759 snd_hda_codec_write_cache(codec, 0x0f, 0,
4760 AC_VERB_SET_PIN_WIDGET_CONTROL,
4763 snd_hda_codec_write_cache(codec, 0x01, 0,
4764 AC_VERB_SET_GPIO_DATA, 0);
4765 snd_hda_codec_write_cache(codec, 0x0f, 0,
4766 AC_VERB_SET_PIN_WIDGET_CONTROL,
4771 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4774 if ((res >> 26) == ALC880_HP_EVENT)
4775 alc260_replacer_672v_automute(codec);
4778 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4779 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4781 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4782 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4783 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4784 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4785 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4786 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4787 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4788 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4792 /* Test configuration for debugging, modelled after the ALC880 test
4795 #ifdef CONFIG_SND_DEBUG
4796 static hda_nid_t alc260_test_dac_nids[1] = {
4799 static hda_nid_t alc260_test_adc_nids[2] = {
4802 /* For testing the ALC260, each input MUX needs its own definition since
4803 * the signal assignments are different. This assumes that the first ADC
4806 static struct hda_input_mux alc260_test_capture_sources[2] = {
4810 { "MIC1 pin", 0x0 },
4811 { "MIC2 pin", 0x1 },
4812 { "LINE1 pin", 0x2 },
4813 { "LINE2 pin", 0x3 },
4815 { "LINE-OUT pin", 0x5 },
4816 { "HP-OUT pin", 0x6 },
4822 { "MIC1 pin", 0x0 },
4823 { "MIC2 pin", 0x1 },
4824 { "LINE1 pin", 0x2 },
4825 { "LINE2 pin", 0x3 },
4828 { "LINE-OUT pin", 0x6 },
4829 { "HP-OUT pin", 0x7 },
4833 static struct snd_kcontrol_new alc260_test_mixer[] = {
4834 /* Output driver widgets */
4835 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4836 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4837 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4838 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4839 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4840 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4842 /* Modes for retasking pin widgets
4843 * Note: the ALC260 doesn't seem to act on requests to enable mic
4844 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4845 * mention this restriction. At this stage it's not clear whether
4846 * this behaviour is intentional or is a hardware bug in chip
4847 * revisions available at least up until early 2006. Therefore for
4848 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4849 * choices, but if it turns out that the lack of mic bias for these
4850 * NIDs is intentional we could change their modes from
4851 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4853 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4854 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4855 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4856 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4857 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4858 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4860 /* Loopback mixer controls */
4861 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4862 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4863 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4864 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4865 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4866 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4867 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4868 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4869 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4870 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4871 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4872 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4873 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4874 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4875 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4876 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4878 /* Controls for GPIO pins, assuming they are configured as outputs */
4879 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4880 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4881 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4882 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4884 /* Switches to allow the digital IO pins to be enabled. The datasheet
4885 * is ambigious as to which NID is which; testing on laptops which
4886 * make this output available should provide clarification.
4888 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4889 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4891 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4892 * this output to turn on an external amplifier.
4894 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4895 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4899 static struct hda_verb alc260_test_init_verbs[] = {
4900 /* Enable all GPIOs as outputs with an initial value of 0 */
4901 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4902 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4903 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4905 /* Enable retasking pins as output, initially without power amp */
4906 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4907 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4909 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4910 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4911 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4913 /* Disable digital (SPDIF) pins initially, but users can enable
4914 * them via a mixer switch. In the case of SPDIF-out, this initverb
4915 * payload also sets the generation to 0, output to be in "consumer"
4916 * PCM format, copyright asserted, no pre-emphasis and no validity
4919 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4920 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4922 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4923 * OUT1 sum bus when acting as an output.
4925 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4926 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4927 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4928 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4930 /* Start with output sum widgets muted and their output gains at min */
4931 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4932 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4934 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4935 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4936 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4937 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4938 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4939 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4941 /* Unmute retasking pin widget output buffers since the default
4942 * state appears to be output. As the pin mode is changed by the
4943 * user the pin mode control will take care of enabling the pin's
4944 * input/output buffers as needed.
4946 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4947 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4949 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4950 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4951 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4952 /* Also unmute the mono-out pin widget */
4953 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4955 /* Mute capture amp left and right */
4956 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4957 /* Set ADC connection select to match default mixer setting (mic1
4960 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4962 /* Do the same for the second ADC: mute capture input amp and
4963 * set ADC connection to mic1 pin
4965 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4966 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4968 /* Mute all inputs to mixer widget (even unconnected ones) */
4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4976 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4982 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4983 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4985 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4986 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4989 * for BIOS auto-configuration
4992 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4996 unsigned long vol_val, sw_val;
5000 if (nid >= 0x0f && nid < 0x11) {
5001 nid_vol = nid - 0x7;
5002 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5003 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5004 } else if (nid == 0x11) {
5005 nid_vol = nid - 0x7;
5006 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5007 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5008 } else if (nid >= 0x12 && nid <= 0x15) {
5010 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5011 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5015 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5016 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5019 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5020 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5026 /* add playback controls from the parsed DAC table */
5027 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5028 const struct auto_pin_cfg *cfg)
5033 spec->multiout.num_dacs = 1;
5034 spec->multiout.dac_nids = spec->private_dac_nids;
5035 spec->multiout.dac_nids[0] = 0x02;
5037 nid = cfg->line_out_pins[0];
5039 err = alc260_add_playback_controls(spec, nid, "Front");
5044 nid = cfg->speaker_pins[0];
5046 err = alc260_add_playback_controls(spec, nid, "Speaker");
5051 nid = cfg->hp_pins[0];
5053 err = alc260_add_playback_controls(spec, nid, "Headphone");
5060 /* create playback/capture controls for input pins */
5061 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5062 const struct auto_pin_cfg *cfg)
5064 struct hda_input_mux *imux = &spec->private_imux;
5067 for (i = 0; i < AUTO_PIN_LAST; i++) {
5068 if (cfg->input_pins[i] >= 0x12) {
5069 idx = cfg->input_pins[i] - 0x12;
5070 err = new_analog_input(spec, cfg->input_pins[i],
5071 auto_pin_cfg_labels[i], idx,
5075 imux->items[imux->num_items].label =
5076 auto_pin_cfg_labels[i];
5077 imux->items[imux->num_items].index = idx;
5080 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5081 idx = cfg->input_pins[i] - 0x09;
5082 err = new_analog_input(spec, cfg->input_pins[i],
5083 auto_pin_cfg_labels[i], idx,
5087 imux->items[imux->num_items].label =
5088 auto_pin_cfg_labels[i];
5089 imux->items[imux->num_items].index = idx;
5096 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5097 hda_nid_t nid, int pin_type,
5100 alc_set_pin_output(codec, nid, pin_type);
5101 /* need the manual connection? */
5103 int idx = nid - 0x12;
5104 snd_hda_codec_write(codec, idx + 0x0b, 0,
5105 AC_VERB_SET_CONNECT_SEL, sel_idx);
5109 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5111 struct alc_spec *spec = codec->spec;
5114 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5115 nid = spec->autocfg.line_out_pins[0];
5117 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5118 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5121 nid = spec->autocfg.speaker_pins[0];
5123 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5125 nid = spec->autocfg.hp_pins[0];
5127 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5130 #define ALC260_PIN_CD_NID 0x16
5131 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5133 struct alc_spec *spec = codec->spec;
5136 for (i = 0; i < AUTO_PIN_LAST; i++) {
5137 hda_nid_t nid = spec->autocfg.input_pins[i];
5139 snd_hda_codec_write(codec, nid, 0,
5140 AC_VERB_SET_PIN_WIDGET_CONTROL,
5141 i <= AUTO_PIN_FRONT_MIC ?
5142 PIN_VREF80 : PIN_IN);
5143 if (nid != ALC260_PIN_CD_NID)
5144 snd_hda_codec_write(codec, nid, 0,
5145 AC_VERB_SET_AMP_GAIN_MUTE,
5152 * generic initialization of ADC, input mixers and output mixers
5154 static struct hda_verb alc260_volume_init_verbs[] = {
5156 * Unmute ADC0-1 and set the default input to mic-in
5158 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5159 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5160 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5161 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5163 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5165 * Note: PASD motherboards uses the Line In 2 as the input for
5166 * front panel mic (mic 2)
5168 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5169 /* mute analog inputs */
5170 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5171 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5172 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5173 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5174 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5177 * Set up output mixers (0x08 - 0x0a)
5179 /* set vol=0 to output mixers */
5180 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5181 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5182 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5183 /* set up input amps for analog loopback */
5184 /* Amp Indices: DAC = 0, mixer = 1 */
5185 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5186 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5187 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5188 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5189 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5190 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5195 static int alc260_parse_auto_config(struct hda_codec *codec)
5197 struct alc_spec *spec = codec->spec;
5200 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5202 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5206 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5209 if (!spec->kctls.list)
5210 return 0; /* can't find valid BIOS pin config */
5211 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5215 spec->multiout.max_channels = 2;
5217 if (spec->autocfg.dig_out_pin)
5218 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5219 if (spec->kctls.list)
5220 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5222 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5224 spec->num_mux_defs = 1;
5225 spec->input_mux = &spec->private_imux;
5227 /* check whether NID 0x04 is valid */
5228 wcap = get_wcaps(codec, 0x04);
5229 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5230 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5231 spec->adc_nids = alc260_adc_nids_alt;
5232 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5233 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5235 spec->adc_nids = alc260_adc_nids;
5236 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5237 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5244 /* additional initialization for auto-configuration model */
5245 static void alc260_auto_init(struct hda_codec *codec)
5247 struct alc_spec *spec = codec->spec;
5248 alc260_auto_init_multi_out(codec);
5249 alc260_auto_init_analog_input(codec);
5250 if (spec->unsol_event)
5251 alc_inithook(codec);
5254 #ifdef CONFIG_SND_HDA_POWER_SAVE
5255 static struct hda_amp_list alc260_loopbacks[] = {
5256 { 0x07, HDA_INPUT, 0 },
5257 { 0x07, HDA_INPUT, 1 },
5258 { 0x07, HDA_INPUT, 2 },
5259 { 0x07, HDA_INPUT, 3 },
5260 { 0x07, HDA_INPUT, 4 },
5266 * ALC260 configurations
5268 static const char *alc260_models[ALC260_MODEL_LAST] = {
5269 [ALC260_BASIC] = "basic",
5271 [ALC260_HP_3013] = "hp-3013",
5272 [ALC260_HP_DC7600] = "hp-dc7600",
5273 [ALC260_FUJITSU_S702X] = "fujitsu",
5274 [ALC260_ACER] = "acer",
5275 [ALC260_WILL] = "will",
5276 [ALC260_REPLACER_672V] = "replacer",
5277 #ifdef CONFIG_SND_DEBUG
5278 [ALC260_TEST] = "test",
5280 [ALC260_AUTO] = "auto",
5283 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5284 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5285 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5286 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5287 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5288 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5289 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5290 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5291 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5292 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5293 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5294 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5295 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5296 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5297 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5298 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5299 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5300 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5301 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5305 static struct alc_config_preset alc260_presets[] = {
5307 .mixers = { alc260_base_output_mixer,
5309 alc260_pc_beep_mixer,
5310 alc260_capture_mixer },
5311 .init_verbs = { alc260_init_verbs },
5312 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5313 .dac_nids = alc260_dac_nids,
5314 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5315 .adc_nids = alc260_adc_nids,
5316 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5317 .channel_mode = alc260_modes,
5318 .input_mux = &alc260_capture_source,
5321 .mixers = { alc260_hp_output_mixer,
5323 alc260_capture_alt_mixer },
5324 .init_verbs = { alc260_init_verbs,
5325 alc260_hp_unsol_verbs },
5326 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5327 .dac_nids = alc260_dac_nids,
5328 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5329 .adc_nids = alc260_hp_adc_nids,
5330 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5331 .channel_mode = alc260_modes,
5332 .input_mux = &alc260_capture_source,
5333 .unsol_event = alc260_hp_unsol_event,
5334 .init_hook = alc260_hp_automute,
5336 [ALC260_HP_DC7600] = {
5337 .mixers = { alc260_hp_dc7600_mixer,
5339 alc260_capture_alt_mixer },
5340 .init_verbs = { alc260_init_verbs,
5341 alc260_hp_dc7600_verbs },
5342 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5343 .dac_nids = alc260_dac_nids,
5344 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5345 .adc_nids = alc260_hp_adc_nids,
5346 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5347 .channel_mode = alc260_modes,
5348 .input_mux = &alc260_capture_source,
5349 .unsol_event = alc260_hp_3012_unsol_event,
5350 .init_hook = alc260_hp_3012_automute,
5352 [ALC260_HP_3013] = {
5353 .mixers = { alc260_hp_3013_mixer,
5355 alc260_capture_alt_mixer },
5356 .init_verbs = { alc260_hp_3013_init_verbs,
5357 alc260_hp_3013_unsol_verbs },
5358 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5359 .dac_nids = alc260_dac_nids,
5360 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5361 .adc_nids = alc260_hp_adc_nids,
5362 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5363 .channel_mode = alc260_modes,
5364 .input_mux = &alc260_capture_source,
5365 .unsol_event = alc260_hp_3013_unsol_event,
5366 .init_hook = alc260_hp_3013_automute,
5368 [ALC260_FUJITSU_S702X] = {
5369 .mixers = { alc260_fujitsu_mixer,
5370 alc260_capture_mixer },
5371 .init_verbs = { alc260_fujitsu_init_verbs },
5372 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5373 .dac_nids = alc260_dac_nids,
5374 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5375 .adc_nids = alc260_dual_adc_nids,
5376 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5377 .channel_mode = alc260_modes,
5378 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5379 .input_mux = alc260_fujitsu_capture_sources,
5382 .mixers = { alc260_acer_mixer,
5383 alc260_capture_mixer },
5384 .init_verbs = { alc260_acer_init_verbs },
5385 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5386 .dac_nids = alc260_dac_nids,
5387 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5388 .adc_nids = alc260_dual_adc_nids,
5389 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5390 .channel_mode = alc260_modes,
5391 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5392 .input_mux = alc260_acer_capture_sources,
5395 .mixers = { alc260_will_mixer,
5396 alc260_capture_mixer },
5397 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5398 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5399 .dac_nids = alc260_dac_nids,
5400 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5401 .adc_nids = alc260_adc_nids,
5402 .dig_out_nid = ALC260_DIGOUT_NID,
5403 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5404 .channel_mode = alc260_modes,
5405 .input_mux = &alc260_capture_source,
5407 [ALC260_REPLACER_672V] = {
5408 .mixers = { alc260_replacer_672v_mixer,
5409 alc260_capture_mixer },
5410 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5411 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5412 .dac_nids = alc260_dac_nids,
5413 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5414 .adc_nids = alc260_adc_nids,
5415 .dig_out_nid = ALC260_DIGOUT_NID,
5416 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5417 .channel_mode = alc260_modes,
5418 .input_mux = &alc260_capture_source,
5419 .unsol_event = alc260_replacer_672v_unsol_event,
5420 .init_hook = alc260_replacer_672v_automute,
5422 #ifdef CONFIG_SND_DEBUG
5424 .mixers = { alc260_test_mixer,
5425 alc260_capture_mixer },
5426 .init_verbs = { alc260_test_init_verbs },
5427 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5428 .dac_nids = alc260_test_dac_nids,
5429 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5430 .adc_nids = alc260_test_adc_nids,
5431 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5432 .channel_mode = alc260_modes,
5433 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5434 .input_mux = alc260_test_capture_sources,
5439 static int patch_alc260(struct hda_codec *codec)
5441 struct alc_spec *spec;
5442 int err, board_config;
5444 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5450 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5453 if (board_config < 0) {
5454 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5455 "trying auto-probe from BIOS...\n");
5456 board_config = ALC260_AUTO;
5459 if (board_config == ALC260_AUTO) {
5460 /* automatic parse from the BIOS config */
5461 err = alc260_parse_auto_config(codec);
5467 "hda_codec: Cannot set up configuration "
5468 "from BIOS. Using base mode...\n");
5469 board_config = ALC260_BASIC;
5473 if (board_config != ALC260_AUTO)
5474 setup_preset(spec, &alc260_presets[board_config]);
5476 spec->stream_name_analog = "ALC260 Analog";
5477 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5478 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5480 spec->stream_name_digital = "ALC260 Digital";
5481 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5482 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5484 spec->vmaster_nid = 0x08;
5486 codec->patch_ops = alc_patch_ops;
5487 if (board_config == ALC260_AUTO)
5488 spec->init_hook = alc260_auto_init;
5489 #ifdef CONFIG_SND_HDA_POWER_SAVE
5490 if (!spec->loopback.amplist)
5491 spec->loopback.amplist = alc260_loopbacks;
5501 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5502 * configuration. Each pin widget can choose any input DACs and a mixer.
5503 * Each ADC is connected from a mixer of all inputs. This makes possible
5504 * 6-channel independent captures.
5506 * In addition, an independent DAC for the multi-playback (not used in this
5509 #define ALC882_DIGOUT_NID 0x06
5510 #define ALC882_DIGIN_NID 0x0a
5512 static struct hda_channel_mode alc882_ch_modes[1] = {
5516 static hda_nid_t alc882_dac_nids[4] = {
5517 /* front, rear, clfe, rear_surr */
5518 0x02, 0x03, 0x04, 0x05
5521 /* identical with ALC880 */
5522 #define alc882_adc_nids alc880_adc_nids
5523 #define alc882_adc_nids_alt alc880_adc_nids_alt
5525 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5526 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5529 /* FIXME: should be a matrix-type input source selection */
5531 static struct hda_input_mux alc882_capture_source = {
5535 { "Front Mic", 0x1 },
5540 #define alc882_mux_enum_info alc_mux_enum_info
5541 #define alc882_mux_enum_get alc_mux_enum_get
5543 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5544 struct snd_ctl_elem_value *ucontrol)
5546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5547 struct alc_spec *spec = codec->spec;
5548 const struct hda_input_mux *imux = spec->input_mux;
5549 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5550 hda_nid_t nid = spec->capsrc_nids ?
5551 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5552 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5553 unsigned int i, idx;
5555 idx = ucontrol->value.enumerated.item[0];
5556 if (idx >= imux->num_items)
5557 idx = imux->num_items - 1;
5558 if (*cur_val == idx)
5560 for (i = 0; i < imux->num_items; i++) {
5561 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5562 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5563 imux->items[i].index,
5573 static struct hda_verb alc882_3ST_ch2_init[] = {
5574 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5575 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5576 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5577 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5584 static struct hda_verb alc882_3ST_ch6_init[] = {
5585 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5586 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5587 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5588 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5589 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5590 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5594 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5595 { 2, alc882_3ST_ch2_init },
5596 { 6, alc882_3ST_ch6_init },
5602 static struct hda_verb alc882_sixstack_ch6_init[] = {
5603 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5604 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5605 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5606 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5613 static struct hda_verb alc882_sixstack_ch8_init[] = {
5614 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5615 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5616 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5617 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5621 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5622 { 6, alc882_sixstack_ch6_init },
5623 { 8, alc882_sixstack_ch8_init },
5627 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5633 static struct hda_verb alc885_mbp_ch2_init[] = {
5634 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5635 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5636 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5643 static struct hda_verb alc885_mbp_ch6_init[] = {
5644 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5645 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5646 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5647 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5648 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5652 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5653 { 2, alc885_mbp_ch2_init },
5654 { 6, alc885_mbp_ch6_init },
5658 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5659 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5661 static struct snd_kcontrol_new alc882_base_mixer[] = {
5662 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5663 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5664 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5665 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5666 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5667 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5668 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5669 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5670 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5671 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5680 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5681 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5682 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5683 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5684 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5688 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5690 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5691 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5692 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5693 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5694 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5696 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5697 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5698 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5701 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5704 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5705 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5706 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5707 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5709 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5711 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5712 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5716 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5719 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5720 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5721 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5722 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5723 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5724 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5725 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5726 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5727 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5728 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5729 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5733 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5734 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5736 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5737 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5738 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5740 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5741 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5742 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5743 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5744 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5745 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5746 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5747 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5748 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5749 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5753 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5755 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5756 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5757 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5758 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5759 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5760 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5762 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5764 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5765 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5769 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5772 .name = "Channel Mode",
5773 .info = alc_ch_mode_info,
5774 .get = alc_ch_mode_get,
5775 .put = alc_ch_mode_put,
5780 static struct hda_verb alc882_init_verbs[] = {
5781 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5787 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5792 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5795 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5798 /* Front Pin: output 0 (0x0c) */
5799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5800 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5801 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5802 /* Rear Pin: output 1 (0x0d) */
5803 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5805 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5806 /* CLFE Pin: output 2 (0x0e) */
5807 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5808 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5809 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5810 /* Side Pin: output 3 (0x0f) */
5811 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5812 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5813 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5814 /* Mic (rear) pin: input vref at 80% */
5815 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5817 /* Front Mic pin: input vref at 80% */
5818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5820 /* Line In pin: input */
5821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5823 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5826 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5827 /* CD pin widget for input */
5828 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5830 /* FIXME: use matrix-type input source selection */
5831 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5832 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5833 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5834 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5835 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5838 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5840 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5843 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5844 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5847 /* ADC1: mute amp left and right */
5848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5849 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5850 /* ADC2: mute amp left and right */
5851 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5852 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5853 /* ADC3: mute amp left and right */
5854 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5855 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5860 static struct hda_verb alc882_eapd_verbs[] = {
5861 /* change to EAPD mode */
5862 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5863 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5868 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5869 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5870 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5871 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5874 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5875 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5879 static struct hda_verb alc882_macpro_init_verbs[] = {
5880 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5881 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5883 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5884 /* Front Pin: output 0 (0x0c) */
5885 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5887 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5888 /* Front Mic pin: input vref at 80% */
5889 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5890 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5891 /* Speaker: output */
5892 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5894 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5895 /* Headphone output (output 0 - 0x0c) */
5896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5898 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5900 /* FIXME: use matrix-type input source selection */
5901 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5902 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5903 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5904 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5905 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5908 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5909 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5910 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5911 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5917 /* ADC1: mute amp left and right */
5918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5919 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5920 /* ADC2: mute amp left and right */
5921 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5922 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5923 /* ADC3: mute amp left and right */
5924 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5925 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5930 /* Macbook Pro rev3 */
5931 static struct hda_verb alc885_mbp3_init_verbs[] = {
5932 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5933 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5937 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5938 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5939 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5940 /* Front Pin: output 0 (0x0c) */
5941 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5942 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5943 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5944 /* HP Pin: output 0 (0x0d) */
5945 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5946 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5947 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5948 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5949 /* Mic (rear) pin: input vref at 80% */
5950 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5951 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5952 /* Front Mic pin: input vref at 80% */
5953 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5954 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5955 /* Line In pin: use output 1 when in LineOut mode */
5956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5957 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5958 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5960 /* FIXME: use matrix-type input source selection */
5961 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5962 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5963 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5964 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5965 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5966 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5968 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5969 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5971 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5973 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5974 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5975 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5976 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5977 /* ADC1: mute amp left and right */
5978 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5979 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5980 /* ADC2: mute amp left and right */
5981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5982 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5983 /* ADC3: mute amp left and right */
5984 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5985 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5990 /* iMac 24 mixer. */
5991 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5992 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5993 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5997 /* iMac 24 init verbs. */
5998 static struct hda_verb alc885_imac24_init_verbs[] = {
5999 /* Internal speakers: output 0 (0x0c) */
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, 0x00},
6003 /* Internal speakers: output 0 (0x0c) */
6004 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6005 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6006 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6007 /* Headphone: output 0 (0x0c) */
6008 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6010 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6011 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6012 /* Front Mic: input vref at 80% */
6013 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6014 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6018 /* Toggle speaker-output according to the hp-jack state */
6019 static void alc885_imac24_automute(struct hda_codec *codec)
6021 unsigned int present;
6023 present = snd_hda_codec_read(codec, 0x14, 0,
6024 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6025 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6026 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6027 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6028 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6031 /* Processes unsolicited events. */
6032 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6035 /* Headphone insertion or removal. */
6036 if ((res >> 26) == ALC880_HP_EVENT)
6037 alc885_imac24_automute(codec);
6040 static void alc885_mbp3_automute(struct hda_codec *codec)
6042 unsigned int present;
6044 present = snd_hda_codec_read(codec, 0x15, 0,
6045 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6046 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6047 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6048 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6049 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6052 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6055 /* Headphone insertion or removal. */
6056 if ((res >> 26) == ALC880_HP_EVENT)
6057 alc885_mbp3_automute(codec);
6061 static struct hda_verb alc882_targa_verbs[] = {
6062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6063 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6068 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6069 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6070 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6072 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6073 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6074 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6075 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6079 /* toggle speaker-output according to the hp-jack state */
6080 static void alc882_targa_automute(struct hda_codec *codec)
6082 unsigned int present;
6084 present = snd_hda_codec_read(codec, 0x14, 0,
6085 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6086 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6087 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6088 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6092 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6094 /* Looks like the unsol event is incompatible with the standard
6095 * definition. 4bit tag is placed at 26 bit!
6097 if (((res >> 26) == ALC880_HP_EVENT)) {
6098 alc882_targa_automute(codec);
6102 static struct hda_verb alc882_asus_a7j_verbs[] = {
6103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6107 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6110 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6111 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6112 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6114 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6115 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6116 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6120 static struct hda_verb alc882_asus_a7m_verbs[] = {
6121 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6122 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6124 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6125 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6128 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6129 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6130 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6132 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6133 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6134 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6138 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6140 unsigned int gpiostate, gpiomask, gpiodir;
6142 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6143 AC_VERB_GET_GPIO_DATA, 0);
6146 gpiostate |= (1 << pin);
6148 gpiostate &= ~(1 << pin);
6150 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6151 AC_VERB_GET_GPIO_MASK, 0);
6152 gpiomask |= (1 << pin);
6154 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6155 AC_VERB_GET_GPIO_DIRECTION, 0);
6156 gpiodir |= (1 << pin);
6159 snd_hda_codec_write(codec, codec->afg, 0,
6160 AC_VERB_SET_GPIO_MASK, gpiomask);
6161 snd_hda_codec_write(codec, codec->afg, 0,
6162 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6166 snd_hda_codec_write(codec, codec->afg, 0,
6167 AC_VERB_SET_GPIO_DATA, gpiostate);
6170 /* set up GPIO at initialization */
6171 static void alc885_macpro_init_hook(struct hda_codec *codec)
6173 alc882_gpio_mute(codec, 0, 0);
6174 alc882_gpio_mute(codec, 1, 0);
6177 /* set up GPIO and update auto-muting at initialization */
6178 static void alc885_imac24_init_hook(struct hda_codec *codec)
6180 alc885_macpro_init_hook(codec);
6181 alc885_imac24_automute(codec);
6185 * generic initialization of ADC, input mixers and output mixers
6187 static struct hda_verb alc882_auto_init_verbs[] = {
6189 * Unmute ADC0-2 and set the default input to mic-in
6191 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6193 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6194 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6195 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6196 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6198 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6200 * Note: PASD motherboards uses the Line In 2 as the input for
6201 * front panel mic (mic 2)
6203 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6204 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6205 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6206 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6207 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6211 * Set up output mixers (0x0c - 0x0f)
6213 /* set vol=0 to output mixers */
6214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6216 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6218 /* set up input amps for analog loopback */
6219 /* Amp Indices: DAC = 0, mixer = 1 */
6220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6228 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6229 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6231 /* FIXME: use matrix-type input source selection */
6232 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6233 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6234 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6235 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6236 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6237 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6239 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6244 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6245 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6252 /* capture mixer elements */
6253 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6254 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6255 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6256 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6257 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6260 /* The multiple "Capture Source" controls confuse alsamixer
6261 * So call somewhat different..
6263 /* .name = "Capture Source", */
6264 .name = "Input Source",
6266 .info = alc882_mux_enum_info,
6267 .get = alc882_mux_enum_get,
6268 .put = alc882_mux_enum_put,
6273 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6274 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6275 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6276 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6277 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6278 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6279 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6281 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6282 /* The multiple "Capture Source" controls confuse alsamixer
6283 * So call somewhat different..
6285 /* .name = "Capture Source", */
6286 .name = "Input Source",
6288 .info = alc882_mux_enum_info,
6289 .get = alc882_mux_enum_get,
6290 .put = alc882_mux_enum_put,
6295 #ifdef CONFIG_SND_HDA_POWER_SAVE
6296 #define alc882_loopbacks alc880_loopbacks
6299 /* pcm configuration: identiacal with ALC880 */
6300 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6301 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6302 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6303 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6306 * configuration and preset
6308 static const char *alc882_models[ALC882_MODEL_LAST] = {
6309 [ALC882_3ST_DIG] = "3stack-dig",
6310 [ALC882_6ST_DIG] = "6stack-dig",
6311 [ALC882_ARIMA] = "arima",
6312 [ALC882_W2JC] = "w2jc",
6313 [ALC882_TARGA] = "targa",
6314 [ALC882_ASUS_A7J] = "asus-a7j",
6315 [ALC882_ASUS_A7M] = "asus-a7m",
6316 [ALC885_MACPRO] = "macpro",
6317 [ALC885_MBP3] = "mbp3",
6318 [ALC885_IMAC24] = "imac24",
6319 [ALC882_AUTO] = "auto",
6322 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6323 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6324 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6325 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6326 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6327 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6328 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6329 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6330 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6331 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6332 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6333 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6334 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6338 static struct alc_config_preset alc882_presets[] = {
6339 [ALC882_3ST_DIG] = {
6340 .mixers = { alc882_base_mixer },
6341 .init_verbs = { alc882_init_verbs },
6342 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6343 .dac_nids = alc882_dac_nids,
6344 .dig_out_nid = ALC882_DIGOUT_NID,
6345 .dig_in_nid = ALC882_DIGIN_NID,
6346 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6347 .channel_mode = alc882_ch_modes,
6349 .input_mux = &alc882_capture_source,
6351 [ALC882_6ST_DIG] = {
6352 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6353 .init_verbs = { alc882_init_verbs },
6354 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6355 .dac_nids = alc882_dac_nids,
6356 .dig_out_nid = ALC882_DIGOUT_NID,
6357 .dig_in_nid = ALC882_DIGIN_NID,
6358 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6359 .channel_mode = alc882_sixstack_modes,
6360 .input_mux = &alc882_capture_source,
6363 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6364 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6365 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6366 .dac_nids = alc882_dac_nids,
6367 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6368 .channel_mode = alc882_sixstack_modes,
6369 .input_mux = &alc882_capture_source,
6372 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6373 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6374 alc880_gpio1_init_verbs },
6375 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6376 .dac_nids = alc882_dac_nids,
6377 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6378 .channel_mode = alc880_threestack_modes,
6380 .input_mux = &alc882_capture_source,
6381 .dig_out_nid = ALC882_DIGOUT_NID,
6384 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6385 .init_verbs = { alc885_mbp3_init_verbs,
6386 alc880_gpio1_init_verbs },
6387 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6388 .dac_nids = alc882_dac_nids,
6389 .channel_mode = alc885_mbp_6ch_modes,
6390 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6391 .input_mux = &alc882_capture_source,
6392 .dig_out_nid = ALC882_DIGOUT_NID,
6393 .dig_in_nid = ALC882_DIGIN_NID,
6394 .unsol_event = alc885_mbp3_unsol_event,
6395 .init_hook = alc885_mbp3_automute,
6398 .mixers = { alc882_macpro_mixer },
6399 .init_verbs = { alc882_macpro_init_verbs },
6400 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6401 .dac_nids = alc882_dac_nids,
6402 .dig_out_nid = ALC882_DIGOUT_NID,
6403 .dig_in_nid = ALC882_DIGIN_NID,
6404 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6405 .channel_mode = alc882_ch_modes,
6406 .input_mux = &alc882_capture_source,
6407 .init_hook = alc885_macpro_init_hook,
6410 .mixers = { alc885_imac24_mixer },
6411 .init_verbs = { alc885_imac24_init_verbs },
6412 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6413 .dac_nids = alc882_dac_nids,
6414 .dig_out_nid = ALC882_DIGOUT_NID,
6415 .dig_in_nid = ALC882_DIGIN_NID,
6416 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6417 .channel_mode = alc882_ch_modes,
6418 .input_mux = &alc882_capture_source,
6419 .unsol_event = alc885_imac24_unsol_event,
6420 .init_hook = alc885_imac24_init_hook,
6423 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6424 alc882_capture_mixer },
6425 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6426 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6427 .dac_nids = alc882_dac_nids,
6428 .dig_out_nid = ALC882_DIGOUT_NID,
6429 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6430 .adc_nids = alc882_adc_nids,
6431 .capsrc_nids = alc882_capsrc_nids,
6432 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6433 .channel_mode = alc882_3ST_6ch_modes,
6435 .input_mux = &alc882_capture_source,
6436 .unsol_event = alc882_targa_unsol_event,
6437 .init_hook = alc882_targa_automute,
6439 [ALC882_ASUS_A7J] = {
6440 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6441 alc882_capture_mixer },
6442 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6443 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6444 .dac_nids = alc882_dac_nids,
6445 .dig_out_nid = ALC882_DIGOUT_NID,
6446 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6447 .adc_nids = alc882_adc_nids,
6448 .capsrc_nids = alc882_capsrc_nids,
6449 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6450 .channel_mode = alc882_3ST_6ch_modes,
6452 .input_mux = &alc882_capture_source,
6454 [ALC882_ASUS_A7M] = {
6455 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6456 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6457 alc880_gpio1_init_verbs,
6458 alc882_asus_a7m_verbs },
6459 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6460 .dac_nids = alc882_dac_nids,
6461 .dig_out_nid = ALC882_DIGOUT_NID,
6462 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6463 .channel_mode = alc880_threestack_modes,
6465 .input_mux = &alc882_capture_source,
6474 PINFIX_ABIT_AW9D_MAX
6477 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6478 { 0x15, 0x01080104 }, /* side */
6479 { 0x16, 0x01011012 }, /* rear */
6480 { 0x17, 0x01016011 }, /* clfe */
6484 static const struct alc_pincfg *alc882_pin_fixes[] = {
6485 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6488 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6489 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6494 * BIOS auto configuration
6496 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6497 hda_nid_t nid, int pin_type,
6501 struct alc_spec *spec = codec->spec;
6504 alc_set_pin_output(codec, nid, pin_type);
6505 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6508 idx = spec->multiout.dac_nids[dac_idx] - 2;
6509 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6513 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6515 struct alc_spec *spec = codec->spec;
6518 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6519 for (i = 0; i <= HDA_SIDE; i++) {
6520 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6521 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6523 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6528 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6530 struct alc_spec *spec = codec->spec;
6533 pin = spec->autocfg.hp_pins[0];
6534 if (pin) /* connect to front */
6536 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6537 pin = spec->autocfg.speaker_pins[0];
6539 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6542 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6543 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6545 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6547 struct alc_spec *spec = codec->spec;
6550 for (i = 0; i < AUTO_PIN_LAST; i++) {
6551 hda_nid_t nid = spec->autocfg.input_pins[i];
6556 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6557 unsigned int pincap;
6558 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6559 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6563 snd_hda_codec_write(codec, nid, 0,
6564 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6565 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6566 snd_hda_codec_write(codec, nid, 0,
6567 AC_VERB_SET_AMP_GAIN_MUTE,
6572 static void alc882_auto_init_input_src(struct hda_codec *codec)
6574 struct alc_spec *spec = codec->spec;
6575 const struct hda_input_mux *imux = spec->input_mux;
6578 for (c = 0; c < spec->num_adc_nids; c++) {
6579 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6580 hda_nid_t nid = spec->capsrc_nids[c];
6581 int conns, mute, idx, item;
6583 conns = snd_hda_get_connections(codec, nid, conn_list,
6584 ARRAY_SIZE(conn_list));
6587 for (idx = 0; idx < conns; idx++) {
6588 /* if the current connection is the selected one,
6589 * unmute it as default - otherwise mute it
6591 mute = AMP_IN_MUTE(idx);
6592 for (item = 0; item < imux->num_items; item++) {
6593 if (imux->items[item].index == idx) {
6594 if (spec->cur_mux[c] == item)
6595 mute = AMP_IN_UNMUTE(idx);
6599 snd_hda_codec_write(codec, nid, 0,
6600 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6605 /* add mic boosts if needed */
6606 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6608 struct alc_spec *spec = codec->spec;
6612 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6613 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6614 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6616 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6620 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6621 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6622 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6624 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6631 /* almost identical with ALC880 parser... */
6632 static int alc882_parse_auto_config(struct hda_codec *codec)
6634 struct alc_spec *spec = codec->spec;
6635 int err = alc880_parse_auto_config(codec);
6640 return 0; /* no config found */
6642 err = alc_auto_add_mic_boost(codec);
6646 /* hack - override the init verbs */
6647 spec->init_verbs[0] = alc882_auto_init_verbs;
6649 return 1; /* config found */
6652 /* additional initialization for auto-configuration model */
6653 static void alc882_auto_init(struct hda_codec *codec)
6655 struct alc_spec *spec = codec->spec;
6656 alc882_auto_init_multi_out(codec);
6657 alc882_auto_init_hp_out(codec);
6658 alc882_auto_init_analog_input(codec);
6659 alc882_auto_init_input_src(codec);
6660 if (spec->unsol_event)
6661 alc_inithook(codec);
6664 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6666 static int patch_alc882(struct hda_codec *codec)
6668 struct alc_spec *spec;
6669 int err, board_config;
6671 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6677 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6681 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6682 /* Pick up systems that don't supply PCI SSID */
6683 switch (codec->subsystem_id) {
6684 case 0x106b0c00: /* Mac Pro */
6685 board_config = ALC885_MACPRO;
6687 case 0x106b1000: /* iMac 24 */
6688 case 0x106b2800: /* AppleTV */
6689 board_config = ALC885_IMAC24;
6691 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6692 case 0x106b00a4: /* MacbookPro4,1 */
6693 case 0x106b2c00: /* Macbook Pro rev3 */
6694 case 0x106b3600: /* Macbook 3.1 */
6695 board_config = ALC885_MBP3;
6698 /* ALC889A is handled better as ALC888-compatible */
6699 if (codec->revision_id == 0x100101 ||
6700 codec->revision_id == 0x100103) {
6702 return patch_alc883(codec);
6704 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6705 "trying auto-probe from BIOS...\n");
6706 board_config = ALC882_AUTO;
6710 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6712 if (board_config == ALC882_AUTO) {
6713 /* automatic parse from the BIOS config */
6714 err = alc882_parse_auto_config(codec);
6720 "hda_codec: Cannot set up configuration "
6721 "from BIOS. Using base mode...\n");
6722 board_config = ALC882_3ST_DIG;
6726 if (board_config != ALC882_AUTO)
6727 setup_preset(spec, &alc882_presets[board_config]);
6729 if (codec->vendor_id == 0x10ec0885) {
6730 spec->stream_name_analog = "ALC885 Analog";
6731 spec->stream_name_digital = "ALC885 Digital";
6733 spec->stream_name_analog = "ALC882 Analog";
6734 spec->stream_name_digital = "ALC882 Digital";
6737 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6738 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6739 /* FIXME: setup DAC5 */
6740 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6741 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6743 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6744 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6746 if (!spec->adc_nids && spec->input_mux) {
6747 /* check whether NID 0x07 is valid */
6748 unsigned int wcap = get_wcaps(codec, 0x07);
6750 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6751 if (wcap != AC_WID_AUD_IN) {
6752 spec->adc_nids = alc882_adc_nids_alt;
6753 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6754 spec->capsrc_nids = alc882_capsrc_nids_alt;
6755 spec->mixers[spec->num_mixers] =
6756 alc882_capture_alt_mixer;
6759 spec->adc_nids = alc882_adc_nids;
6760 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6761 spec->capsrc_nids = alc882_capsrc_nids;
6762 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6767 spec->vmaster_nid = 0x0c;
6769 codec->patch_ops = alc_patch_ops;
6770 if (board_config == ALC882_AUTO)
6771 spec->init_hook = alc882_auto_init;
6772 #ifdef CONFIG_SND_HDA_POWER_SAVE
6773 if (!spec->loopback.amplist)
6774 spec->loopback.amplist = alc882_loopbacks;
6783 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6784 * configuration. Each pin widget can choose any input DACs and a mixer.
6785 * Each ADC is connected from a mixer of all inputs. This makes possible
6786 * 6-channel independent captures.
6788 * In addition, an independent DAC for the multi-playback (not used in this
6791 #define ALC883_DIGOUT_NID 0x06
6792 #define ALC883_DIGIN_NID 0x0a
6794 static hda_nid_t alc883_dac_nids[4] = {
6795 /* front, rear, clfe, rear_surr */
6796 0x02, 0x03, 0x04, 0x05
6799 static hda_nid_t alc883_adc_nids[2] = {
6804 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6807 /* FIXME: should be a matrix-type input source selection */
6809 static struct hda_input_mux alc883_capture_source = {
6813 { "Front Mic", 0x1 },
6819 static struct hda_input_mux alc883_3stack_6ch_intel = {
6823 { "Front Mic", 0x0 },
6829 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6837 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6847 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6855 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6859 { "Front Mic", 0x1 },
6864 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6872 #define alc883_mux_enum_info alc_mux_enum_info
6873 #define alc883_mux_enum_get alc_mux_enum_get
6874 /* ALC883 has the ALC882-type input selection */
6875 #define alc883_mux_enum_put alc882_mux_enum_put
6880 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6887 static struct hda_verb alc883_3ST_ch2_init[] = {
6888 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6889 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6890 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6891 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6898 static struct hda_verb alc883_3ST_ch4_init[] = {
6899 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6900 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6901 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6902 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6903 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6910 static struct hda_verb alc883_3ST_ch6_init[] = {
6911 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6912 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6913 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6914 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6915 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6916 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6920 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6921 { 2, alc883_3ST_ch2_init },
6922 { 4, alc883_3ST_ch4_init },
6923 { 6, alc883_3ST_ch6_init },
6929 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6930 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6931 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6932 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6933 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6940 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6941 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6942 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6943 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6944 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6945 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6952 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6953 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6954 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6955 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6956 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6957 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6958 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6962 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6963 { 2, alc883_3ST_ch2_intel_init },
6964 { 4, alc883_3ST_ch4_intel_init },
6965 { 6, alc883_3ST_ch6_intel_init },
6971 static struct hda_verb alc883_sixstack_ch6_init[] = {
6972 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6973 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6974 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6975 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6982 static struct hda_verb alc883_sixstack_ch8_init[] = {
6983 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6984 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6985 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6986 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6990 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6991 { 6, alc883_sixstack_ch6_init },
6992 { 8, alc883_sixstack_ch8_init },
6995 static struct hda_verb alc883_medion_eapd_verbs[] = {
6996 /* eanable EAPD on medion laptop */
6997 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6998 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7002 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7003 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7006 static struct snd_kcontrol_new alc883_base_mixer[] = {
7007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7009 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7010 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7011 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7012 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7013 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7014 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7015 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7016 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7017 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7018 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7019 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7020 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7021 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7023 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7025 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7026 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7027 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7028 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7029 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7030 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7031 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7032 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7033 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7035 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7036 /* .name = "Capture Source", */
7037 .name = "Input Source",
7039 .info = alc883_mux_enum_info,
7040 .get = alc883_mux_enum_get,
7041 .put = alc883_mux_enum_put,
7046 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7047 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7048 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7049 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7050 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7051 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7052 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7053 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7054 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7055 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7057 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7058 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7059 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7060 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7061 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7062 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7063 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7065 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7066 /* .name = "Capture Source", */
7067 .name = "Input Source",
7069 .info = alc883_mux_enum_info,
7070 .get = alc883_mux_enum_get,
7071 .put = alc883_mux_enum_put,
7076 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7077 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7078 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7079 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7080 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7082 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7084 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7085 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7086 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7087 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7088 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7089 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7090 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7092 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7093 /* .name = "Capture Source", */
7094 .name = "Input Source",
7096 .info = alc883_mux_enum_info,
7097 .get = alc883_mux_enum_get,
7098 .put = alc883_mux_enum_put,
7103 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7104 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7105 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7106 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7107 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7109 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7111 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7112 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7113 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7114 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7115 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7116 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7117 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7120 /* .name = "Capture Source", */
7121 .name = "Input Source",
7123 .info = alc883_mux_enum_info,
7124 .get = alc883_mux_enum_get,
7125 .put = alc883_mux_enum_put,
7130 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7131 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7132 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7133 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7134 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7135 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7139 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7142 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7144 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7145 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7147 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7148 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7149 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7152 /* .name = "Capture Source", */
7153 .name = "Input Source",
7155 .info = alc883_mux_enum_info,
7156 .get = alc883_mux_enum_get,
7157 .put = alc883_mux_enum_put,
7162 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7163 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7164 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7165 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7166 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7167 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7168 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7169 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7170 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7172 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7173 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7175 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7177 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7179 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7180 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7181 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7182 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7183 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7184 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7185 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7188 /* .name = "Capture Source", */
7189 .name = "Input Source",
7191 .info = alc883_mux_enum_info,
7192 .get = alc883_mux_enum_get,
7193 .put = alc883_mux_enum_put,
7198 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7199 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7200 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7201 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7202 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7203 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7205 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7206 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7207 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7209 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7210 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7211 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7212 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7214 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7216 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7217 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7218 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7219 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7220 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7221 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7222 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7223 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7224 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7226 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7227 /* .name = "Capture Source", */
7228 .name = "Input Source",
7230 .info = alc883_mux_enum_info,
7231 .get = alc883_mux_enum_get,
7232 .put = alc883_mux_enum_put,
7237 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7238 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7239 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7240 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7241 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7242 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7243 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7244 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7245 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7246 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7247 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7248 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7249 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7250 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7252 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7255 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7256 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7257 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7258 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7259 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7260 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7264 /* .name = "Capture Source", */
7265 .name = "Input Source",
7267 .info = alc883_mux_enum_info,
7268 .get = alc883_mux_enum_get,
7269 .put = alc883_mux_enum_put,
7274 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7275 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7277 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7278 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7279 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7280 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7281 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7282 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7283 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7289 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7290 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7291 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7292 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7293 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7294 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7297 /* .name = "Capture Source", */
7298 .name = "Input Source",
7300 .info = alc883_mux_enum_info,
7301 .get = alc883_mux_enum_get,
7302 .put = alc883_mux_enum_put,
7307 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7310 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7311 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7312 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7314 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7316 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7317 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7318 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7319 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7320 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7321 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7322 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7324 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7325 /* .name = "Capture Source", */
7326 .name = "Input Source",
7328 .info = alc883_mux_enum_info,
7329 .get = alc883_mux_enum_get,
7330 .put = alc883_mux_enum_put,
7335 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7339 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7340 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7342 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7344 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7345 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7347 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7348 /* .name = "Capture Source", */
7349 .name = "Input Source",
7351 .info = alc883_mux_enum_info,
7352 .get = alc883_mux_enum_get,
7353 .put = alc883_mux_enum_put,
7358 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7359 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7360 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7362 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7363 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7366 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7367 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7368 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7369 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7370 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7371 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7374 /* .name = "Capture Source", */
7375 .name = "Input Source",
7377 .info = alc883_mux_enum_info,
7378 .get = alc883_mux_enum_get,
7379 .put = alc883_mux_enum_put,
7384 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7385 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7386 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7387 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7390 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7392 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7393 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7394 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7395 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7396 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7397 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7400 /* .name = "Capture Source", */
7401 .name = "Input Source",
7403 .info = alc883_mux_enum_info,
7404 .get = alc883_mux_enum_get,
7405 .put = alc883_mux_enum_put,
7410 static struct snd_kcontrol_new alc883_acer_aspire_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_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7417 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7419 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7420 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7421 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7422 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7425 /* .name = "Capture Source", */
7426 .name = "Input Source",
7428 .info = alc883_mux_enum_info,
7429 .get = alc883_mux_enum_get,
7430 .put = alc883_mux_enum_put,
7435 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7436 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7437 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7438 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7439 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7440 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7441 0x0d, 1, 0x0, HDA_OUTPUT),
7442 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7443 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7444 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7445 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7446 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7448 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7454 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7459 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7460 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7461 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7462 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7465 /* .name = "Capture Source", */
7466 .name = "Input Source",
7468 .info = alc883_mux_enum_info,
7469 .get = alc883_mux_enum_get,
7470 .put = alc883_mux_enum_put,
7475 static struct hda_bind_ctls alc883_bind_cap_vol = {
7476 .ops = &snd_hda_bind_vol,
7478 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7479 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7484 static struct hda_bind_ctls alc883_bind_cap_switch = {
7485 .ops = &snd_hda_bind_sw,
7487 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7488 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7493 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7494 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7495 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7496 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7500 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7501 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7502 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7503 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7505 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7506 /* .name = "Capture Source", */
7507 .name = "Input Source",
7509 .info = alc883_mux_enum_info,
7510 .get = alc883_mux_enum_get,
7511 .put = alc883_mux_enum_put,
7516 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7519 .name = "Channel Mode",
7520 .info = alc_ch_mode_info,
7521 .get = alc_ch_mode_get,
7522 .put = alc_ch_mode_put,
7527 static struct hda_verb alc883_init_verbs[] = {
7528 /* ADC1: mute amp left and right */
7529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7530 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7531 /* ADC2: mute amp left and right */
7532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7533 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7534 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7539 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7540 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7541 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7543 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7544 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7545 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7548 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7549 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7551 /* mute analog input loopbacks */
7552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7558 /* Front Pin: output 0 (0x0c) */
7559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7561 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7562 /* Rear Pin: output 1 (0x0d) */
7563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7565 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7566 /* CLFE Pin: output 2 (0x0e) */
7567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7569 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7570 /* Side Pin: output 3 (0x0f) */
7571 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7572 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7573 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7574 /* Mic (rear) pin: input vref at 80% */
7575 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7576 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7577 /* Front Mic pin: input vref at 80% */
7578 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7579 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7580 /* Line In pin: input */
7581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7583 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7587 /* CD pin widget for input */
7588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7590 /* FIXME: use matrix-type input source selection */
7591 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7605 /* toggle speaker-output according to the hp-jack state */
7606 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7608 unsigned int present;
7610 present = snd_hda_codec_read(codec, 0x15, 0,
7611 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7612 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7613 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7614 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7615 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7618 /* auto-toggle front mic */
7620 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7622 unsigned int present;
7625 present = snd_hda_codec_read(codec, 0x18, 0,
7626 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7627 bits = present ? HDA_AMP_MUTE : 0;
7628 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7632 static void alc883_mitac_automute(struct hda_codec *codec)
7634 alc883_mitac_hp_automute(codec);
7635 /* alc883_mitac_mic_automute(codec); */
7638 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7641 switch (res >> 26) {
7642 case ALC880_HP_EVENT:
7643 alc883_mitac_hp_automute(codec);
7645 case ALC880_MIC_EVENT:
7646 /* alc883_mitac_mic_automute(codec); */
7651 static struct hda_verb alc883_mitac_verbs[] = {
7653 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7656 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7657 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7659 /* enable unsolicited event */
7660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7661 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7666 static struct hda_verb alc883_clevo_m720_verbs[] = {
7668 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7669 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7671 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7672 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7674 /* enable unsolicited event */
7675 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7676 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7681 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7683 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7686 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7689 /* enable unsolicited event */
7690 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7695 static struct hda_verb alc883_tagra_verbs[] = {
7696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7699 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7700 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7702 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7703 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7704 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7706 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7707 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7708 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7709 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7714 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7715 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7716 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7717 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7721 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7724 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7729 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7732 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7733 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7734 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7738 static struct hda_verb alc883_haier_w66_verbs[] = {
7739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7744 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7745 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7746 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7747 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7751 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7757 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7758 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7759 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7763 static struct hda_verb alc888_3st_hp_verbs[] = {
7764 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7765 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7766 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7770 static struct hda_verb alc888_6st_dell_verbs[] = {
7771 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7775 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7776 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7777 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7778 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7779 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7783 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7784 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7785 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7786 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7787 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7791 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7792 { 2, alc888_3st_hp_2ch_init },
7793 { 6, alc888_3st_hp_6ch_init },
7796 /* toggle front-jack and RCA according to the hp-jack state */
7797 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7799 unsigned int present;
7801 present = snd_hda_codec_read(codec, 0x1b, 0,
7802 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7803 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7804 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7805 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7806 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7809 /* toggle RCA according to the front-jack state */
7810 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7812 unsigned int present;
7814 present = snd_hda_codec_read(codec, 0x14, 0,
7815 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7816 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7817 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7820 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7823 if ((res >> 26) == ALC880_HP_EVENT)
7824 alc888_lenovo_ms7195_front_automute(codec);
7825 if ((res >> 26) == ALC880_FRONT_EVENT)
7826 alc888_lenovo_ms7195_rca_automute(codec);
7829 static struct hda_verb alc883_medion_md2_verbs[] = {
7830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7833 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7835 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7839 /* toggle speaker-output according to the hp-jack state */
7840 static void alc883_medion_md2_automute(struct hda_codec *codec)
7842 unsigned int present;
7844 present = snd_hda_codec_read(codec, 0x14, 0,
7845 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7846 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7847 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7850 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7853 if ((res >> 26) == ALC880_HP_EVENT)
7854 alc883_medion_md2_automute(codec);
7857 /* toggle speaker-output according to the hp-jack state */
7858 static void alc883_tagra_automute(struct hda_codec *codec)
7860 unsigned int present;
7863 present = snd_hda_codec_read(codec, 0x14, 0,
7864 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7865 bits = present ? HDA_AMP_MUTE : 0;
7866 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7867 HDA_AMP_MUTE, bits);
7868 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7872 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7874 if ((res >> 26) == ALC880_HP_EVENT)
7875 alc883_tagra_automute(codec);
7878 /* toggle speaker-output according to the hp-jack state */
7879 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7881 unsigned int present;
7884 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7885 & AC_PINSENSE_PRESENCE;
7886 bits = present ? HDA_AMP_MUTE : 0;
7887 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7888 HDA_AMP_MUTE, bits);
7891 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7893 unsigned int present;
7895 present = snd_hda_codec_read(codec, 0x18, 0,
7896 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7897 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7898 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7901 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7903 alc883_clevo_m720_hp_automute(codec);
7904 alc883_clevo_m720_mic_automute(codec);
7907 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7910 switch (res >> 26) {
7911 case ALC880_HP_EVENT:
7912 alc883_clevo_m720_hp_automute(codec);
7914 case ALC880_MIC_EVENT:
7915 alc883_clevo_m720_mic_automute(codec);
7920 /* toggle speaker-output according to the hp-jack state */
7921 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7923 unsigned int present;
7926 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7927 & AC_PINSENSE_PRESENCE;
7928 bits = present ? HDA_AMP_MUTE : 0;
7929 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7930 HDA_AMP_MUTE, bits);
7933 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7936 if ((res >> 26) == ALC880_HP_EVENT)
7937 alc883_2ch_fujitsu_pi2515_automute(codec);
7940 static void alc883_haier_w66_automute(struct hda_codec *codec)
7942 unsigned int present;
7945 present = snd_hda_codec_read(codec, 0x1b, 0,
7946 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7947 bits = present ? 0x80 : 0;
7948 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7952 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7955 if ((res >> 26) == ALC880_HP_EVENT)
7956 alc883_haier_w66_automute(codec);
7959 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7961 unsigned int present;
7964 present = snd_hda_codec_read(codec, 0x14, 0,
7965 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7966 bits = present ? HDA_AMP_MUTE : 0;
7967 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7968 HDA_AMP_MUTE, bits);
7971 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7973 unsigned int present;
7976 present = snd_hda_codec_read(codec, 0x1b, 0,
7977 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7978 bits = present ? HDA_AMP_MUTE : 0;
7979 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7980 HDA_AMP_MUTE, bits);
7981 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7982 HDA_AMP_MUTE, bits);
7985 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7988 if ((res >> 26) == ALC880_HP_EVENT)
7989 alc883_lenovo_101e_all_automute(codec);
7990 if ((res >> 26) == ALC880_FRONT_EVENT)
7991 alc883_lenovo_101e_ispeaker_automute(codec);
7994 /* toggle speaker-output according to the hp-jack state */
7995 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7997 unsigned int present;
7999 present = snd_hda_codec_read(codec, 0x14, 0,
8000 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8001 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8002 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8003 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8004 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8007 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8010 if ((res >> 26) == ALC880_HP_EVENT)
8011 alc883_acer_aspire_automute(codec);
8014 static struct hda_verb alc883_acer_eapd_verbs[] = {
8015 /* HP Pin: output 0 (0x0c) */
8016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8018 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8019 /* Front Pin: output 0 (0x0c) */
8020 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8021 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8022 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8023 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8024 /* eanable EAPD on medion laptop */
8025 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8026 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8027 /* enable unsolicited event */
8028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8032 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8034 unsigned int present;
8036 present = snd_hda_codec_read(codec, 0x1b, 0,
8037 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8038 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8039 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8040 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8041 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8042 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8043 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8044 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8045 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8048 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8051 switch (res >> 26) {
8052 case ALC880_HP_EVENT:
8053 printk("hp_event\n");
8054 alc888_6st_dell_front_automute(codec);
8059 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8062 unsigned int present;
8064 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8065 present = snd_hda_codec_read(codec, 0x1b, 0,
8066 AC_VERB_GET_PIN_SENSE, 0);
8067 present = (present & 0x80000000) != 0;
8069 /* mute internal speaker */
8070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8071 HDA_AMP_MUTE, HDA_AMP_MUTE);
8072 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8073 HDA_AMP_MUTE, HDA_AMP_MUTE);
8074 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8075 HDA_AMP_MUTE, HDA_AMP_MUTE);
8076 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8077 HDA_AMP_MUTE, HDA_AMP_MUTE);
8078 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8079 HDA_AMP_MUTE, HDA_AMP_MUTE);
8081 /* unmute internal speaker if necessary */
8082 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8083 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8084 HDA_AMP_MUTE, mute);
8085 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8086 HDA_AMP_MUTE, mute);
8087 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8088 HDA_AMP_MUTE, mute);
8089 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8090 HDA_AMP_MUTE, mute);
8091 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8092 HDA_AMP_MUTE, mute);
8096 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8099 if ((res >> 26) == ALC880_HP_EVENT)
8100 alc888_lenovo_sky_front_automute(codec);
8104 * generic initialization of ADC, input mixers and output mixers
8106 static struct hda_verb alc883_auto_init_verbs[] = {
8108 * Unmute ADC0-2 and set the default input to mic-in
8110 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8111 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8112 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8115 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8117 * Note: PASD motherboards uses the Line In 2 as the input for
8118 * front panel mic (mic 2)
8120 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8124 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8125 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8128 * Set up output mixers (0x0c - 0x0f)
8130 /* set vol=0 to output mixers */
8131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8132 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8133 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8134 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8135 /* set up input amps for analog loopback */
8136 /* Amp Indices: DAC = 0, mixer = 1 */
8137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8139 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8140 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8142 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8143 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8144 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8145 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8146 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8148 /* FIXME: use matrix-type input source selection */
8149 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8154 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8160 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8161 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8166 /* capture mixer elements */
8167 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8168 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8169 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8170 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8171 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8174 /* The multiple "Capture Source" controls confuse alsamixer
8175 * So call somewhat different..
8177 /* .name = "Capture Source", */
8178 .name = "Input Source",
8180 .info = alc882_mux_enum_info,
8181 .get = alc882_mux_enum_get,
8182 .put = alc882_mux_enum_put,
8187 static struct hda_verb alc888_asus_m90v_verbs[] = {
8188 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8189 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8190 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8191 /* enable unsolicited event */
8192 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8193 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8197 static void alc883_nb_mic_automute(struct hda_codec *codec)
8199 unsigned int present;
8201 present = snd_hda_codec_read(codec, 0x18, 0,
8202 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8203 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8204 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8205 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8206 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8209 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8211 unsigned int present;
8214 present = snd_hda_codec_read(codec, 0x1b, 0,
8215 AC_VERB_GET_PIN_SENSE, 0)
8216 & AC_PINSENSE_PRESENCE;
8217 bits = present ? 0 : PIN_OUT;
8218 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8220 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8222 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8226 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8229 switch (res >> 26) {
8230 case ALC880_HP_EVENT:
8231 alc883_M90V_speaker_automute(codec);
8233 case ALC880_MIC_EVENT:
8234 alc883_nb_mic_automute(codec);
8239 static void alc883_mode2_inithook(struct hda_codec *codec)
8241 alc883_M90V_speaker_automute(codec);
8242 alc883_nb_mic_automute(codec);
8245 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8246 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8247 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8249 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8250 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8251 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8252 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8253 /* enable unsolicited event */
8254 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8258 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8260 unsigned int present;
8263 present = snd_hda_codec_read(codec, 0x14, 0,
8264 AC_VERB_GET_PIN_SENSE, 0)
8265 & AC_PINSENSE_PRESENCE;
8266 bits = present ? 0 : PIN_OUT;
8267 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8271 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8274 switch (res >> 26) {
8275 case ALC880_HP_EVENT:
8276 alc883_eee1601_speaker_automute(codec);
8281 static void alc883_eee1601_inithook(struct hda_codec *codec)
8283 alc883_eee1601_speaker_automute(codec);
8286 #ifdef CONFIG_SND_HDA_POWER_SAVE
8287 #define alc883_loopbacks alc880_loopbacks
8290 /* pcm configuration: identiacal with ALC880 */
8291 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8292 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8293 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8294 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8295 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8298 * configuration and preset
8300 static const char *alc883_models[ALC883_MODEL_LAST] = {
8301 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8302 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8303 [ALC883_3ST_6ch] = "3stack-6ch",
8304 [ALC883_6ST_DIG] = "6stack-dig",
8305 [ALC883_TARGA_DIG] = "targa-dig",
8306 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8307 [ALC883_ACER] = "acer",
8308 [ALC883_ACER_ASPIRE] = "acer-aspire",
8309 [ALC883_MEDION] = "medion",
8310 [ALC883_MEDION_MD2] = "medion-md2",
8311 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8312 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8313 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8314 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8315 [ALC888_LENOVO_SKY] = "lenovo-sky",
8316 [ALC883_HAIER_W66] = "haier-w66",
8317 [ALC888_3ST_HP] = "3stack-hp",
8318 [ALC888_6ST_DELL] = "6stack-dell",
8319 [ALC883_MITAC] = "mitac",
8320 [ALC883_CLEVO_M720] = "clevo-m720",
8321 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8322 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8323 [ALC883_AUTO] = "auto",
8326 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8327 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8328 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8329 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8330 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8331 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8332 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8333 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8334 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8335 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8336 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8337 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8338 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8339 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8340 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8341 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8342 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8343 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8344 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8345 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8346 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8347 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8348 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8349 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8350 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8351 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8352 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8353 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8354 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8355 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8356 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8357 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8358 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8359 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8360 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8361 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8362 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8363 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8364 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8365 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8366 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8367 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8368 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8369 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8370 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8371 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8372 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8373 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8374 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8375 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8376 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8377 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8378 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8379 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8380 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8381 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8382 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8383 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8384 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8385 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8386 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8387 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8391 static struct alc_config_preset alc883_presets[] = {
8392 [ALC883_3ST_2ch_DIG] = {
8393 .mixers = { alc883_3ST_2ch_mixer },
8394 .init_verbs = { alc883_init_verbs },
8395 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8396 .dac_nids = alc883_dac_nids,
8397 .dig_out_nid = ALC883_DIGOUT_NID,
8398 .dig_in_nid = ALC883_DIGIN_NID,
8399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8400 .channel_mode = alc883_3ST_2ch_modes,
8401 .input_mux = &alc883_capture_source,
8403 [ALC883_3ST_6ch_DIG] = {
8404 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8405 .init_verbs = { alc883_init_verbs },
8406 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8407 .dac_nids = alc883_dac_nids,
8408 .dig_out_nid = ALC883_DIGOUT_NID,
8409 .dig_in_nid = ALC883_DIGIN_NID,
8410 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8411 .channel_mode = alc883_3ST_6ch_modes,
8413 .input_mux = &alc883_capture_source,
8415 [ALC883_3ST_6ch] = {
8416 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8417 .init_verbs = { alc883_init_verbs },
8418 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8419 .dac_nids = alc883_dac_nids,
8420 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8421 .channel_mode = alc883_3ST_6ch_modes,
8423 .input_mux = &alc883_capture_source,
8425 [ALC883_3ST_6ch_INTEL] = {
8426 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8427 .init_verbs = { alc883_init_verbs },
8428 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8429 .dac_nids = alc883_dac_nids,
8430 .dig_out_nid = ALC883_DIGOUT_NID,
8431 .dig_in_nid = ALC883_DIGIN_NID,
8432 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8433 .channel_mode = alc883_3ST_6ch_intel_modes,
8435 .input_mux = &alc883_3stack_6ch_intel,
8437 [ALC883_6ST_DIG] = {
8438 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8439 .init_verbs = { alc883_init_verbs },
8440 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8441 .dac_nids = alc883_dac_nids,
8442 .dig_out_nid = ALC883_DIGOUT_NID,
8443 .dig_in_nid = ALC883_DIGIN_NID,
8444 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8445 .channel_mode = alc883_sixstack_modes,
8446 .input_mux = &alc883_capture_source,
8448 [ALC883_TARGA_DIG] = {
8449 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8450 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8451 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8452 .dac_nids = alc883_dac_nids,
8453 .dig_out_nid = ALC883_DIGOUT_NID,
8454 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8455 .channel_mode = alc883_3ST_6ch_modes,
8457 .input_mux = &alc883_capture_source,
8458 .unsol_event = alc883_tagra_unsol_event,
8459 .init_hook = alc883_tagra_automute,
8461 [ALC883_TARGA_2ch_DIG] = {
8462 .mixers = { alc883_tagra_2ch_mixer},
8463 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8464 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8465 .dac_nids = alc883_dac_nids,
8466 .dig_out_nid = ALC883_DIGOUT_NID,
8467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8468 .channel_mode = alc883_3ST_2ch_modes,
8469 .input_mux = &alc883_capture_source,
8470 .unsol_event = alc883_tagra_unsol_event,
8471 .init_hook = alc883_tagra_automute,
8474 .mixers = { alc883_base_mixer },
8475 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8476 * and the headphone jack. Turn this on and rely on the
8477 * standard mute methods whenever the user wants to turn
8478 * these outputs off.
8480 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8482 .dac_nids = alc883_dac_nids,
8483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8484 .channel_mode = alc883_3ST_2ch_modes,
8485 .input_mux = &alc883_capture_source,
8487 [ALC883_ACER_ASPIRE] = {
8488 .mixers = { alc883_acer_aspire_mixer },
8489 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8491 .dac_nids = alc883_dac_nids,
8492 .dig_out_nid = ALC883_DIGOUT_NID,
8493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8494 .channel_mode = alc883_3ST_2ch_modes,
8495 .input_mux = &alc883_capture_source,
8496 .unsol_event = alc883_acer_aspire_unsol_event,
8497 .init_hook = alc883_acer_aspire_automute,
8500 .mixers = { alc883_fivestack_mixer,
8501 alc883_chmode_mixer },
8502 .init_verbs = { alc883_init_verbs,
8503 alc883_medion_eapd_verbs },
8504 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8505 .dac_nids = alc883_dac_nids,
8506 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8507 .channel_mode = alc883_sixstack_modes,
8508 .input_mux = &alc883_capture_source,
8510 [ALC883_MEDION_MD2] = {
8511 .mixers = { alc883_medion_md2_mixer},
8512 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8513 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8514 .dac_nids = alc883_dac_nids,
8515 .dig_out_nid = ALC883_DIGOUT_NID,
8516 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8517 .channel_mode = alc883_3ST_2ch_modes,
8518 .input_mux = &alc883_capture_source,
8519 .unsol_event = alc883_medion_md2_unsol_event,
8520 .init_hook = alc883_medion_md2_automute,
8522 [ALC883_LAPTOP_EAPD] = {
8523 .mixers = { alc883_base_mixer },
8524 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8525 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8526 .dac_nids = alc883_dac_nids,
8527 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8528 .channel_mode = alc883_3ST_2ch_modes,
8529 .input_mux = &alc883_capture_source,
8531 [ALC883_CLEVO_M720] = {
8532 .mixers = { alc883_clevo_m720_mixer },
8533 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8534 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8535 .dac_nids = alc883_dac_nids,
8536 .dig_out_nid = ALC883_DIGOUT_NID,
8537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8538 .channel_mode = alc883_3ST_2ch_modes,
8539 .input_mux = &alc883_capture_source,
8540 .unsol_event = alc883_clevo_m720_unsol_event,
8541 .init_hook = alc883_clevo_m720_automute,
8543 [ALC883_LENOVO_101E_2ch] = {
8544 .mixers = { alc883_lenovo_101e_2ch_mixer},
8545 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8547 .dac_nids = alc883_dac_nids,
8548 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8549 .channel_mode = alc883_3ST_2ch_modes,
8550 .input_mux = &alc883_lenovo_101e_capture_source,
8551 .unsol_event = alc883_lenovo_101e_unsol_event,
8552 .init_hook = alc883_lenovo_101e_all_automute,
8554 [ALC883_LENOVO_NB0763] = {
8555 .mixers = { alc883_lenovo_nb0763_mixer },
8556 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8557 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8558 .dac_nids = alc883_dac_nids,
8559 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8560 .channel_mode = alc883_3ST_2ch_modes,
8562 .input_mux = &alc883_lenovo_nb0763_capture_source,
8563 .unsol_event = alc883_medion_md2_unsol_event,
8564 .init_hook = alc883_medion_md2_automute,
8566 [ALC888_LENOVO_MS7195_DIG] = {
8567 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8568 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8569 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8570 .dac_nids = alc883_dac_nids,
8571 .dig_out_nid = ALC883_DIGOUT_NID,
8572 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8573 .channel_mode = alc883_3ST_6ch_modes,
8575 .input_mux = &alc883_capture_source,
8576 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8577 .init_hook = alc888_lenovo_ms7195_front_automute,
8579 [ALC883_HAIER_W66] = {
8580 .mixers = { alc883_tagra_2ch_mixer},
8581 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8583 .dac_nids = alc883_dac_nids,
8584 .dig_out_nid = ALC883_DIGOUT_NID,
8585 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8586 .channel_mode = alc883_3ST_2ch_modes,
8587 .input_mux = &alc883_capture_source,
8588 .unsol_event = alc883_haier_w66_unsol_event,
8589 .init_hook = alc883_haier_w66_automute,
8592 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8593 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8594 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8595 .dac_nids = alc883_dac_nids,
8596 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8597 .channel_mode = alc888_3st_hp_modes,
8599 .input_mux = &alc883_capture_source,
8601 [ALC888_6ST_DELL] = {
8602 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8603 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8604 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8605 .dac_nids = alc883_dac_nids,
8606 .dig_out_nid = ALC883_DIGOUT_NID,
8607 .dig_in_nid = ALC883_DIGIN_NID,
8608 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8609 .channel_mode = alc883_sixstack_modes,
8610 .input_mux = &alc883_capture_source,
8611 .unsol_event = alc888_6st_dell_unsol_event,
8612 .init_hook = alc888_6st_dell_front_automute,
8615 .mixers = { alc883_mitac_mixer },
8616 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8617 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8618 .dac_nids = alc883_dac_nids,
8619 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8620 .channel_mode = alc883_3ST_2ch_modes,
8621 .input_mux = &alc883_capture_source,
8622 .unsol_event = alc883_mitac_unsol_event,
8623 .init_hook = alc883_mitac_automute,
8625 [ALC883_FUJITSU_PI2515] = {
8626 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8627 .init_verbs = { alc883_init_verbs,
8628 alc883_2ch_fujitsu_pi2515_verbs},
8629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8630 .dac_nids = alc883_dac_nids,
8631 .dig_out_nid = ALC883_DIGOUT_NID,
8632 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8633 .channel_mode = alc883_3ST_2ch_modes,
8634 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8635 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8636 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8638 [ALC888_LENOVO_SKY] = {
8639 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8640 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8641 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8642 .dac_nids = alc883_dac_nids,
8643 .dig_out_nid = ALC883_DIGOUT_NID,
8644 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8645 .adc_nids = alc883_adc_nids,
8646 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8647 .channel_mode = alc883_sixstack_modes,
8649 .input_mux = &alc883_lenovo_sky_capture_source,
8650 .unsol_event = alc883_lenovo_sky_unsol_event,
8651 .init_hook = alc888_lenovo_sky_front_automute,
8653 [ALC888_ASUS_M90V] = {
8654 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8655 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8656 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8657 .dac_nids = alc883_dac_nids,
8658 .dig_out_nid = ALC883_DIGOUT_NID,
8659 .dig_in_nid = ALC883_DIGIN_NID,
8660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8661 .channel_mode = alc883_3ST_6ch_modes,
8663 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8664 .unsol_event = alc883_mode2_unsol_event,
8665 .init_hook = alc883_mode2_inithook,
8667 [ALC888_ASUS_EEE1601] = {
8668 .mixers = { alc883_asus_eee1601_mixer },
8669 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8670 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8671 .dac_nids = alc883_dac_nids,
8672 .dig_out_nid = ALC883_DIGOUT_NID,
8673 .dig_in_nid = ALC883_DIGIN_NID,
8674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8675 .channel_mode = alc883_3ST_2ch_modes,
8677 .input_mux = &alc883_asus_eee1601_capture_source,
8678 .unsol_event = alc883_eee1601_unsol_event,
8679 .init_hook = alc883_eee1601_inithook,
8685 * BIOS auto configuration
8687 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8688 hda_nid_t nid, int pin_type,
8692 struct alc_spec *spec = codec->spec;
8695 alc_set_pin_output(codec, nid, pin_type);
8696 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8699 idx = spec->multiout.dac_nids[dac_idx] - 2;
8700 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8704 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8706 struct alc_spec *spec = codec->spec;
8709 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8710 for (i = 0; i <= HDA_SIDE; i++) {
8711 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8712 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8714 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8719 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8721 struct alc_spec *spec = codec->spec;
8724 pin = spec->autocfg.hp_pins[0];
8725 if (pin) /* connect to front */
8727 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8728 pin = spec->autocfg.speaker_pins[0];
8730 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8733 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8734 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8736 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8738 struct alc_spec *spec = codec->spec;
8741 for (i = 0; i < AUTO_PIN_LAST; i++) {
8742 hda_nid_t nid = spec->autocfg.input_pins[i];
8743 if (alc883_is_input_pin(nid)) {
8744 snd_hda_codec_write(codec, nid, 0,
8745 AC_VERB_SET_PIN_WIDGET_CONTROL,
8746 (i <= AUTO_PIN_FRONT_MIC ?
8747 PIN_VREF80 : PIN_IN));
8748 if (nid != ALC883_PIN_CD_NID)
8749 snd_hda_codec_write(codec, nid, 0,
8750 AC_VERB_SET_AMP_GAIN_MUTE,
8756 #define alc883_auto_init_input_src alc882_auto_init_input_src
8758 /* almost identical with ALC880 parser... */
8759 static int alc883_parse_auto_config(struct hda_codec *codec)
8761 struct alc_spec *spec = codec->spec;
8762 int err = alc880_parse_auto_config(codec);
8767 return 0; /* no config found */
8769 err = alc_auto_add_mic_boost(codec);
8773 /* hack - override the init verbs */
8774 spec->init_verbs[0] = alc883_auto_init_verbs;
8775 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8778 return 1; /* config found */
8781 /* additional initialization for auto-configuration model */
8782 static void alc883_auto_init(struct hda_codec *codec)
8784 struct alc_spec *spec = codec->spec;
8785 alc883_auto_init_multi_out(codec);
8786 alc883_auto_init_hp_out(codec);
8787 alc883_auto_init_analog_input(codec);
8788 alc883_auto_init_input_src(codec);
8789 if (spec->unsol_event)
8790 alc_inithook(codec);
8793 static int patch_alc883(struct hda_codec *codec)
8795 struct alc_spec *spec;
8796 int err, board_config;
8798 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8804 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8806 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8809 if (board_config < 0) {
8810 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8811 "trying auto-probe from BIOS...\n");
8812 board_config = ALC883_AUTO;
8815 if (board_config == ALC883_AUTO) {
8816 /* automatic parse from the BIOS config */
8817 err = alc883_parse_auto_config(codec);
8823 "hda_codec: Cannot set up configuration "
8824 "from BIOS. Using base mode...\n");
8825 board_config = ALC883_3ST_2ch_DIG;
8829 if (board_config != ALC883_AUTO)
8830 setup_preset(spec, &alc883_presets[board_config]);
8832 switch (codec->vendor_id) {
8834 if (codec->revision_id == 0x100101) {
8835 spec->stream_name_analog = "ALC1200 Analog";
8836 spec->stream_name_digital = "ALC1200 Digital";
8838 spec->stream_name_analog = "ALC888 Analog";
8839 spec->stream_name_digital = "ALC888 Digital";
8843 spec->stream_name_analog = "ALC889 Analog";
8844 spec->stream_name_digital = "ALC889 Digital";
8847 spec->stream_name_analog = "ALC883 Analog";
8848 spec->stream_name_digital = "ALC883 Digital";
8852 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8853 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8854 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8856 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8857 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8859 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8860 spec->adc_nids = alc883_adc_nids;
8861 spec->capsrc_nids = alc883_capsrc_nids;
8863 spec->vmaster_nid = 0x0c;
8865 codec->patch_ops = alc_patch_ops;
8866 if (board_config == ALC883_AUTO)
8867 spec->init_hook = alc883_auto_init;
8869 #ifdef CONFIG_SND_HDA_POWER_SAVE
8870 if (!spec->loopback.amplist)
8871 spec->loopback.amplist = alc883_loopbacks;
8881 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8882 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8884 #define alc262_dac_nids alc260_dac_nids
8885 #define alc262_adc_nids alc882_adc_nids
8886 #define alc262_adc_nids_alt alc882_adc_nids_alt
8887 #define alc262_capsrc_nids alc882_capsrc_nids
8888 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8890 #define alc262_modes alc260_modes
8891 #define alc262_capture_source alc882_capture_source
8893 static hda_nid_t alc262_dmic_adc_nids[1] = {
8898 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8900 static struct snd_kcontrol_new alc262_base_mixer[] = {
8901 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8902 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8903 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8904 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8906 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8908 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8909 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8910 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8911 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8912 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8913 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8914 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8915 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8916 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8917 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8918 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8922 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8923 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8924 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8925 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8926 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8927 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8928 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8933 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8935 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8936 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8937 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8942 /* update HP, line and mono-out pins according to the master switch */
8943 static void alc262_hp_master_update(struct hda_codec *codec)
8945 struct alc_spec *spec = codec->spec;
8946 int val = spec->master_sw;
8949 snd_hda_codec_write_cache(codec, 0x1b, 0,
8950 AC_VERB_SET_PIN_WIDGET_CONTROL,
8952 snd_hda_codec_write_cache(codec, 0x15, 0,
8953 AC_VERB_SET_PIN_WIDGET_CONTROL,
8955 /* mono (speaker) depending on the HP jack sense */
8956 val = val && !spec->jack_present;
8957 snd_hda_codec_write_cache(codec, 0x16, 0,
8958 AC_VERB_SET_PIN_WIDGET_CONTROL,
8962 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8964 struct alc_spec *spec = codec->spec;
8965 unsigned int presence;
8966 presence = snd_hda_codec_read(codec, 0x1b, 0,
8967 AC_VERB_GET_PIN_SENSE, 0);
8968 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8969 alc262_hp_master_update(codec);
8972 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8974 if ((res >> 26) != ALC880_HP_EVENT)
8976 alc262_hp_bpc_automute(codec);
8979 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8981 struct alc_spec *spec = codec->spec;
8982 unsigned int presence;
8983 presence = snd_hda_codec_read(codec, 0x15, 0,
8984 AC_VERB_GET_PIN_SENSE, 0);
8985 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8986 alc262_hp_master_update(codec);
8989 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8992 if ((res >> 26) != ALC880_HP_EVENT)
8994 alc262_hp_wildwest_automute(codec);
8997 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8998 struct snd_ctl_elem_value *ucontrol)
9000 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9001 struct alc_spec *spec = codec->spec;
9002 *ucontrol->value.integer.value = spec->master_sw;
9006 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9007 struct snd_ctl_elem_value *ucontrol)
9009 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9010 struct alc_spec *spec = codec->spec;
9011 int val = !!*ucontrol->value.integer.value;
9013 if (val == spec->master_sw)
9015 spec->master_sw = val;
9016 alc262_hp_master_update(codec);
9020 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9023 .name = "Master Playback Switch",
9024 .info = snd_ctl_boolean_mono_info,
9025 .get = alc262_hp_master_sw_get,
9026 .put = alc262_hp_master_sw_put,
9028 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9029 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9030 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9031 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9033 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9035 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9036 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9037 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9038 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9041 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9042 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9043 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9044 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9045 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9046 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9047 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9048 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9052 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9055 .name = "Master Playback Switch",
9056 .info = snd_ctl_boolean_mono_info,
9057 .get = alc262_hp_master_sw_get,
9058 .put = alc262_hp_master_sw_put,
9060 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9061 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9062 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9064 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9066 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9068 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9070 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9071 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9072 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9073 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9074 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9075 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9076 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9080 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9081 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9082 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9083 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9087 /* mute/unmute internal speaker according to the hp jack and mute state */
9088 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9090 struct alc_spec *spec = codec->spec;
9092 if (force || !spec->sense_updated) {
9093 unsigned int present;
9094 present = snd_hda_codec_read(codec, 0x15, 0,
9095 AC_VERB_GET_PIN_SENSE, 0);
9096 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9097 spec->sense_updated = 1;
9099 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9100 spec->jack_present ? HDA_AMP_MUTE : 0);
9103 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9106 if ((res >> 26) != ALC880_HP_EVENT)
9108 alc262_hp_t5735_automute(codec, 1);
9111 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9113 alc262_hp_t5735_automute(codec, 1);
9116 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9117 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9118 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9119 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9122 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9123 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9127 static struct hda_verb alc262_hp_t5735_verbs[] = {
9128 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9129 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9135 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9136 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9138 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9139 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9145 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9146 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9147 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9151 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9159 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9166 /* bind hp and internal speaker mute (with plug check) */
9167 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9168 struct snd_ctl_elem_value *ucontrol)
9170 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9171 long *valp = ucontrol->value.integer.value;
9174 /* change hp mute */
9175 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9177 valp[0] ? 0 : HDA_AMP_MUTE);
9178 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9180 valp[1] ? 0 : HDA_AMP_MUTE);
9182 /* change speaker according to HP jack state */
9183 struct alc_spec *spec = codec->spec;
9185 if (spec->jack_present)
9186 mute = HDA_AMP_MUTE;
9188 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9191 HDA_AMP_MUTE, mute);
9196 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9197 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9200 .name = "Master Playback Switch",
9201 .info = snd_hda_mixer_amp_switch_info,
9202 .get = snd_hda_mixer_amp_switch_get,
9203 .put = alc262_sony_master_sw_put,
9204 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9207 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9208 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9209 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9213 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9214 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9215 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9216 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9219 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9220 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9224 #define alc262_capture_mixer alc882_capture_mixer
9225 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9228 * generic initialization of ADC, input mixers and output mixers
9230 static struct hda_verb alc262_init_verbs[] = {
9232 * Unmute ADC0-2 and set the default input to mic-in
9234 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9235 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9236 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9238 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9239 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9241 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9243 * Note: PASD motherboards uses the Line In 2 as the input for
9244 * front panel mic (mic 2)
9246 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9254 * Set up output mixers (0x0c - 0x0e)
9256 /* set vol=0 to output mixers */
9257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9260 /* set up input amps for analog loopback */
9261 /* Amp Indices: DAC = 0, mixer = 1 */
9262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9264 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9266 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9267 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9272 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9273 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9276 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9278 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9279 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9285 /* FIXME: use matrix-type input source selection */
9286 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9287 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9288 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9289 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9290 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9291 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9295 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9296 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9298 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9300 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9301 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9306 static struct hda_verb alc262_eapd_verbs[] = {
9307 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9312 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9313 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9318 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9320 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9323 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9324 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9328 static struct hda_verb alc262_sony_unsol_verbs[] = {
9329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9330 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9331 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9334 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9338 static struct hda_input_mux alc262_dmic_capture_source = {
9341 { "Int DMic", 0x9 },
9346 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9347 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9348 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9349 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9352 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9353 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9356 /* The multiple "Capture Source" controls confuse alsamixer
9357 * So call somewhat different..
9359 /* .name = "Capture Source", */
9360 .name = "Input Source",
9362 .info = alc_mux_enum_info,
9363 .get = alc_mux_enum_get,
9364 .put = alc_mux_enum_put,
9369 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9370 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9372 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9374 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9377 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9381 static void alc262_dmic_automute(struct hda_codec *codec)
9383 unsigned int present;
9385 present = snd_hda_codec_read(codec, 0x18, 0,
9386 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9387 snd_hda_codec_write(codec, 0x22, 0,
9388 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9391 /* toggle speaker-output according to the hp-jack state */
9392 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9394 unsigned int present;
9397 present = snd_hda_codec_read(codec, 0x15, 0,
9398 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9399 bits = present ? 0 : PIN_OUT;
9400 snd_hda_codec_write(codec, 0x14, 0,
9401 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9406 /* unsolicited event for HP jack sensing */
9407 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9410 if ((res >> 26) == ALC880_HP_EVENT)
9411 alc262_toshiba_s06_speaker_automute(codec);
9412 if ((res >> 26) == ALC880_MIC_EVENT)
9413 alc262_dmic_automute(codec);
9417 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9419 alc262_toshiba_s06_speaker_automute(codec);
9420 alc262_dmic_automute(codec);
9423 /* mute/unmute internal speaker according to the hp jack and mute state */
9424 static void alc262_hippo_automute(struct hda_codec *codec)
9426 struct alc_spec *spec = codec->spec;
9428 unsigned int present;
9430 /* need to execute and sync at first */
9431 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9432 present = snd_hda_codec_read(codec, 0x15, 0,
9433 AC_VERB_GET_PIN_SENSE, 0);
9434 spec->jack_present = (present & 0x80000000) != 0;
9435 if (spec->jack_present) {
9436 /* mute internal speaker */
9437 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9438 HDA_AMP_MUTE, HDA_AMP_MUTE);
9440 /* unmute internal speaker if necessary */
9441 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9442 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9443 HDA_AMP_MUTE, mute);
9447 /* unsolicited event for HP jack sensing */
9448 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9451 if ((res >> 26) != ALC880_HP_EVENT)
9453 alc262_hippo_automute(codec);
9456 static void alc262_hippo1_automute(struct hda_codec *codec)
9459 unsigned int present;
9461 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9462 present = snd_hda_codec_read(codec, 0x1b, 0,
9463 AC_VERB_GET_PIN_SENSE, 0);
9464 present = (present & 0x80000000) != 0;
9466 /* mute internal speaker */
9467 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9468 HDA_AMP_MUTE, HDA_AMP_MUTE);
9470 /* unmute internal speaker if necessary */
9471 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9472 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9473 HDA_AMP_MUTE, mute);
9477 /* unsolicited event for HP jack sensing */
9478 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9481 if ((res >> 26) != ALC880_HP_EVENT)
9483 alc262_hippo1_automute(codec);
9489 * 0x16 = internal speaker
9490 * 0x18 = external mic
9493 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9494 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9495 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9499 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9501 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9506 static struct hda_verb alc262_nec_verbs[] = {
9507 /* Unmute Speaker */
9508 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9511 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9514 /* External mic to headphone */
9515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9516 /* External mic to speaker */
9517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9523 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9524 * 0x1b = port replicator headphone out
9527 #define ALC_HP_EVENT 0x37
9529 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9530 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9532 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9533 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9537 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9538 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9543 static struct hda_input_mux alc262_fujitsu_capture_source = {
9552 static struct hda_input_mux alc262_HP_capture_source = {
9556 { "Front Mic", 0x1 },
9563 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9567 { "Front Mic", 0x2 },
9573 /* mute/unmute internal speaker according to the hp jacks and mute state */
9574 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9576 struct alc_spec *spec = codec->spec;
9579 if (force || !spec->sense_updated) {
9580 unsigned int present;
9581 /* need to execute and sync at first */
9582 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9583 /* check laptop HP jack */
9584 present = snd_hda_codec_read(codec, 0x14, 0,
9585 AC_VERB_GET_PIN_SENSE, 0);
9586 /* need to execute and sync at first */
9587 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9588 /* check docking HP jack */
9589 present |= snd_hda_codec_read(codec, 0x1b, 0,
9590 AC_VERB_GET_PIN_SENSE, 0);
9591 if (present & AC_PINSENSE_PRESENCE)
9592 spec->jack_present = 1;
9594 spec->jack_present = 0;
9595 spec->sense_updated = 1;
9597 /* unmute internal speaker only if both HPs are unplugged and
9598 * master switch is on
9600 if (spec->jack_present)
9601 mute = HDA_AMP_MUTE;
9603 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9604 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9605 HDA_AMP_MUTE, mute);
9608 /* unsolicited event for HP jack sensing */
9609 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9612 if ((res >> 26) != ALC_HP_EVENT)
9614 alc262_fujitsu_automute(codec, 1);
9617 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9619 alc262_fujitsu_automute(codec, 1);
9622 /* bind volumes of both NID 0x0c and 0x0d */
9623 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9624 .ops = &snd_hda_bind_vol,
9626 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9627 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9632 /* mute/unmute internal speaker according to the hp jack and mute state */
9633 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9635 struct alc_spec *spec = codec->spec;
9638 if (force || !spec->sense_updated) {
9639 unsigned int present_int_hp;
9640 /* need to execute and sync at first */
9641 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9642 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9643 AC_VERB_GET_PIN_SENSE, 0);
9644 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9645 spec->sense_updated = 1;
9647 if (spec->jack_present) {
9648 /* mute internal speaker */
9649 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9650 HDA_AMP_MUTE, HDA_AMP_MUTE);
9651 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9652 HDA_AMP_MUTE, HDA_AMP_MUTE);
9654 /* unmute internal speaker if necessary */
9655 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9656 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9657 HDA_AMP_MUTE, mute);
9658 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9659 HDA_AMP_MUTE, mute);
9663 /* unsolicited event for HP jack sensing */
9664 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9667 if ((res >> 26) != ALC_HP_EVENT)
9669 alc262_lenovo_3000_automute(codec, 1);
9672 /* bind hp and internal speaker mute (with plug check) */
9673 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9674 struct snd_ctl_elem_value *ucontrol)
9676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9677 long *valp = ucontrol->value.integer.value;
9680 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9682 valp ? 0 : HDA_AMP_MUTE);
9683 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9685 valp ? 0 : HDA_AMP_MUTE);
9688 alc262_fujitsu_automute(codec, 0);
9692 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9693 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9696 .name = "Master Playback Switch",
9697 .info = snd_hda_mixer_amp_switch_info,
9698 .get = snd_hda_mixer_amp_switch_get,
9699 .put = alc262_fujitsu_master_sw_put,
9700 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9704 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9705 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9706 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9709 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9710 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9711 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9715 /* bind hp and internal speaker mute (with plug check) */
9716 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9717 struct snd_ctl_elem_value *ucontrol)
9719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9720 long *valp = ucontrol->value.integer.value;
9723 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9725 valp ? 0 : HDA_AMP_MUTE);
9728 alc262_lenovo_3000_automute(codec, 0);
9732 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9733 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9736 .name = "Master Playback Switch",
9737 .info = snd_hda_mixer_amp_switch_info,
9738 .get = snd_hda_mixer_amp_switch_get,
9739 .put = alc262_lenovo_3000_master_sw_put,
9740 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9742 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9743 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9744 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9747 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9748 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9749 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9753 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9754 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9757 .name = "Master Playback Switch",
9758 .info = snd_hda_mixer_amp_switch_info,
9759 .get = snd_hda_mixer_amp_switch_get,
9760 .put = alc262_sony_master_sw_put,
9761 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9765 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9766 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9767 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9768 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9772 /* additional init verbs for Benq laptops */
9773 static struct hda_verb alc262_EAPD_verbs[] = {
9774 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9775 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9779 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9783 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9784 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9788 /* Samsung Q1 Ultra Vista model setup */
9789 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9790 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9791 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9794 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9795 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9799 static struct hda_verb alc262_ultra_verbs[] = {
9801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9803 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9805 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9807 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9808 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9813 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9814 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9817 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9818 /* ADC, choose mic */
9819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9820 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9821 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9822 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9823 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9824 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9825 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9826 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9827 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9828 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9832 /* mute/unmute internal speaker according to the hp jack and mute state */
9833 static void alc262_ultra_automute(struct hda_codec *codec)
9835 struct alc_spec *spec = codec->spec;
9839 /* auto-mute only when HP is used as HP */
9840 if (!spec->cur_mux[0]) {
9841 unsigned int present;
9842 /* need to execute and sync at first */
9843 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9844 present = snd_hda_codec_read(codec, 0x15, 0,
9845 AC_VERB_GET_PIN_SENSE, 0);
9846 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9847 if (spec->jack_present)
9848 mute = HDA_AMP_MUTE;
9850 /* mute/unmute internal speaker */
9851 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9852 HDA_AMP_MUTE, mute);
9853 /* mute/unmute HP */
9854 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9855 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9858 /* unsolicited event for HP jack sensing */
9859 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9862 if ((res >> 26) != ALC880_HP_EVENT)
9864 alc262_ultra_automute(codec);
9867 static struct hda_input_mux alc262_ultra_capture_source = {
9871 { "Headphone", 0x7 },
9875 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9876 struct snd_ctl_elem_value *ucontrol)
9878 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9879 struct alc_spec *spec = codec->spec;
9882 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9885 /* reprogram the HP pin as mic or HP according to the input source */
9886 snd_hda_codec_write_cache(codec, 0x15, 0,
9887 AC_VERB_SET_PIN_WIDGET_CONTROL,
9888 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9889 alc262_ultra_automute(codec); /* mute/unmute HP */
9893 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9894 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9895 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9897 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9898 .name = "Capture Source",
9899 .info = alc882_mux_enum_info,
9900 .get = alc882_mux_enum_get,
9901 .put = alc262_ultra_mux_enum_put,
9906 /* add playback controls from the parsed DAC table */
9907 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9908 const struct auto_pin_cfg *cfg)
9913 spec->multiout.num_dacs = 1; /* only use one dac */
9914 spec->multiout.dac_nids = spec->private_dac_nids;
9915 spec->multiout.dac_nids[0] = 2;
9917 nid = cfg->line_out_pins[0];
9919 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9920 "Front Playback Volume",
9921 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9924 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9925 "Front Playback Switch",
9926 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9931 nid = cfg->speaker_pins[0];
9934 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9935 "Speaker Playback Volume",
9936 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9940 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9941 "Speaker Playback Switch",
9942 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9947 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9948 "Speaker Playback Switch",
9949 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9955 nid = cfg->hp_pins[0];
9957 /* spec->multiout.hp_nid = 2; */
9959 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9960 "Headphone Playback Volume",
9961 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9965 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9966 "Headphone Playback Switch",
9967 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9972 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9973 "Headphone Playback Switch",
9974 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9983 /* identical with ALC880 */
9984 #define alc262_auto_create_analog_input_ctls \
9985 alc880_auto_create_analog_input_ctls
9988 * generic initialization of ADC, input mixers and output mixers
9990 static struct hda_verb alc262_volume_init_verbs[] = {
9992 * Unmute ADC0-2 and set the default input to mic-in
9994 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9996 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9997 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9998 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9999 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10001 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10003 * Note: PASD motherboards uses the Line In 2 as the input for
10004 * front panel mic (mic 2)
10006 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10014 * Set up output mixers (0x0c - 0x0f)
10016 /* set vol=0 to output mixers */
10017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10019 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10021 /* set up input amps for analog loopback */
10022 /* Amp Indices: DAC = 0, mixer = 1 */
10023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10025 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10027 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10030 /* FIXME: use matrix-type input source selection */
10031 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10032 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10033 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10034 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10038 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10039 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10041 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10051 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10053 * Unmute ADC0-2 and set the default input to mic-in
10055 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10057 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10058 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10059 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10060 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10062 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10064 * Note: PASD motherboards uses the Line In 2 as the input for
10065 * front panel mic (mic 2)
10067 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10070 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10072 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10073 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10074 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10077 * Set up output mixers (0x0c - 0x0e)
10079 /* set vol=0 to output mixers */
10080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10081 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10082 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10084 /* set up input amps for analog loopback */
10085 /* Amp Indices: DAC = 0, mixer = 1 */
10086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10087 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10088 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10089 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10090 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10091 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10093 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10094 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10095 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10097 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10100 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10101 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10103 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10104 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10105 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10106 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10107 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10111 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10112 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10113 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10114 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10117 /* FIXME: use matrix-type input source selection */
10118 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10119 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10125 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10130 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10135 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10140 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10142 * Unmute ADC0-2 and set the default input to mic-in
10144 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10146 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10148 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10149 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10151 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10153 * Note: PASD motherboards uses the Line In 2 as the input for front
10154 * panel mic (mic 2)
10156 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10159 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10160 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10161 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10162 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10163 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10164 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10166 * Set up output mixers (0x0c - 0x0e)
10168 /* set vol=0 to output mixers */
10169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10171 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10173 /* set up input amps for analog loopback */
10174 /* Amp Indices: DAC = 0, mixer = 1 */
10175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10184 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10185 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10186 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10187 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10188 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10189 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10191 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10194 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10195 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10197 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10200 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10201 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10202 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10204 /* FIXME: use matrix-type input source selection */
10205 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10206 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10212 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10213 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10220 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10221 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10228 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10229 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10231 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10236 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10238 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10239 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10240 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10243 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10245 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10247 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10249 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10254 #ifdef CONFIG_SND_HDA_POWER_SAVE
10255 #define alc262_loopbacks alc880_loopbacks
10258 /* pcm configuration: identiacal with ALC880 */
10259 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10260 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10261 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10262 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10265 * BIOS auto configuration
10267 static int alc262_parse_auto_config(struct hda_codec *codec)
10269 struct alc_spec *spec = codec->spec;
10271 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10273 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10277 if (!spec->autocfg.line_outs)
10278 return 0; /* can't find valid BIOS pin config */
10279 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10282 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10286 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10288 if (spec->autocfg.dig_out_pin)
10289 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10290 if (spec->autocfg.dig_in_pin)
10291 spec->dig_in_nid = ALC262_DIGIN_NID;
10293 if (spec->kctls.list)
10294 spec->mixers[spec->num_mixers++] = spec->kctls.list;
10296 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10297 spec->num_mux_defs = 1;
10298 spec->input_mux = &spec->private_imux;
10300 err = alc_auto_add_mic_boost(codec);
10307 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10308 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10309 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10310 #define alc262_auto_init_input_src alc882_auto_init_input_src
10313 /* init callback for auto-configuration model -- overriding the default init */
10314 static void alc262_auto_init(struct hda_codec *codec)
10316 struct alc_spec *spec = codec->spec;
10317 alc262_auto_init_multi_out(codec);
10318 alc262_auto_init_hp_out(codec);
10319 alc262_auto_init_analog_input(codec);
10320 alc262_auto_init_input_src(codec);
10321 if (spec->unsol_event)
10322 alc_inithook(codec);
10326 * configuration and preset
10328 static const char *alc262_models[ALC262_MODEL_LAST] = {
10329 [ALC262_BASIC] = "basic",
10330 [ALC262_HIPPO] = "hippo",
10331 [ALC262_HIPPO_1] = "hippo_1",
10332 [ALC262_FUJITSU] = "fujitsu",
10333 [ALC262_HP_BPC] = "hp-bpc",
10334 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10335 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10336 [ALC262_HP_RP5700] = "hp-rp5700",
10337 [ALC262_BENQ_ED8] = "benq",
10338 [ALC262_BENQ_T31] = "benq-t31",
10339 [ALC262_SONY_ASSAMD] = "sony-assamd",
10340 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10341 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10342 [ALC262_ULTRA] = "ultra",
10343 [ALC262_LENOVO_3000] = "lenovo-3000",
10344 [ALC262_NEC] = "nec",
10345 [ALC262_AUTO] = "auto",
10348 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10349 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10350 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10351 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10352 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10353 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10354 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10355 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10356 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10357 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10358 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10359 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10360 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10361 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10362 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10363 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10364 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10365 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10366 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10367 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10368 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10369 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10370 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10371 ALC262_HP_TC_T5735),
10372 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10373 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10374 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10375 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10376 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10377 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10378 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10379 ALC262_TOSHIBA_RX1),
10380 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10381 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10382 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10383 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10384 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10385 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10386 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10387 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10388 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10392 static struct alc_config_preset alc262_presets[] = {
10394 .mixers = { alc262_base_mixer },
10395 .init_verbs = { alc262_init_verbs },
10396 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10397 .dac_nids = alc262_dac_nids,
10399 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10400 .channel_mode = alc262_modes,
10401 .input_mux = &alc262_capture_source,
10404 .mixers = { alc262_base_mixer },
10405 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10406 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10407 .dac_nids = alc262_dac_nids,
10409 .dig_out_nid = ALC262_DIGOUT_NID,
10410 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10411 .channel_mode = alc262_modes,
10412 .input_mux = &alc262_capture_source,
10413 .unsol_event = alc262_hippo_unsol_event,
10414 .init_hook = alc262_hippo_automute,
10416 [ALC262_HIPPO_1] = {
10417 .mixers = { alc262_hippo1_mixer },
10418 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10419 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10420 .dac_nids = alc262_dac_nids,
10422 .dig_out_nid = ALC262_DIGOUT_NID,
10423 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10424 .channel_mode = alc262_modes,
10425 .input_mux = &alc262_capture_source,
10426 .unsol_event = alc262_hippo1_unsol_event,
10427 .init_hook = alc262_hippo1_automute,
10429 [ALC262_FUJITSU] = {
10430 .mixers = { alc262_fujitsu_mixer },
10431 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10432 alc262_fujitsu_unsol_verbs },
10433 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10434 .dac_nids = alc262_dac_nids,
10436 .dig_out_nid = ALC262_DIGOUT_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10438 .channel_mode = alc262_modes,
10439 .input_mux = &alc262_fujitsu_capture_source,
10440 .unsol_event = alc262_fujitsu_unsol_event,
10441 .init_hook = alc262_fujitsu_init_hook,
10443 [ALC262_HP_BPC] = {
10444 .mixers = { alc262_HP_BPC_mixer },
10445 .init_verbs = { alc262_HP_BPC_init_verbs },
10446 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10447 .dac_nids = alc262_dac_nids,
10449 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10450 .channel_mode = alc262_modes,
10451 .input_mux = &alc262_HP_capture_source,
10452 .unsol_event = alc262_hp_bpc_unsol_event,
10453 .init_hook = alc262_hp_bpc_automute,
10455 [ALC262_HP_BPC_D7000_WF] = {
10456 .mixers = { alc262_HP_BPC_WildWest_mixer },
10457 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10458 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10459 .dac_nids = alc262_dac_nids,
10461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10462 .channel_mode = alc262_modes,
10463 .input_mux = &alc262_HP_D7000_capture_source,
10464 .unsol_event = alc262_hp_wildwest_unsol_event,
10465 .init_hook = alc262_hp_wildwest_automute,
10467 [ALC262_HP_BPC_D7000_WL] = {
10468 .mixers = { alc262_HP_BPC_WildWest_mixer,
10469 alc262_HP_BPC_WildWest_option_mixer },
10470 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10471 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10472 .dac_nids = alc262_dac_nids,
10474 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10475 .channel_mode = alc262_modes,
10476 .input_mux = &alc262_HP_D7000_capture_source,
10477 .unsol_event = alc262_hp_wildwest_unsol_event,
10478 .init_hook = alc262_hp_wildwest_automute,
10480 [ALC262_HP_TC_T5735] = {
10481 .mixers = { alc262_hp_t5735_mixer },
10482 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10483 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10484 .dac_nids = alc262_dac_nids,
10486 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10487 .channel_mode = alc262_modes,
10488 .input_mux = &alc262_capture_source,
10489 .unsol_event = alc262_hp_t5735_unsol_event,
10490 .init_hook = alc262_hp_t5735_init_hook,
10492 [ALC262_HP_RP5700] = {
10493 .mixers = { alc262_hp_rp5700_mixer },
10494 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10495 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10496 .dac_nids = alc262_dac_nids,
10497 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10498 .channel_mode = alc262_modes,
10499 .input_mux = &alc262_hp_rp5700_capture_source,
10501 [ALC262_BENQ_ED8] = {
10502 .mixers = { alc262_base_mixer },
10503 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10504 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10505 .dac_nids = alc262_dac_nids,
10507 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10508 .channel_mode = alc262_modes,
10509 .input_mux = &alc262_capture_source,
10511 [ALC262_SONY_ASSAMD] = {
10512 .mixers = { alc262_sony_mixer },
10513 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10514 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10515 .dac_nids = alc262_dac_nids,
10517 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10518 .channel_mode = alc262_modes,
10519 .input_mux = &alc262_capture_source,
10520 .unsol_event = alc262_hippo_unsol_event,
10521 .init_hook = alc262_hippo_automute,
10523 [ALC262_BENQ_T31] = {
10524 .mixers = { alc262_benq_t31_mixer },
10525 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10527 .dac_nids = alc262_dac_nids,
10529 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10530 .channel_mode = alc262_modes,
10531 .input_mux = &alc262_capture_source,
10532 .unsol_event = alc262_hippo_unsol_event,
10533 .init_hook = alc262_hippo_automute,
10536 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10537 .init_verbs = { alc262_ultra_verbs },
10538 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10539 .dac_nids = alc262_dac_nids,
10540 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10541 .channel_mode = alc262_modes,
10542 .input_mux = &alc262_ultra_capture_source,
10543 .adc_nids = alc262_adc_nids, /* ADC0 */
10544 .capsrc_nids = alc262_capsrc_nids,
10545 .num_adc_nids = 1, /* single ADC */
10546 .unsol_event = alc262_ultra_unsol_event,
10547 .init_hook = alc262_ultra_automute,
10549 [ALC262_LENOVO_3000] = {
10550 .mixers = { alc262_lenovo_3000_mixer },
10551 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10552 alc262_lenovo_3000_unsol_verbs },
10553 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10554 .dac_nids = alc262_dac_nids,
10556 .dig_out_nid = ALC262_DIGOUT_NID,
10557 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10558 .channel_mode = alc262_modes,
10559 .input_mux = &alc262_fujitsu_capture_source,
10560 .unsol_event = alc262_lenovo_3000_unsol_event,
10563 .mixers = { alc262_nec_mixer },
10564 .init_verbs = { alc262_nec_verbs },
10565 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10566 .dac_nids = alc262_dac_nids,
10568 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10569 .channel_mode = alc262_modes,
10570 .input_mux = &alc262_capture_source,
10572 [ALC262_TOSHIBA_S06] = {
10573 .mixers = { alc262_toshiba_s06_mixer },
10574 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10575 alc262_eapd_verbs },
10576 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10577 .capsrc_nids = alc262_dmic_capsrc_nids,
10578 .dac_nids = alc262_dac_nids,
10579 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10580 .dig_out_nid = ALC262_DIGOUT_NID,
10581 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10582 .channel_mode = alc262_modes,
10583 .input_mux = &alc262_dmic_capture_source,
10584 .unsol_event = alc262_toshiba_s06_unsol_event,
10585 .init_hook = alc262_toshiba_s06_init_hook,
10587 [ALC262_TOSHIBA_RX1] = {
10588 .mixers = { alc262_toshiba_rx1_mixer },
10589 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10590 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10591 .dac_nids = alc262_dac_nids,
10593 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10594 .channel_mode = alc262_modes,
10595 .input_mux = &alc262_capture_source,
10596 .unsol_event = alc262_hippo_unsol_event,
10597 .init_hook = alc262_hippo_automute,
10601 static int patch_alc262(struct hda_codec *codec)
10603 struct alc_spec *spec;
10607 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10611 codec->spec = spec;
10613 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10618 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10619 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10620 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10621 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10625 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10627 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10631 if (board_config < 0) {
10632 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10633 "trying auto-probe from BIOS...\n");
10634 board_config = ALC262_AUTO;
10637 if (board_config == ALC262_AUTO) {
10638 /* automatic parse from the BIOS config */
10639 err = alc262_parse_auto_config(codec);
10645 "hda_codec: Cannot set up configuration "
10646 "from BIOS. Using base mode...\n");
10647 board_config = ALC262_BASIC;
10651 if (board_config != ALC262_AUTO)
10652 setup_preset(spec, &alc262_presets[board_config]);
10654 spec->stream_name_analog = "ALC262 Analog";
10655 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10656 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10658 spec->stream_name_digital = "ALC262 Digital";
10659 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10660 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10662 if (!spec->adc_nids && spec->input_mux) {
10663 /* check whether NID 0x07 is valid */
10664 unsigned int wcap = get_wcaps(codec, 0x07);
10667 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10668 if (wcap != AC_WID_AUD_IN) {
10669 spec->adc_nids = alc262_adc_nids_alt;
10670 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10671 spec->capsrc_nids = alc262_capsrc_nids_alt;
10672 spec->mixers[spec->num_mixers] =
10673 alc262_capture_alt_mixer;
10674 spec->num_mixers++;
10676 spec->adc_nids = alc262_adc_nids;
10677 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10678 spec->capsrc_nids = alc262_capsrc_nids;
10679 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10680 spec->num_mixers++;
10684 spec->vmaster_nid = 0x0c;
10686 codec->patch_ops = alc_patch_ops;
10687 if (board_config == ALC262_AUTO)
10688 spec->init_hook = alc262_auto_init;
10689 #ifdef CONFIG_SND_HDA_POWER_SAVE
10690 if (!spec->loopback.amplist)
10691 spec->loopback.amplist = alc262_loopbacks;
10698 * ALC268 channel source setting (2 channel)
10700 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10701 #define alc268_modes alc260_modes
10703 static hda_nid_t alc268_dac_nids[2] = {
10708 static hda_nid_t alc268_adc_nids[2] = {
10713 static hda_nid_t alc268_adc_nids_alt[1] = {
10718 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10720 static struct snd_kcontrol_new alc268_base_mixer[] = {
10721 /* output mixer control */
10722 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10723 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10726 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10727 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10728 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10732 /* bind Beep switches of both NID 0x0f and 0x10 */
10733 static struct hda_bind_ctls alc268_bind_beep_sw = {
10734 .ops = &snd_hda_bind_sw,
10736 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10737 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10742 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10743 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10744 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10748 static struct hda_verb alc268_eapd_verbs[] = {
10749 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10750 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10754 /* Toshiba specific */
10755 #define alc268_toshiba_automute alc262_hippo_automute
10757 static struct hda_verb alc268_toshiba_verbs[] = {
10758 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10762 static struct hda_input_mux alc268_acer_lc_capture_source = {
10770 /* Acer specific */
10771 /* bind volumes of both NID 0x02 and 0x03 */
10772 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10773 .ops = &snd_hda_bind_vol,
10775 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10776 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10781 /* mute/unmute internal speaker according to the hp jack and mute state */
10782 static void alc268_acer_automute(struct hda_codec *codec, int force)
10784 struct alc_spec *spec = codec->spec;
10787 if (force || !spec->sense_updated) {
10788 unsigned int present;
10789 present = snd_hda_codec_read(codec, 0x14, 0,
10790 AC_VERB_GET_PIN_SENSE, 0);
10791 spec->jack_present = (present & 0x80000000) != 0;
10792 spec->sense_updated = 1;
10794 if (spec->jack_present)
10795 mute = HDA_AMP_MUTE; /* mute internal speaker */
10796 else /* unmute internal speaker if necessary */
10797 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10798 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10799 HDA_AMP_MUTE, mute);
10803 /* bind hp and internal speaker mute (with plug check) */
10804 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10805 struct snd_ctl_elem_value *ucontrol)
10807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10808 long *valp = ucontrol->value.integer.value;
10811 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10813 valp[0] ? 0 : HDA_AMP_MUTE);
10814 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10816 valp[1] ? 0 : HDA_AMP_MUTE);
10818 alc268_acer_automute(codec, 0);
10822 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10823 /* output mixer control */
10824 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10827 .name = "Master Playback Switch",
10828 .info = snd_hda_mixer_amp_switch_info,
10829 .get = snd_hda_mixer_amp_switch_get,
10830 .put = alc268_acer_master_sw_put,
10831 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10833 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10837 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10838 /* output mixer control */
10839 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10842 .name = "Master Playback Switch",
10843 .info = snd_hda_mixer_amp_switch_info,
10844 .get = snd_hda_mixer_amp_switch_get,
10845 .put = alc268_acer_master_sw_put,
10846 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10848 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10849 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10850 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10854 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10855 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10856 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10858 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10859 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10860 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10864 static struct hda_verb alc268_acer_verbs[] = {
10865 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10866 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10867 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10868 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10869 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10870 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10871 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10875 /* unsolicited event for HP jack sensing */
10876 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10879 if ((res >> 26) != ALC880_HP_EVENT)
10881 alc268_toshiba_automute(codec);
10884 static void alc268_acer_unsol_event(struct hda_codec *codec,
10887 if ((res >> 26) != ALC880_HP_EVENT)
10889 alc268_acer_automute(codec, 1);
10892 static void alc268_acer_init_hook(struct hda_codec *codec)
10894 alc268_acer_automute(codec, 1);
10897 /* toggle speaker-output according to the hp-jack state */
10898 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10900 unsigned int present;
10901 unsigned char bits;
10903 present = snd_hda_codec_read(codec, 0x15, 0,
10904 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10905 bits = present ? AMP_IN_MUTE(0) : 0;
10906 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10907 AMP_IN_MUTE(0), bits);
10908 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10909 AMP_IN_MUTE(0), bits);
10913 static void alc268_acer_mic_automute(struct hda_codec *codec)
10915 unsigned int present;
10917 present = snd_hda_codec_read(codec, 0x18, 0,
10918 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10919 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10920 present ? 0x0 : 0x6);
10923 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10926 if ((res >> 26) == ALC880_HP_EVENT)
10927 alc268_aspire_one_speaker_automute(codec);
10928 if ((res >> 26) == ALC880_MIC_EVENT)
10929 alc268_acer_mic_automute(codec);
10932 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10934 alc268_aspire_one_speaker_automute(codec);
10935 alc268_acer_mic_automute(codec);
10938 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10939 /* output mixer control */
10940 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10941 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10942 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10943 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10944 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10945 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10949 static struct hda_verb alc268_dell_verbs[] = {
10950 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10951 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10952 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10956 /* mute/unmute internal speaker according to the hp jack and mute state */
10957 static void alc268_dell_automute(struct hda_codec *codec)
10959 unsigned int present;
10962 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10963 if (present & 0x80000000)
10964 mute = HDA_AMP_MUTE;
10966 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10967 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10968 HDA_AMP_MUTE, mute);
10971 static void alc268_dell_unsol_event(struct hda_codec *codec,
10974 if ((res >> 26) != ALC880_HP_EVENT)
10976 alc268_dell_automute(codec);
10979 #define alc268_dell_init_hook alc268_dell_automute
10981 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10982 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10983 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10984 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10986 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10987 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10988 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10989 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10993 static struct hda_verb alc267_quanta_il1_verbs[] = {
10994 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10995 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10999 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11001 unsigned int present;
11003 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11004 & AC_PINSENSE_PRESENCE;
11005 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11006 present ? 0 : PIN_OUT);
11009 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11011 unsigned int present;
11013 present = snd_hda_codec_read(codec, 0x18, 0,
11014 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11015 snd_hda_codec_write(codec, 0x23, 0,
11016 AC_VERB_SET_CONNECT_SEL,
11017 present ? 0x00 : 0x01);
11020 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11022 alc267_quanta_il1_hp_automute(codec);
11023 alc267_quanta_il1_mic_automute(codec);
11026 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11029 switch (res >> 26) {
11030 case ALC880_HP_EVENT:
11031 alc267_quanta_il1_hp_automute(codec);
11033 case ALC880_MIC_EVENT:
11034 alc267_quanta_il1_mic_automute(codec);
11040 * generic initialization of ADC, input mixers and output mixers
11042 static struct hda_verb alc268_base_init_verbs[] = {
11043 /* Unmute DAC0-1 and set vol = 0 */
11044 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11045 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11046 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11047 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11048 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11049 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11052 * Set up output mixers (0x0c - 0x0e)
11054 /* set vol=0 to output mixers */
11055 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11056 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11057 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11058 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11060 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11061 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11066 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11067 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11068 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11069 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11070 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11073 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11074 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11076 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11078 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11080 /* set PCBEEP vol = 0, mute connections */
11081 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11083 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11085 /* Unmute Selector 23h,24h and set the default input to mic-in */
11087 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11088 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11089 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11096 * generic initialization of ADC, input mixers and output mixers
11098 static struct hda_verb alc268_volume_init_verbs[] = {
11099 /* set output DAC */
11100 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11101 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11102 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11103 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11105 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11106 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11107 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11108 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11109 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11112 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11115 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11117 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11118 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11119 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11120 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11122 /* set PCBEEP vol = 0, mute connections */
11123 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11125 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11130 #define alc268_mux_enum_info alc_mux_enum_info
11131 #define alc268_mux_enum_get alc_mux_enum_get
11132 #define alc268_mux_enum_put alc_mux_enum_put
11134 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11135 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11136 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11139 /* The multiple "Capture Source" controls confuse alsamixer
11140 * So call somewhat different..
11142 /* .name = "Capture Source", */
11143 .name = "Input Source",
11145 .info = alc268_mux_enum_info,
11146 .get = alc268_mux_enum_get,
11147 .put = alc268_mux_enum_put,
11152 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11153 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11154 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11155 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11156 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11159 /* The multiple "Capture Source" controls confuse alsamixer
11160 * So call somewhat different..
11162 /* .name = "Capture Source", */
11163 .name = "Input Source",
11165 .info = alc268_mux_enum_info,
11166 .get = alc268_mux_enum_get,
11167 .put = alc268_mux_enum_put,
11172 static struct hda_input_mux alc268_capture_source = {
11176 { "Front Mic", 0x1 },
11182 static struct hda_input_mux alc268_acer_capture_source = {
11186 { "Internal Mic", 0x6 },
11191 #ifdef CONFIG_SND_DEBUG
11192 static struct snd_kcontrol_new alc268_test_mixer[] = {
11193 /* Volume widgets */
11194 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11195 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11196 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11197 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11198 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11199 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11200 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11201 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11202 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11203 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11204 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11205 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11206 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11207 /* The below appears problematic on some hardwares */
11208 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11209 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11210 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11211 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11212 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11214 /* Modes for retasking pin widgets */
11215 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11216 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11217 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11218 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11220 /* Controls for GPIO pins, assuming they are configured as outputs */
11221 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11222 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11223 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11224 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11226 /* Switches to allow the digital SPDIF output pin to be enabled.
11227 * The ALC268 does not have an SPDIF input.
11229 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11231 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11232 * this output to turn on an external amplifier.
11234 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11235 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11241 /* create input playback/capture controls for the given pin */
11242 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11243 const char *ctlname, int idx)
11248 sprintf(name, "%s Playback Volume", ctlname);
11250 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11251 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11255 } else if (nid == 0x15) {
11256 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11257 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11263 sprintf(name, "%s Playback Switch", ctlname);
11264 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11265 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11271 /* add playback controls from the parsed DAC table */
11272 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11273 const struct auto_pin_cfg *cfg)
11278 spec->multiout.num_dacs = 2; /* only use one dac */
11279 spec->multiout.dac_nids = spec->private_dac_nids;
11280 spec->multiout.dac_nids[0] = 2;
11281 spec->multiout.dac_nids[1] = 3;
11283 nid = cfg->line_out_pins[0];
11285 alc268_new_analog_output(spec, nid, "Front", 0);
11287 nid = cfg->speaker_pins[0];
11289 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11290 "Speaker Playback Volume",
11291 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11295 nid = cfg->hp_pins[0];
11297 alc268_new_analog_output(spec, nid, "Headphone", 0);
11299 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11301 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11302 "Mono Playback Switch",
11303 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11310 /* create playback/capture controls for input pins */
11311 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11312 const struct auto_pin_cfg *cfg)
11314 struct hda_input_mux *imux = &spec->private_imux;
11317 for (i = 0; i < AUTO_PIN_LAST; i++) {
11318 switch(cfg->input_pins[i]) {
11320 idx1 = 0; /* Mic 1 */
11323 idx1 = 1; /* Mic 2 */
11326 idx1 = 2; /* Line In */
11333 idx1 = 6; /* digital mics */
11338 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11339 imux->items[imux->num_items].index = idx1;
11345 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11347 struct alc_spec *spec = codec->spec;
11348 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11349 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11350 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11351 unsigned int dac_vol1, dac_vol2;
11354 snd_hda_codec_write(codec, speaker_nid, 0,
11355 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11356 snd_hda_codec_write(codec, 0x0f, 0,
11357 AC_VERB_SET_AMP_GAIN_MUTE,
11359 snd_hda_codec_write(codec, 0x10, 0,
11360 AC_VERB_SET_AMP_GAIN_MUTE,
11363 snd_hda_codec_write(codec, 0x0f, 0,
11364 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11365 snd_hda_codec_write(codec, 0x10, 0,
11366 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11369 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11370 if (line_nid == 0x14)
11371 dac_vol2 = AMP_OUT_ZERO;
11372 else if (line_nid == 0x15)
11373 dac_vol1 = AMP_OUT_ZERO;
11374 if (hp_nid == 0x14)
11375 dac_vol2 = AMP_OUT_ZERO;
11376 else if (hp_nid == 0x15)
11377 dac_vol1 = AMP_OUT_ZERO;
11378 if (line_nid != 0x16 || hp_nid != 0x16 ||
11379 spec->autocfg.line_out_pins[1] != 0x16 ||
11380 spec->autocfg.line_out_pins[2] != 0x16)
11381 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11383 snd_hda_codec_write(codec, 0x02, 0,
11384 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11385 snd_hda_codec_write(codec, 0x03, 0,
11386 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11389 /* pcm configuration: identiacal with ALC880 */
11390 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11391 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11392 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11393 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11396 * BIOS auto configuration
11398 static int alc268_parse_auto_config(struct hda_codec *codec)
11400 struct alc_spec *spec = codec->spec;
11402 static hda_nid_t alc268_ignore[] = { 0 };
11404 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11408 if (!spec->autocfg.line_outs)
11409 return 0; /* can't find valid BIOS pin config */
11411 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11414 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11418 spec->multiout.max_channels = 2;
11420 /* digital only support output */
11421 if (spec->autocfg.dig_out_pin)
11422 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11424 if (spec->kctls.list)
11425 spec->mixers[spec->num_mixers++] = spec->kctls.list;
11427 if (spec->autocfg.speaker_pins[0] != 0x1d)
11428 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11430 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11431 spec->num_mux_defs = 1;
11432 spec->input_mux = &spec->private_imux;
11434 err = alc_auto_add_mic_boost(codec);
11441 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11442 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11443 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11445 /* init callback for auto-configuration model -- overriding the default init */
11446 static void alc268_auto_init(struct hda_codec *codec)
11448 struct alc_spec *spec = codec->spec;
11449 alc268_auto_init_multi_out(codec);
11450 alc268_auto_init_hp_out(codec);
11451 alc268_auto_init_mono_speaker_out(codec);
11452 alc268_auto_init_analog_input(codec);
11453 if (spec->unsol_event)
11454 alc_inithook(codec);
11458 * configuration and preset
11460 static const char *alc268_models[ALC268_MODEL_LAST] = {
11461 [ALC267_QUANTA_IL1] = "quanta-il1",
11462 [ALC268_3ST] = "3stack",
11463 [ALC268_TOSHIBA] = "toshiba",
11464 [ALC268_ACER] = "acer",
11465 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11466 [ALC268_DELL] = "dell",
11467 [ALC268_ZEPTO] = "zepto",
11468 #ifdef CONFIG_SND_DEBUG
11469 [ALC268_TEST] = "test",
11471 [ALC268_AUTO] = "auto",
11474 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11475 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11476 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11477 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11478 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11479 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11480 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11481 ALC268_ACER_ASPIRE_ONE),
11482 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11483 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11484 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11485 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11486 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11487 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11488 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11489 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11490 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11491 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11495 static struct alc_config_preset alc268_presets[] = {
11496 [ALC267_QUANTA_IL1] = {
11497 .mixers = { alc267_quanta_il1_mixer },
11498 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11499 alc267_quanta_il1_verbs },
11500 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11501 .dac_nids = alc268_dac_nids,
11502 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11503 .adc_nids = alc268_adc_nids_alt,
11505 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11506 .channel_mode = alc268_modes,
11507 .input_mux = &alc268_capture_source,
11508 .unsol_event = alc267_quanta_il1_unsol_event,
11509 .init_hook = alc267_quanta_il1_automute,
11512 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11513 alc268_beep_mixer },
11514 .init_verbs = { alc268_base_init_verbs },
11515 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11516 .dac_nids = alc268_dac_nids,
11517 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11518 .adc_nids = alc268_adc_nids_alt,
11519 .capsrc_nids = alc268_capsrc_nids,
11521 .dig_out_nid = ALC268_DIGOUT_NID,
11522 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11523 .channel_mode = alc268_modes,
11524 .input_mux = &alc268_capture_source,
11526 [ALC268_TOSHIBA] = {
11527 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11528 alc268_beep_mixer },
11529 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11530 alc268_toshiba_verbs },
11531 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11532 .dac_nids = alc268_dac_nids,
11533 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11534 .adc_nids = alc268_adc_nids_alt,
11535 .capsrc_nids = alc268_capsrc_nids,
11537 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11538 .channel_mode = alc268_modes,
11539 .input_mux = &alc268_capture_source,
11540 .unsol_event = alc268_toshiba_unsol_event,
11541 .init_hook = alc268_toshiba_automute,
11544 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11545 alc268_beep_mixer },
11546 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11547 alc268_acer_verbs },
11548 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11549 .dac_nids = alc268_dac_nids,
11550 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11551 .adc_nids = alc268_adc_nids_alt,
11552 .capsrc_nids = alc268_capsrc_nids,
11554 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11555 .channel_mode = alc268_modes,
11556 .input_mux = &alc268_acer_capture_source,
11557 .unsol_event = alc268_acer_unsol_event,
11558 .init_hook = alc268_acer_init_hook,
11560 [ALC268_ACER_ASPIRE_ONE] = {
11561 .mixers = { alc268_acer_aspire_one_mixer,
11562 alc268_capture_alt_mixer },
11563 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11564 alc268_acer_aspire_one_verbs },
11565 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11566 .dac_nids = alc268_dac_nids,
11567 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11568 .adc_nids = alc268_adc_nids_alt,
11569 .capsrc_nids = alc268_capsrc_nids,
11571 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11572 .channel_mode = alc268_modes,
11573 .input_mux = &alc268_acer_lc_capture_source,
11574 .unsol_event = alc268_acer_lc_unsol_event,
11575 .init_hook = alc268_acer_lc_init_hook,
11578 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11579 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11580 alc268_dell_verbs },
11581 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11582 .dac_nids = alc268_dac_nids,
11584 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11585 .channel_mode = alc268_modes,
11586 .unsol_event = alc268_dell_unsol_event,
11587 .init_hook = alc268_dell_init_hook,
11588 .input_mux = &alc268_capture_source,
11591 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11592 alc268_beep_mixer },
11593 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11594 alc268_toshiba_verbs },
11595 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11596 .dac_nids = alc268_dac_nids,
11597 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11598 .adc_nids = alc268_adc_nids_alt,
11599 .capsrc_nids = alc268_capsrc_nids,
11601 .dig_out_nid = ALC268_DIGOUT_NID,
11602 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11603 .channel_mode = alc268_modes,
11604 .input_mux = &alc268_capture_source,
11605 .unsol_event = alc268_toshiba_unsol_event,
11606 .init_hook = alc268_toshiba_automute
11608 #ifdef CONFIG_SND_DEBUG
11610 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11611 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11612 alc268_volume_init_verbs },
11613 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11614 .dac_nids = alc268_dac_nids,
11615 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11616 .adc_nids = alc268_adc_nids_alt,
11617 .capsrc_nids = alc268_capsrc_nids,
11619 .dig_out_nid = ALC268_DIGOUT_NID,
11620 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11621 .channel_mode = alc268_modes,
11622 .input_mux = &alc268_capture_source,
11627 static int patch_alc268(struct hda_codec *codec)
11629 struct alc_spec *spec;
11633 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11637 codec->spec = spec;
11639 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11643 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11644 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11645 "trying auto-probe from BIOS...\n");
11646 board_config = ALC268_AUTO;
11649 if (board_config == ALC268_AUTO) {
11650 /* automatic parse from the BIOS config */
11651 err = alc268_parse_auto_config(codec);
11657 "hda_codec: Cannot set up configuration "
11658 "from BIOS. Using base mode...\n");
11659 board_config = ALC268_3ST;
11663 if (board_config != ALC268_AUTO)
11664 setup_preset(spec, &alc268_presets[board_config]);
11666 if (codec->vendor_id == 0x10ec0267) {
11667 spec->stream_name_analog = "ALC267 Analog";
11668 spec->stream_name_digital = "ALC267 Digital";
11670 spec->stream_name_analog = "ALC268 Analog";
11671 spec->stream_name_digital = "ALC268 Digital";
11674 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11675 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11676 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11678 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11680 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11681 /* override the amp caps for beep generator */
11682 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11683 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11684 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11685 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11686 (0 << AC_AMPCAP_MUTE_SHIFT));
11688 if (!spec->adc_nids && spec->input_mux) {
11689 /* check whether NID 0x07 is valid */
11690 unsigned int wcap = get_wcaps(codec, 0x07);
11694 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11695 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11696 spec->adc_nids = alc268_adc_nids_alt;
11697 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11698 spec->mixers[spec->num_mixers] =
11699 alc268_capture_alt_mixer;
11700 spec->num_mixers++;
11702 spec->adc_nids = alc268_adc_nids;
11703 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11704 spec->mixers[spec->num_mixers] =
11705 alc268_capture_mixer;
11706 spec->num_mixers++;
11708 spec->capsrc_nids = alc268_capsrc_nids;
11709 /* set default input source */
11710 for (i = 0; i < spec->num_adc_nids; i++)
11711 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11712 0, AC_VERB_SET_CONNECT_SEL,
11713 spec->input_mux->items[0].index);
11716 spec->vmaster_nid = 0x02;
11718 codec->patch_ops = alc_patch_ops;
11719 if (board_config == ALC268_AUTO)
11720 spec->init_hook = alc268_auto_init;
11726 * ALC269 channel source setting (2 channel)
11728 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11730 #define alc269_dac_nids alc260_dac_nids
11732 static hda_nid_t alc269_adc_nids[1] = {
11737 static hda_nid_t alc269_capsrc_nids[1] = {
11741 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11745 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11753 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11761 #define alc269_modes alc260_modes
11762 #define alc269_capture_source alc880_lg_lw_capture_source
11764 static struct snd_kcontrol_new alc269_base_mixer[] = {
11765 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11766 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11771 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11772 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11773 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11774 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11775 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11776 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11777 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11778 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11782 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11783 /* output mixer control */
11784 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11787 .name = "Master Playback Switch",
11788 .info = snd_hda_mixer_amp_switch_info,
11789 .get = snd_hda_mixer_amp_switch_get,
11790 .put = alc268_acer_master_sw_put,
11791 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11796 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11797 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11798 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11799 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11800 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11804 /* bind volumes of both NID 0x0c and 0x0d */
11805 static struct hda_bind_ctls alc269_epc_bind_vol = {
11806 .ops = &snd_hda_bind_vol,
11808 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11809 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11814 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11815 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11816 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11817 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11821 /* capture mixer elements */
11822 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11823 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11824 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11827 /* The multiple "Capture Source" controls confuse alsamixer
11828 * So call somewhat different..
11830 /* .name = "Capture Source", */
11831 .name = "Input Source",
11833 .info = alc_mux_enum_info,
11834 .get = alc_mux_enum_get,
11835 .put = alc_mux_enum_put,
11840 /* capture mixer elements */
11841 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11842 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11843 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11848 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11849 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11850 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11854 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11855 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11856 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11858 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11860 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11864 /* toggle speaker-output according to the hp-jack state */
11865 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11867 unsigned int present;
11868 unsigned char bits;
11870 present = snd_hda_codec_read(codec, 0x15, 0,
11871 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11872 bits = present ? AMP_IN_MUTE(0) : 0;
11873 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11874 AMP_IN_MUTE(0), bits);
11875 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11876 AMP_IN_MUTE(0), bits);
11878 snd_hda_codec_write(codec, 0x20, 0,
11879 AC_VERB_SET_COEF_INDEX, 0x0c);
11880 snd_hda_codec_write(codec, 0x20, 0,
11881 AC_VERB_SET_PROC_COEF, 0x680);
11883 snd_hda_codec_write(codec, 0x20, 0,
11884 AC_VERB_SET_COEF_INDEX, 0x0c);
11885 snd_hda_codec_write(codec, 0x20, 0,
11886 AC_VERB_SET_PROC_COEF, 0x480);
11889 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11891 unsigned int present;
11893 present = snd_hda_codec_read(codec, 0x18, 0,
11894 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11895 snd_hda_codec_write(codec, 0x23, 0,
11896 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11899 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11902 if ((res >> 26) == ALC880_HP_EVENT)
11903 alc269_quanta_fl1_speaker_automute(codec);
11904 if ((res >> 26) == ALC880_MIC_EVENT)
11905 alc269_quanta_fl1_mic_automute(codec);
11908 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11910 alc269_quanta_fl1_speaker_automute(codec);
11911 alc269_quanta_fl1_mic_automute(codec);
11914 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11915 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11916 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11917 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11918 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11919 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11920 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11925 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11926 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11927 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11928 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11929 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11930 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11931 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11935 /* toggle speaker-output according to the hp-jack state */
11936 static void alc269_speaker_automute(struct hda_codec *codec)
11938 unsigned int present;
11939 unsigned char bits;
11941 present = snd_hda_codec_read(codec, 0x15, 0,
11942 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11943 bits = present ? AMP_IN_MUTE(0) : 0;
11944 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11945 AMP_IN_MUTE(0), bits);
11946 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11947 AMP_IN_MUTE(0), bits);
11950 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11952 unsigned int present;
11954 present = snd_hda_codec_read(codec, 0x18, 0,
11955 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11956 snd_hda_codec_write(codec, 0x23, 0,
11957 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11960 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11962 unsigned int present;
11964 present = snd_hda_codec_read(codec, 0x18, 0,
11965 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11966 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11967 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11968 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11969 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11972 /* unsolicited event for HP jack sensing */
11973 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11976 if ((res >> 26) == ALC880_HP_EVENT)
11977 alc269_speaker_automute(codec);
11979 if ((res >> 26) == ALC880_MIC_EVENT)
11980 alc269_eeepc_dmic_automute(codec);
11983 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11985 alc269_speaker_automute(codec);
11986 alc269_eeepc_dmic_automute(codec);
11989 /* unsolicited event for HP jack sensing */
11990 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11993 if ((res >> 26) == ALC880_HP_EVENT)
11994 alc269_speaker_automute(codec);
11996 if ((res >> 26) == ALC880_MIC_EVENT)
11997 alc269_eeepc_amic_automute(codec);
12000 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12002 alc269_speaker_automute(codec);
12003 alc269_eeepc_amic_automute(codec);
12007 * generic initialization of ADC, input mixers and output mixers
12009 static struct hda_verb alc269_init_verbs[] = {
12011 * Unmute ADC0 and set the default input to mic-in
12013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12015 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12016 * analog-loopback mixer widget
12017 * Note: PASD motherboards uses the Line In 2 as the input for
12018 * front panel mic (mic 2)
12020 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12028 * Set up output mixers (0x0c - 0x0e)
12030 /* set vol=0 to output mixers */
12031 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12032 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12034 /* set up input amps for analog loopback */
12035 /* Amp Indices: DAC = 0, mixer = 1 */
12036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12038 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12039 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12040 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12041 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12043 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12045 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12046 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12047 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12048 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12049 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12052 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12053 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12054 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12055 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12059 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12062 /* FIXME: use matrix-type input source selection */
12063 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12064 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12066 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12071 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12072 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12076 /* add playback controls from the parsed DAC table */
12077 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12078 const struct auto_pin_cfg *cfg)
12083 spec->multiout.num_dacs = 1; /* only use one dac */
12084 spec->multiout.dac_nids = spec->private_dac_nids;
12085 spec->multiout.dac_nids[0] = 2;
12087 nid = cfg->line_out_pins[0];
12089 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12090 "Front Playback Volume",
12091 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12094 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12095 "Front Playback Switch",
12096 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12101 nid = cfg->speaker_pins[0];
12103 if (!cfg->line_out_pins[0]) {
12104 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12105 "Speaker Playback Volume",
12106 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12112 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12113 "Speaker Playback Switch",
12114 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12119 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12120 "Speaker Playback Switch",
12121 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12127 nid = cfg->hp_pins[0];
12129 /* spec->multiout.hp_nid = 2; */
12130 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12131 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12132 "Headphone Playback Volume",
12133 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12139 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12140 "Headphone Playback Switch",
12141 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12146 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12147 "Headphone Playback Switch",
12148 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12157 #define alc269_auto_create_analog_input_ctls \
12158 alc880_auto_create_analog_input_ctls
12160 #ifdef CONFIG_SND_HDA_POWER_SAVE
12161 #define alc269_loopbacks alc880_loopbacks
12164 /* pcm configuration: identiacal with ALC880 */
12165 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12166 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12167 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12168 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12171 * BIOS auto configuration
12173 static int alc269_parse_auto_config(struct hda_codec *codec)
12175 struct alc_spec *spec = codec->spec;
12177 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12179 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12184 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12187 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12191 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12193 if (spec->autocfg.dig_out_pin)
12194 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12196 if (spec->kctls.list)
12197 spec->mixers[spec->num_mixers++] = spec->kctls.list;
12199 /* create a beep mixer control if the pin 0x1d isn't assigned */
12200 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12201 if (spec->autocfg.input_pins[i] == 0x1d)
12203 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12204 spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12206 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12207 spec->num_mux_defs = 1;
12208 spec->input_mux = &spec->private_imux;
12209 /* set default input source */
12210 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12211 0, AC_VERB_SET_CONNECT_SEL,
12212 spec->input_mux->items[0].index);
12214 err = alc_auto_add_mic_boost(codec);
12218 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12219 spec->num_mixers++;
12224 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12225 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12226 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12229 /* init callback for auto-configuration model -- overriding the default init */
12230 static void alc269_auto_init(struct hda_codec *codec)
12232 struct alc_spec *spec = codec->spec;
12233 alc269_auto_init_multi_out(codec);
12234 alc269_auto_init_hp_out(codec);
12235 alc269_auto_init_analog_input(codec);
12236 if (spec->unsol_event)
12237 alc_inithook(codec);
12241 * configuration and preset
12243 static const char *alc269_models[ALC269_MODEL_LAST] = {
12244 [ALC269_BASIC] = "basic",
12245 [ALC269_QUANTA_FL1] = "quanta",
12246 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12247 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
12250 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12251 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12252 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12253 ALC269_ASUS_EEEPC_P703),
12254 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12255 ALC269_ASUS_EEEPC_P901),
12256 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12257 ALC269_ASUS_EEEPC_P901),
12261 static struct alc_config_preset alc269_presets[] = {
12263 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12264 .init_verbs = { alc269_init_verbs },
12265 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12266 .dac_nids = alc269_dac_nids,
12268 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12269 .channel_mode = alc269_modes,
12270 .input_mux = &alc269_capture_source,
12272 [ALC269_QUANTA_FL1] = {
12273 .mixers = { alc269_quanta_fl1_mixer },
12274 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12275 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12276 .dac_nids = alc269_dac_nids,
12278 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12279 .channel_mode = alc269_modes,
12280 .input_mux = &alc269_capture_source,
12281 .unsol_event = alc269_quanta_fl1_unsol_event,
12282 .init_hook = alc269_quanta_fl1_init_hook,
12284 [ALC269_ASUS_EEEPC_P703] = {
12285 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12286 .init_verbs = { alc269_init_verbs,
12287 alc269_eeepc_amic_init_verbs },
12288 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12289 .dac_nids = alc269_dac_nids,
12291 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12292 .channel_mode = alc269_modes,
12293 .input_mux = &alc269_eeepc_amic_capture_source,
12294 .unsol_event = alc269_eeepc_amic_unsol_event,
12295 .init_hook = alc269_eeepc_amic_inithook,
12297 [ALC269_ASUS_EEEPC_P901] = {
12298 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12299 .init_verbs = { alc269_init_verbs,
12300 alc269_eeepc_dmic_init_verbs },
12301 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12302 .dac_nids = alc269_dac_nids,
12304 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12305 .channel_mode = alc269_modes,
12306 .input_mux = &alc269_eeepc_dmic_capture_source,
12307 .unsol_event = alc269_eeepc_dmic_unsol_event,
12308 .init_hook = alc269_eeepc_dmic_inithook,
12312 static int patch_alc269(struct hda_codec *codec)
12314 struct alc_spec *spec;
12318 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12322 codec->spec = spec;
12324 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12326 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12330 if (board_config < 0) {
12331 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12332 "trying auto-probe from BIOS...\n");
12333 board_config = ALC269_AUTO;
12336 if (board_config == ALC269_AUTO) {
12337 /* automatic parse from the BIOS config */
12338 err = alc269_parse_auto_config(codec);
12344 "hda_codec: Cannot set up configuration "
12345 "from BIOS. Using base mode...\n");
12346 board_config = ALC269_BASIC;
12350 if (board_config != ALC269_AUTO)
12351 setup_preset(spec, &alc269_presets[board_config]);
12353 spec->stream_name_analog = "ALC269 Analog";
12354 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12355 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12357 spec->stream_name_digital = "ALC269 Digital";
12358 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12359 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12361 spec->adc_nids = alc269_adc_nids;
12362 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12363 spec->capsrc_nids = alc269_capsrc_nids;
12365 codec->patch_ops = alc_patch_ops;
12366 if (board_config == ALC269_AUTO)
12367 spec->init_hook = alc269_auto_init;
12368 #ifdef CONFIG_SND_HDA_POWER_SAVE
12369 if (!spec->loopback.amplist)
12370 spec->loopback.amplist = alc269_loopbacks;
12377 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12381 * set the path ways for 2 channel output
12382 * need to set the codec line out and mic 1 pin widgets to inputs
12384 static struct hda_verb alc861_threestack_ch2_init[] = {
12385 /* set pin widget 1Ah (line in) for input */
12386 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12387 /* set pin widget 18h (mic1/2) for input, for mic also enable
12390 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12392 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12394 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12395 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12401 * need to set the codec line out and mic 1 pin widgets to outputs
12403 static struct hda_verb alc861_threestack_ch6_init[] = {
12404 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12405 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12406 /* set pin widget 18h (mic1) for output (CLFE)*/
12407 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12409 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12410 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12412 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12414 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12415 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12420 static struct hda_channel_mode alc861_threestack_modes[2] = {
12421 { 2, alc861_threestack_ch2_init },
12422 { 6, alc861_threestack_ch6_init },
12424 /* Set mic1 as input and unmute the mixer */
12425 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12426 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12427 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12430 /* Set mic1 as output and mute mixer */
12431 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12432 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12433 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12437 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12438 { 2, alc861_uniwill_m31_ch2_init },
12439 { 4, alc861_uniwill_m31_ch4_init },
12442 /* Set mic1 and line-in as input and unmute the mixer */
12443 static struct hda_verb alc861_asus_ch2_init[] = {
12444 /* set pin widget 1Ah (line in) for input */
12445 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12446 /* set pin widget 18h (mic1/2) for input, for mic also enable
12449 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12451 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12453 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12454 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12458 /* Set mic1 nad line-in as output and mute mixer */
12459 static struct hda_verb alc861_asus_ch6_init[] = {
12460 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12461 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12462 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12463 /* set pin widget 18h (mic1) for output (CLFE)*/
12464 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12465 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12466 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12467 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12469 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12471 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12472 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12477 static struct hda_channel_mode alc861_asus_modes[2] = {
12478 { 2, alc861_asus_ch2_init },
12479 { 6, alc861_asus_ch6_init },
12484 static struct snd_kcontrol_new alc861_base_mixer[] = {
12485 /* output mixer control */
12486 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12487 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12488 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12489 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12490 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12492 /*Input mixer control */
12493 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12494 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12495 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12496 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12497 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12498 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12500 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12501 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12504 /* Capture mixer control */
12505 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12506 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12509 .name = "Capture Source",
12511 .info = alc_mux_enum_info,
12512 .get = alc_mux_enum_get,
12513 .put = alc_mux_enum_put,
12518 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12519 /* output mixer control */
12520 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12521 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12522 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12523 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12524 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12526 /* Input mixer control */
12527 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12528 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12529 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12530 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12531 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12532 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12534 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12535 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12538 /* Capture mixer control */
12539 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12540 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12543 .name = "Capture Source",
12545 .info = alc_mux_enum_info,
12546 .get = alc_mux_enum_get,
12547 .put = alc_mux_enum_put,
12550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12551 .name = "Channel Mode",
12552 .info = alc_ch_mode_info,
12553 .get = alc_ch_mode_get,
12554 .put = alc_ch_mode_put,
12555 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12560 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12561 /* output mixer control */
12562 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12564 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12566 /*Capture mixer control */
12567 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12568 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12570 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12571 .name = "Capture Source",
12573 .info = alc_mux_enum_info,
12574 .get = alc_mux_enum_get,
12575 .put = alc_mux_enum_put,
12581 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12582 /* output mixer control */
12583 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12584 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12585 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12586 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12587 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12589 /* Input mixer control */
12590 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12591 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12592 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12593 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12594 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12595 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12596 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12597 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12598 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12599 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12601 /* Capture mixer control */
12602 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12603 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12606 .name = "Capture Source",
12608 .info = alc_mux_enum_info,
12609 .get = alc_mux_enum_get,
12610 .put = alc_mux_enum_put,
12613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12614 .name = "Channel Mode",
12615 .info = alc_ch_mode_info,
12616 .get = alc_ch_mode_get,
12617 .put = alc_ch_mode_put,
12618 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12623 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12624 /* output mixer control */
12625 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12626 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12627 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12628 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12629 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12631 /* Input mixer control */
12632 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12633 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12634 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12635 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12636 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12637 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12639 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12640 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12643 /* Capture mixer control */
12644 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12645 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12648 .name = "Capture Source",
12650 .info = alc_mux_enum_info,
12651 .get = alc_mux_enum_get,
12652 .put = alc_mux_enum_put,
12655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12656 .name = "Channel Mode",
12657 .info = alc_ch_mode_info,
12658 .get = alc_ch_mode_get,
12659 .put = alc_ch_mode_put,
12660 .private_value = ARRAY_SIZE(alc861_asus_modes),
12665 /* additional mixer */
12666 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12667 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12668 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12669 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12670 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12675 * generic initialization of ADC, input mixers and output mixers
12677 static struct hda_verb alc861_base_init_verbs[] = {
12679 * Unmute ADC0 and set the default input to mic-in
12681 /* port-A for surround (rear panel) */
12682 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12683 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12684 /* port-B for mic-in (rear panel) with vref */
12685 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12686 /* port-C for line-in (rear panel) */
12687 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12688 /* port-D for Front */
12689 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12690 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12691 /* port-E for HP out (front panel) */
12692 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12693 /* route front PCM to HP */
12694 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12695 /* port-F for mic-in (front panel) with vref */
12696 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12697 /* port-G for CLFE (rear panel) */
12698 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12699 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12700 /* port-H for side (rear panel) */
12701 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12702 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12704 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12705 /* route front mic to ADC1*/
12706 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12707 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12709 /* Unmute DAC0~3 & spdif out*/
12710 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12711 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12712 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12713 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12716 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12717 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12718 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12719 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12720 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12722 /* Unmute Stereo Mixer 15 */
12723 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12728 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12729 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12730 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12731 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12732 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12733 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12734 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736 /* hp used DAC 3 (Front) */
12737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12738 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12743 static struct hda_verb alc861_threestack_init_verbs[] = {
12745 * Unmute ADC0 and set the default input to mic-in
12747 /* port-A for surround (rear panel) */
12748 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12749 /* port-B for mic-in (rear panel) with vref */
12750 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12751 /* port-C for line-in (rear panel) */
12752 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12753 /* port-D for Front */
12754 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12755 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12756 /* port-E for HP out (front panel) */
12757 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12758 /* route front PCM to HP */
12759 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12760 /* port-F for mic-in (front panel) with vref */
12761 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12762 /* port-G for CLFE (rear panel) */
12763 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12764 /* port-H for side (rear panel) */
12765 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12767 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12768 /* route front mic to ADC1*/
12769 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12770 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12771 /* Unmute DAC0~3 & spdif out*/
12772 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12773 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12774 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12775 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12778 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12779 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12780 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12781 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12782 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12784 /* Unmute Stereo Mixer 15 */
12785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12787 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12788 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12790 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12791 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12792 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12793 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12794 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12796 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12798 /* hp used DAC 3 (Front) */
12799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12800 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12804 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12806 * Unmute ADC0 and set the default input to mic-in
12808 /* port-A for surround (rear panel) */
12809 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12810 /* port-B for mic-in (rear panel) with vref */
12811 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12812 /* port-C for line-in (rear panel) */
12813 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12814 /* port-D for Front */
12815 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12816 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12817 /* port-E for HP out (front panel) */
12818 /* this has to be set to VREF80 */
12819 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12820 /* route front PCM to HP */
12821 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12822 /* port-F for mic-in (front panel) with vref */
12823 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12824 /* port-G for CLFE (rear panel) */
12825 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12826 /* port-H for side (rear panel) */
12827 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12829 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12830 /* route front mic to ADC1*/
12831 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12833 /* Unmute DAC0~3 & spdif out*/
12834 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12835 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12836 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12837 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12840 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12841 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12842 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12843 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12844 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12846 /* Unmute Stereo Mixer 15 */
12847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12849 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12850 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12853 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12854 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12857 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12860 /* hp used DAC 3 (Front) */
12861 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12866 static struct hda_verb alc861_asus_init_verbs[] = {
12868 * Unmute ADC0 and set the default input to mic-in
12870 /* port-A for surround (rear panel)
12871 * according to codec#0 this is the HP jack
12873 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12874 /* route front PCM to HP */
12875 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12876 /* port-B for mic-in (rear panel) with vref */
12877 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12878 /* port-C for line-in (rear panel) */
12879 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12880 /* port-D for Front */
12881 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12882 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12883 /* port-E for HP out (front panel) */
12884 /* this has to be set to VREF80 */
12885 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12886 /* route front PCM to HP */
12887 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12888 /* port-F for mic-in (front panel) with vref */
12889 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12890 /* port-G for CLFE (rear panel) */
12891 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12892 /* port-H for side (rear panel) */
12893 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12895 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12896 /* route front mic to ADC1*/
12897 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12898 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12899 /* Unmute DAC0~3 & spdif out*/
12900 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12901 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12902 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12903 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12904 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12905 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12906 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12907 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12908 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12909 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12911 /* Unmute Stereo Mixer 15 */
12912 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12914 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12915 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12917 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12919 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12920 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12921 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12922 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12923 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12924 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12925 /* hp used DAC 3 (Front) */
12926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12927 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12931 /* additional init verbs for ASUS laptops */
12932 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12933 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12934 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12939 * generic initialization of ADC, input mixers and output mixers
12941 static struct hda_verb alc861_auto_init_verbs[] = {
12943 * Unmute ADC0 and set the default input to mic-in
12945 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12946 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12948 /* Unmute DAC0~3 & spdif out*/
12949 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12950 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12951 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12952 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12955 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12956 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12957 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12958 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12959 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12961 /* Unmute Stereo Mixer 15 */
12962 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12963 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12967 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12968 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12969 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12970 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12971 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12972 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12973 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12974 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12976 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12979 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12980 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12981 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12983 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12985 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12990 static struct hda_verb alc861_toshiba_init_verbs[] = {
12991 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12996 /* toggle speaker-output according to the hp-jack state */
12997 static void alc861_toshiba_automute(struct hda_codec *codec)
12999 unsigned int present;
13001 present = snd_hda_codec_read(codec, 0x0f, 0,
13002 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13003 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13004 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13005 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13006 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13009 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13012 if ((res >> 26) == ALC880_HP_EVENT)
13013 alc861_toshiba_automute(codec);
13016 /* pcm configuration: identiacal with ALC880 */
13017 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13018 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13019 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13020 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13023 #define ALC861_DIGOUT_NID 0x07
13025 static struct hda_channel_mode alc861_8ch_modes[1] = {
13029 static hda_nid_t alc861_dac_nids[4] = {
13030 /* front, surround, clfe, side */
13031 0x03, 0x06, 0x05, 0x04
13034 static hda_nid_t alc660_dac_nids[3] = {
13035 /* front, clfe, surround */
13039 static hda_nid_t alc861_adc_nids[1] = {
13044 static struct hda_input_mux alc861_capture_source = {
13048 { "Front Mic", 0x3 },
13055 /* fill in the dac_nids table from the parsed pin configuration */
13056 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13057 const struct auto_pin_cfg *cfg)
13062 spec->multiout.dac_nids = spec->private_dac_nids;
13063 for (i = 0; i < cfg->line_outs; i++) {
13064 nid = cfg->line_out_pins[i];
13066 if (i >= ARRAY_SIZE(alc861_dac_nids))
13068 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13071 spec->multiout.num_dacs = cfg->line_outs;
13075 /* add playback controls from the parsed DAC table */
13076 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13077 const struct auto_pin_cfg *cfg)
13080 static const char *chname[4] = {
13081 "Front", "Surround", NULL /*CLFE*/, "Side"
13086 for (i = 0; i < cfg->line_outs; i++) {
13087 nid = spec->multiout.dac_nids[i];
13092 err = add_control(spec, ALC_CTL_BIND_MUTE,
13093 "Center Playback Switch",
13094 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13098 err = add_control(spec, ALC_CTL_BIND_MUTE,
13099 "LFE Playback Switch",
13100 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13105 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13107 if (nid == alc861_dac_nids[idx])
13109 sprintf(name, "%s Playback Switch", chname[idx]);
13110 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13111 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13120 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13128 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13130 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13131 "Headphone Playback Switch",
13132 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13135 spec->multiout.hp_nid = nid;
13140 /* create playback/capture controls for input pins */
13141 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13142 const struct auto_pin_cfg *cfg)
13144 struct hda_input_mux *imux = &spec->private_imux;
13145 int i, err, idx, idx1;
13147 for (i = 0; i < AUTO_PIN_LAST; i++) {
13148 switch (cfg->input_pins[i]) {
13151 idx = 2; /* Line In */
13155 idx = 2; /* Line In */
13159 idx = 1; /* Mic In */
13163 idx = 1; /* Mic In */
13173 err = new_analog_input(spec, cfg->input_pins[i],
13174 auto_pin_cfg_labels[i], idx, 0x15);
13178 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13179 imux->items[imux->num_items].index = idx1;
13185 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13186 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13187 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13190 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13191 /* The multiple "Capture Source" controls confuse alsamixer
13192 * So call somewhat different..
13194 /* .name = "Capture Source", */
13195 .name = "Input Source",
13197 .info = alc_mux_enum_info,
13198 .get = alc_mux_enum_get,
13199 .put = alc_mux_enum_put,
13204 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13206 int pin_type, int dac_idx)
13208 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13210 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13214 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13216 struct alc_spec *spec = codec->spec;
13219 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13220 for (i = 0; i < spec->autocfg.line_outs; i++) {
13221 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13222 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13224 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13225 spec->multiout.dac_nids[i]);
13229 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13231 struct alc_spec *spec = codec->spec;
13234 pin = spec->autocfg.hp_pins[0];
13235 if (pin) /* connect to front */
13236 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13237 spec->multiout.dac_nids[0]);
13238 pin = spec->autocfg.speaker_pins[0];
13240 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13243 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13245 struct alc_spec *spec = codec->spec;
13248 for (i = 0; i < AUTO_PIN_LAST; i++) {
13249 hda_nid_t nid = spec->autocfg.input_pins[i];
13250 if (nid >= 0x0c && nid <= 0x11) {
13251 snd_hda_codec_write(codec, nid, 0,
13252 AC_VERB_SET_PIN_WIDGET_CONTROL,
13253 i <= AUTO_PIN_FRONT_MIC ?
13254 PIN_VREF80 : PIN_IN);
13259 /* parse the BIOS configuration and set up the alc_spec */
13260 /* return 1 if successful, 0 if the proper config is not found,
13261 * or a negative error code
13263 static int alc861_parse_auto_config(struct hda_codec *codec)
13265 struct alc_spec *spec = codec->spec;
13267 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13269 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13273 if (!spec->autocfg.line_outs)
13274 return 0; /* can't find valid BIOS pin config */
13276 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13279 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13282 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13285 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13289 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13291 if (spec->autocfg.dig_out_pin)
13292 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13294 if (spec->kctls.list)
13295 spec->mixers[spec->num_mixers++] = spec->kctls.list;
13297 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13299 spec->num_mux_defs = 1;
13300 spec->input_mux = &spec->private_imux;
13302 spec->adc_nids = alc861_adc_nids;
13303 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13304 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13305 spec->num_mixers++;
13310 /* additional initialization for auto-configuration model */
13311 static void alc861_auto_init(struct hda_codec *codec)
13313 struct alc_spec *spec = codec->spec;
13314 alc861_auto_init_multi_out(codec);
13315 alc861_auto_init_hp_out(codec);
13316 alc861_auto_init_analog_input(codec);
13317 if (spec->unsol_event)
13318 alc_inithook(codec);
13321 #ifdef CONFIG_SND_HDA_POWER_SAVE
13322 static struct hda_amp_list alc861_loopbacks[] = {
13323 { 0x15, HDA_INPUT, 0 },
13324 { 0x15, HDA_INPUT, 1 },
13325 { 0x15, HDA_INPUT, 2 },
13326 { 0x15, HDA_INPUT, 3 },
13333 * configuration and preset
13335 static const char *alc861_models[ALC861_MODEL_LAST] = {
13336 [ALC861_3ST] = "3stack",
13337 [ALC660_3ST] = "3stack-660",
13338 [ALC861_3ST_DIG] = "3stack-dig",
13339 [ALC861_6ST_DIG] = "6stack-dig",
13340 [ALC861_UNIWILL_M31] = "uniwill-m31",
13341 [ALC861_TOSHIBA] = "toshiba",
13342 [ALC861_ASUS] = "asus",
13343 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13344 [ALC861_AUTO] = "auto",
13347 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13348 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13349 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13350 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13351 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13352 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13353 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13354 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13355 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13356 * Any other models that need this preset?
13358 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13359 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13360 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13361 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13362 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13363 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13364 /* FIXME: the below seems conflict */
13365 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13366 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13367 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13371 static struct alc_config_preset alc861_presets[] = {
13373 .mixers = { alc861_3ST_mixer },
13374 .init_verbs = { alc861_threestack_init_verbs },
13375 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13376 .dac_nids = alc861_dac_nids,
13377 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13378 .channel_mode = alc861_threestack_modes,
13380 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13381 .adc_nids = alc861_adc_nids,
13382 .input_mux = &alc861_capture_source,
13384 [ALC861_3ST_DIG] = {
13385 .mixers = { alc861_base_mixer },
13386 .init_verbs = { alc861_threestack_init_verbs },
13387 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13388 .dac_nids = alc861_dac_nids,
13389 .dig_out_nid = ALC861_DIGOUT_NID,
13390 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13391 .channel_mode = alc861_threestack_modes,
13393 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13394 .adc_nids = alc861_adc_nids,
13395 .input_mux = &alc861_capture_source,
13397 [ALC861_6ST_DIG] = {
13398 .mixers = { alc861_base_mixer },
13399 .init_verbs = { alc861_base_init_verbs },
13400 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13401 .dac_nids = alc861_dac_nids,
13402 .dig_out_nid = ALC861_DIGOUT_NID,
13403 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13404 .channel_mode = alc861_8ch_modes,
13405 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13406 .adc_nids = alc861_adc_nids,
13407 .input_mux = &alc861_capture_source,
13410 .mixers = { alc861_3ST_mixer },
13411 .init_verbs = { alc861_threestack_init_verbs },
13412 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13413 .dac_nids = alc660_dac_nids,
13414 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13415 .channel_mode = alc861_threestack_modes,
13417 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13418 .adc_nids = alc861_adc_nids,
13419 .input_mux = &alc861_capture_source,
13421 [ALC861_UNIWILL_M31] = {
13422 .mixers = { alc861_uniwill_m31_mixer },
13423 .init_verbs = { alc861_uniwill_m31_init_verbs },
13424 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13425 .dac_nids = alc861_dac_nids,
13426 .dig_out_nid = ALC861_DIGOUT_NID,
13427 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13428 .channel_mode = alc861_uniwill_m31_modes,
13430 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13431 .adc_nids = alc861_adc_nids,
13432 .input_mux = &alc861_capture_source,
13434 [ALC861_TOSHIBA] = {
13435 .mixers = { alc861_toshiba_mixer },
13436 .init_verbs = { alc861_base_init_verbs,
13437 alc861_toshiba_init_verbs },
13438 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13439 .dac_nids = alc861_dac_nids,
13440 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13441 .channel_mode = alc883_3ST_2ch_modes,
13442 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13443 .adc_nids = alc861_adc_nids,
13444 .input_mux = &alc861_capture_source,
13445 .unsol_event = alc861_toshiba_unsol_event,
13446 .init_hook = alc861_toshiba_automute,
13449 .mixers = { alc861_asus_mixer },
13450 .init_verbs = { alc861_asus_init_verbs },
13451 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13452 .dac_nids = alc861_dac_nids,
13453 .dig_out_nid = ALC861_DIGOUT_NID,
13454 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13455 .channel_mode = alc861_asus_modes,
13458 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13459 .adc_nids = alc861_adc_nids,
13460 .input_mux = &alc861_capture_source,
13462 [ALC861_ASUS_LAPTOP] = {
13463 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13464 .init_verbs = { alc861_asus_init_verbs,
13465 alc861_asus_laptop_init_verbs },
13466 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13467 .dac_nids = alc861_dac_nids,
13468 .dig_out_nid = ALC861_DIGOUT_NID,
13469 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13470 .channel_mode = alc883_3ST_2ch_modes,
13472 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13473 .adc_nids = alc861_adc_nids,
13474 .input_mux = &alc861_capture_source,
13479 static int patch_alc861(struct hda_codec *codec)
13481 struct alc_spec *spec;
13485 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13489 codec->spec = spec;
13491 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13495 if (board_config < 0) {
13496 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13497 "trying auto-probe from BIOS...\n");
13498 board_config = ALC861_AUTO;
13501 if (board_config == ALC861_AUTO) {
13502 /* automatic parse from the BIOS config */
13503 err = alc861_parse_auto_config(codec);
13509 "hda_codec: Cannot set up configuration "
13510 "from BIOS. Using base mode...\n");
13511 board_config = ALC861_3ST_DIG;
13515 if (board_config != ALC861_AUTO)
13516 setup_preset(spec, &alc861_presets[board_config]);
13518 spec->stream_name_analog = "ALC861 Analog";
13519 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13520 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13522 spec->stream_name_digital = "ALC861 Digital";
13523 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13524 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13526 spec->vmaster_nid = 0x03;
13528 codec->patch_ops = alc_patch_ops;
13529 if (board_config == ALC861_AUTO)
13530 spec->init_hook = alc861_auto_init;
13531 #ifdef CONFIG_SND_HDA_POWER_SAVE
13532 if (!spec->loopback.amplist)
13533 spec->loopback.amplist = alc861_loopbacks;
13540 * ALC861-VD support
13544 * In addition, an independent DAC
13546 #define ALC861VD_DIGOUT_NID 0x06
13548 static hda_nid_t alc861vd_dac_nids[4] = {
13549 /* front, surr, clfe, side surr */
13550 0x02, 0x03, 0x04, 0x05
13553 /* dac_nids for ALC660vd are in a different order - according to
13554 * Realtek's driver.
13555 * This should probably tesult in a different mixer for 6stack models
13556 * of ALC660vd codecs, but for now there is only 3stack mixer
13557 * - and it is the same as in 861vd.
13558 * adc_nids in ALC660vd are (is) the same as in 861vd
13560 static hda_nid_t alc660vd_dac_nids[3] = {
13561 /* front, rear, clfe, rear_surr */
13565 static hda_nid_t alc861vd_adc_nids[1] = {
13570 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13573 /* FIXME: should be a matrix-type input source selection */
13574 static struct hda_input_mux alc861vd_capture_source = {
13578 { "Front Mic", 0x1 },
13584 static struct hda_input_mux alc861vd_dallas_capture_source = {
13587 { "Ext Mic", 0x0 },
13588 { "Int Mic", 0x1 },
13592 static struct hda_input_mux alc861vd_hp_capture_source = {
13595 { "Front Mic", 0x0 },
13596 { "ATAPI Mic", 0x1 },
13600 #define alc861vd_mux_enum_info alc_mux_enum_info
13601 #define alc861vd_mux_enum_get alc_mux_enum_get
13602 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13603 #define alc861vd_mux_enum_put alc882_mux_enum_put
13608 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13615 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13616 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13617 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13618 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13619 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13626 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13627 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13628 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13629 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13630 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13634 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13635 { 6, alc861vd_6stack_ch6_init },
13636 { 8, alc861vd_6stack_ch8_init },
13639 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13641 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13642 .name = "Channel Mode",
13643 .info = alc_ch_mode_info,
13644 .get = alc_ch_mode_get,
13645 .put = alc_ch_mode_put,
13650 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13651 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13652 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13656 /* The multiple "Capture Source" controls confuse alsamixer
13657 * So call somewhat different..
13659 /* .name = "Capture Source", */
13660 .name = "Input Source",
13662 .info = alc861vd_mux_enum_info,
13663 .get = alc861vd_mux_enum_get,
13664 .put = alc861vd_mux_enum_put,
13669 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13670 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13672 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13673 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13674 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13676 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13677 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13679 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13681 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13683 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13684 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13686 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13687 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13695 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13696 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13699 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13700 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13705 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13706 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13711 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13712 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13713 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13715 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13717 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13718 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13719 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13721 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13722 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13723 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13728 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13729 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13731 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13732 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13737 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13738 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13739 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13740 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13744 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13748 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13749 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13750 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13752 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13753 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13758 /* Pin assignment: Speaker=0x14, HP = 0x15,
13759 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13761 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13762 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13763 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13764 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13765 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13766 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13767 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13768 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13770 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13771 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13772 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13773 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13777 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13778 * Front Mic=0x18, ATAPI Mic = 0x19,
13780 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13781 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13782 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13783 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13784 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13785 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13786 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13787 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13788 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13794 * generic initialization of ADC, input mixers and output mixers
13796 static struct hda_verb alc861vd_volume_init_verbs[] = {
13798 * Unmute ADC0 and set the default input to mic-in
13800 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13803 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13804 * the analog-loopback mixer widget
13806 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13807 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13808 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13809 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13810 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13813 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13820 * Set up output mixers (0x02 - 0x05)
13822 /* set vol=0 to output mixers */
13823 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13824 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13825 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13826 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13828 /* set up input amps for analog loopback */
13829 /* Amp Indices: DAC = 0, mixer = 1 */
13830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13832 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13833 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13834 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13835 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13836 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13837 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13843 * 3-stack pin configuration:
13844 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13846 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13848 * Set pin mode and muting
13850 /* set front pin widgets 0x14 for output */
13851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13853 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13855 /* Mic (rear) pin: input vref at 80% */
13856 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13857 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13858 /* Front Mic pin: input vref at 80% */
13859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13861 /* Line In pin: input */
13862 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13864 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13865 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13867 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13868 /* CD pin widget for input */
13869 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13875 * 6-stack pin configuration:
13877 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13879 * Set pin mode and muting
13881 /* set front pin widgets 0x14 for output */
13882 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13883 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13884 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13886 /* Rear Pin: output 1 (0x0d) */
13887 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13888 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13889 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13890 /* CLFE Pin: output 2 (0x0e) */
13891 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13892 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13893 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13894 /* Side Pin: output 3 (0x0f) */
13895 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13896 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13897 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13899 /* Mic (rear) pin: input vref at 80% */
13900 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13901 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13902 /* Front Mic pin: input vref at 80% */
13903 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13904 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13905 /* Line In pin: input */
13906 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13907 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13908 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13910 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13911 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13912 /* CD pin widget for input */
13913 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13918 static struct hda_verb alc861vd_eapd_verbs[] = {
13919 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13923 static struct hda_verb alc660vd_eapd_verbs[] = {
13924 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13925 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13929 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13933 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13934 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13938 /* toggle speaker-output according to the hp-jack state */
13939 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13941 unsigned int present;
13942 unsigned char bits;
13944 present = snd_hda_codec_read(codec, 0x1b, 0,
13945 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13946 bits = present ? HDA_AMP_MUTE : 0;
13947 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13948 HDA_AMP_MUTE, bits);
13951 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13953 unsigned int present;
13954 unsigned char bits;
13956 present = snd_hda_codec_read(codec, 0x18, 0,
13957 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13958 bits = present ? HDA_AMP_MUTE : 0;
13959 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13960 HDA_AMP_MUTE, bits);
13963 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13965 alc861vd_lenovo_hp_automute(codec);
13966 alc861vd_lenovo_mic_automute(codec);
13969 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13972 switch (res >> 26) {
13973 case ALC880_HP_EVENT:
13974 alc861vd_lenovo_hp_automute(codec);
13976 case ALC880_MIC_EVENT:
13977 alc861vd_lenovo_mic_automute(codec);
13982 static struct hda_verb alc861vd_dallas_verbs[] = {
13983 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13984 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13985 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13986 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13989 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13992 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13995 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13997 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13999 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14001 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14002 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14003 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14004 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14007 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14008 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14009 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14010 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14011 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14012 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14013 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14015 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14017 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14021 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14022 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14027 /* toggle speaker-output according to the hp-jack state */
14028 static void alc861vd_dallas_automute(struct hda_codec *codec)
14030 unsigned int present;
14032 present = snd_hda_codec_read(codec, 0x15, 0,
14033 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14034 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14035 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14038 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14040 if ((res >> 26) == ALC880_HP_EVENT)
14041 alc861vd_dallas_automute(codec);
14044 #ifdef CONFIG_SND_HDA_POWER_SAVE
14045 #define alc861vd_loopbacks alc880_loopbacks
14048 /* pcm configuration: identiacal with ALC880 */
14049 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14050 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14051 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14052 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14055 * configuration and preset
14057 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14058 [ALC660VD_3ST] = "3stack-660",
14059 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14060 [ALC861VD_3ST] = "3stack",
14061 [ALC861VD_3ST_DIG] = "3stack-digout",
14062 [ALC861VD_6ST_DIG] = "6stack-digout",
14063 [ALC861VD_LENOVO] = "lenovo",
14064 [ALC861VD_DALLAS] = "dallas",
14065 [ALC861VD_HP] = "hp",
14066 [ALC861VD_AUTO] = "auto",
14069 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14070 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14071 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14072 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14073 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14074 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14075 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14076 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14077 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14078 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14079 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14080 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14081 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14082 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14083 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14084 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14085 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14086 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14090 static struct alc_config_preset alc861vd_presets[] = {
14092 .mixers = { alc861vd_3st_mixer },
14093 .init_verbs = { alc861vd_volume_init_verbs,
14094 alc861vd_3stack_init_verbs },
14095 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14096 .dac_nids = alc660vd_dac_nids,
14097 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14098 .channel_mode = alc861vd_3stack_2ch_modes,
14099 .input_mux = &alc861vd_capture_source,
14101 [ALC660VD_3ST_DIG] = {
14102 .mixers = { alc861vd_3st_mixer },
14103 .init_verbs = { alc861vd_volume_init_verbs,
14104 alc861vd_3stack_init_verbs },
14105 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14106 .dac_nids = alc660vd_dac_nids,
14107 .dig_out_nid = ALC861VD_DIGOUT_NID,
14108 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14109 .channel_mode = alc861vd_3stack_2ch_modes,
14110 .input_mux = &alc861vd_capture_source,
14113 .mixers = { alc861vd_3st_mixer },
14114 .init_verbs = { alc861vd_volume_init_verbs,
14115 alc861vd_3stack_init_verbs },
14116 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14117 .dac_nids = alc861vd_dac_nids,
14118 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14119 .channel_mode = alc861vd_3stack_2ch_modes,
14120 .input_mux = &alc861vd_capture_source,
14122 [ALC861VD_3ST_DIG] = {
14123 .mixers = { alc861vd_3st_mixer },
14124 .init_verbs = { alc861vd_volume_init_verbs,
14125 alc861vd_3stack_init_verbs },
14126 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14127 .dac_nids = alc861vd_dac_nids,
14128 .dig_out_nid = ALC861VD_DIGOUT_NID,
14129 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14130 .channel_mode = alc861vd_3stack_2ch_modes,
14131 .input_mux = &alc861vd_capture_source,
14133 [ALC861VD_6ST_DIG] = {
14134 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14135 .init_verbs = { alc861vd_volume_init_verbs,
14136 alc861vd_6stack_init_verbs },
14137 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14138 .dac_nids = alc861vd_dac_nids,
14139 .dig_out_nid = ALC861VD_DIGOUT_NID,
14140 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14141 .channel_mode = alc861vd_6stack_modes,
14142 .input_mux = &alc861vd_capture_source,
14144 [ALC861VD_LENOVO] = {
14145 .mixers = { alc861vd_lenovo_mixer },
14146 .init_verbs = { alc861vd_volume_init_verbs,
14147 alc861vd_3stack_init_verbs,
14148 alc861vd_eapd_verbs,
14149 alc861vd_lenovo_unsol_verbs },
14150 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14151 .dac_nids = alc660vd_dac_nids,
14152 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14153 .channel_mode = alc861vd_3stack_2ch_modes,
14154 .input_mux = &alc861vd_capture_source,
14155 .unsol_event = alc861vd_lenovo_unsol_event,
14156 .init_hook = alc861vd_lenovo_automute,
14158 [ALC861VD_DALLAS] = {
14159 .mixers = { alc861vd_dallas_mixer },
14160 .init_verbs = { alc861vd_dallas_verbs },
14161 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14162 .dac_nids = alc861vd_dac_nids,
14163 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14164 .channel_mode = alc861vd_3stack_2ch_modes,
14165 .input_mux = &alc861vd_dallas_capture_source,
14166 .unsol_event = alc861vd_dallas_unsol_event,
14167 .init_hook = alc861vd_dallas_automute,
14170 .mixers = { alc861vd_hp_mixer },
14171 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14172 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14173 .dac_nids = alc861vd_dac_nids,
14174 .dig_out_nid = ALC861VD_DIGOUT_NID,
14175 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14176 .channel_mode = alc861vd_3stack_2ch_modes,
14177 .input_mux = &alc861vd_hp_capture_source,
14178 .unsol_event = alc861vd_dallas_unsol_event,
14179 .init_hook = alc861vd_dallas_automute,
14184 * BIOS auto configuration
14186 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14187 hda_nid_t nid, int pin_type, int dac_idx)
14189 alc_set_pin_output(codec, nid, pin_type);
14192 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14194 struct alc_spec *spec = codec->spec;
14197 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14198 for (i = 0; i <= HDA_SIDE; i++) {
14199 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14200 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14202 alc861vd_auto_set_output_and_unmute(codec, nid,
14208 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14210 struct alc_spec *spec = codec->spec;
14213 pin = spec->autocfg.hp_pins[0];
14214 if (pin) /* connect to front and use dac 0 */
14215 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14216 pin = spec->autocfg.speaker_pins[0];
14218 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14221 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14222 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14224 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14226 struct alc_spec *spec = codec->spec;
14229 for (i = 0; i < AUTO_PIN_LAST; i++) {
14230 hda_nid_t nid = spec->autocfg.input_pins[i];
14231 if (alc861vd_is_input_pin(nid)) {
14232 snd_hda_codec_write(codec, nid, 0,
14233 AC_VERB_SET_PIN_WIDGET_CONTROL,
14234 i <= AUTO_PIN_FRONT_MIC ?
14235 PIN_VREF80 : PIN_IN);
14236 if (nid != ALC861VD_PIN_CD_NID)
14237 snd_hda_codec_write(codec, nid, 0,
14238 AC_VERB_SET_AMP_GAIN_MUTE,
14244 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14246 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14247 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14249 /* add playback controls from the parsed DAC table */
14250 /* Based on ALC880 version. But ALC861VD has separate,
14251 * different NIDs for mute/unmute switch and volume control */
14252 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14253 const struct auto_pin_cfg *cfg)
14256 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14257 hda_nid_t nid_v, nid_s;
14260 for (i = 0; i < cfg->line_outs; i++) {
14261 if (!spec->multiout.dac_nids[i])
14263 nid_v = alc861vd_idx_to_mixer_vol(
14265 spec->multiout.dac_nids[i]));
14266 nid_s = alc861vd_idx_to_mixer_switch(
14268 spec->multiout.dac_nids[i]));
14272 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14273 "Center Playback Volume",
14274 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14278 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14279 "LFE Playback Volume",
14280 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14284 err = add_control(spec, ALC_CTL_BIND_MUTE,
14285 "Center Playback Switch",
14286 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14290 err = add_control(spec, ALC_CTL_BIND_MUTE,
14291 "LFE Playback Switch",
14292 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14297 sprintf(name, "%s Playback Volume", chname[i]);
14298 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14299 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14303 sprintf(name, "%s Playback Switch", chname[i]);
14304 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14305 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14314 /* add playback controls for speaker and HP outputs */
14315 /* Based on ALC880 version. But ALC861VD has separate,
14316 * different NIDs for mute/unmute switch and volume control */
14317 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14318 hda_nid_t pin, const char *pfx)
14320 hda_nid_t nid_v, nid_s;
14327 if (alc880_is_fixed_pin(pin)) {
14328 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14329 /* specify the DAC as the extra output */
14330 if (!spec->multiout.hp_nid)
14331 spec->multiout.hp_nid = nid_v;
14333 spec->multiout.extra_out_nid[0] = nid_v;
14334 /* control HP volume/switch on the output mixer amp */
14335 nid_v = alc861vd_idx_to_mixer_vol(
14336 alc880_fixed_pin_idx(pin));
14337 nid_s = alc861vd_idx_to_mixer_switch(
14338 alc880_fixed_pin_idx(pin));
14340 sprintf(name, "%s Playback Volume", pfx);
14341 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14342 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14345 sprintf(name, "%s Playback Switch", pfx);
14346 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14347 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14350 } else if (alc880_is_multi_pin(pin)) {
14351 /* set manual connection */
14352 /* we have only a switch on HP-out PIN */
14353 sprintf(name, "%s Playback Switch", pfx);
14354 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14355 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14362 /* parse the BIOS configuration and set up the alc_spec
14363 * return 1 if successful, 0 if the proper config is not found,
14364 * or a negative error code
14365 * Based on ALC880 version - had to change it to override
14366 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14367 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14369 struct alc_spec *spec = codec->spec;
14371 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14373 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14377 if (!spec->autocfg.line_outs)
14378 return 0; /* can't find valid BIOS pin config */
14380 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14383 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14386 err = alc861vd_auto_create_extra_out(spec,
14387 spec->autocfg.speaker_pins[0],
14391 err = alc861vd_auto_create_extra_out(spec,
14392 spec->autocfg.hp_pins[0],
14396 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14400 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14402 if (spec->autocfg.dig_out_pin)
14403 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14405 if (spec->kctls.list)
14406 spec->mixers[spec->num_mixers++] = spec->kctls.list;
14408 spec->init_verbs[spec->num_init_verbs++]
14409 = alc861vd_volume_init_verbs;
14411 spec->num_mux_defs = 1;
14412 spec->input_mux = &spec->private_imux;
14414 err = alc_auto_add_mic_boost(codec);
14421 /* additional initialization for auto-configuration model */
14422 static void alc861vd_auto_init(struct hda_codec *codec)
14424 struct alc_spec *spec = codec->spec;
14425 alc861vd_auto_init_multi_out(codec);
14426 alc861vd_auto_init_hp_out(codec);
14427 alc861vd_auto_init_analog_input(codec);
14428 alc861vd_auto_init_input_src(codec);
14429 if (spec->unsol_event)
14430 alc_inithook(codec);
14433 static int patch_alc861vd(struct hda_codec *codec)
14435 struct alc_spec *spec;
14436 int err, board_config;
14438 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14442 codec->spec = spec;
14444 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14448 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14449 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14450 "ALC861VD, trying auto-probe from BIOS...\n");
14451 board_config = ALC861VD_AUTO;
14454 if (board_config == ALC861VD_AUTO) {
14455 /* automatic parse from the BIOS config */
14456 err = alc861vd_parse_auto_config(codec);
14462 "hda_codec: Cannot set up configuration "
14463 "from BIOS. Using base mode...\n");
14464 board_config = ALC861VD_3ST;
14468 if (board_config != ALC861VD_AUTO)
14469 setup_preset(spec, &alc861vd_presets[board_config]);
14471 if (codec->vendor_id == 0x10ec0660) {
14472 spec->stream_name_analog = "ALC660-VD Analog";
14473 spec->stream_name_digital = "ALC660-VD Digital";
14474 /* always turn on EAPD */
14475 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14477 spec->stream_name_analog = "ALC861VD Analog";
14478 spec->stream_name_digital = "ALC861VD Digital";
14481 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14482 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14484 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14485 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14487 spec->adc_nids = alc861vd_adc_nids;
14488 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14489 spec->capsrc_nids = alc861vd_capsrc_nids;
14491 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14492 spec->num_mixers++;
14494 spec->vmaster_nid = 0x02;
14496 codec->patch_ops = alc_patch_ops;
14498 if (board_config == ALC861VD_AUTO)
14499 spec->init_hook = alc861vd_auto_init;
14500 #ifdef CONFIG_SND_HDA_POWER_SAVE
14501 if (!spec->loopback.amplist)
14502 spec->loopback.amplist = alc861vd_loopbacks;
14511 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14512 * configuration. Each pin widget can choose any input DACs and a mixer.
14513 * Each ADC is connected from a mixer of all inputs. This makes possible
14514 * 6-channel independent captures.
14516 * In addition, an independent DAC for the multi-playback (not used in this
14519 #define ALC662_DIGOUT_NID 0x06
14520 #define ALC662_DIGIN_NID 0x0a
14522 static hda_nid_t alc662_dac_nids[4] = {
14523 /* front, rear, clfe, rear_surr */
14527 static hda_nid_t alc662_adc_nids[1] = {
14532 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14535 /* FIXME: should be a matrix-type input source selection */
14536 static struct hda_input_mux alc662_capture_source = {
14540 { "Front Mic", 0x1 },
14546 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14554 static struct hda_input_mux alc662_eeepc_capture_source = {
14562 static struct hda_input_mux alc663_capture_source = {
14566 { "Front Mic", 0x1 },
14571 static struct hda_input_mux alc663_m51va_capture_source = {
14574 { "Ext-Mic", 0x0 },
14579 #define alc662_mux_enum_info alc_mux_enum_info
14580 #define alc662_mux_enum_get alc_mux_enum_get
14581 #define alc662_mux_enum_put alc882_mux_enum_put
14586 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14593 static struct hda_verb alc662_3ST_ch2_init[] = {
14594 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14595 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14596 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14597 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14604 static struct hda_verb alc662_3ST_ch6_init[] = {
14605 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14606 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14607 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14608 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14609 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14610 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14614 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14615 { 2, alc662_3ST_ch2_init },
14616 { 6, alc662_3ST_ch6_init },
14622 static struct hda_verb alc662_sixstack_ch6_init[] = {
14623 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14624 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14625 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14632 static struct hda_verb alc662_sixstack_ch8_init[] = {
14633 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14634 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14635 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14639 static struct hda_channel_mode alc662_5stack_modes[2] = {
14640 { 2, alc662_sixstack_ch6_init },
14641 { 6, alc662_sixstack_ch8_init },
14644 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14645 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14648 static struct snd_kcontrol_new alc662_base_mixer[] = {
14649 /* output mixer control */
14650 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14651 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14652 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14653 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14654 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14655 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14656 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14657 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14660 /*Input mixer control */
14661 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14662 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14663 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14664 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14665 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14666 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14667 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14668 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14672 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14673 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14674 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14676 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14677 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14682 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14683 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14684 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14685 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14689 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14690 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14691 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14692 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14693 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14694 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14695 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14696 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14697 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14698 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14699 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14700 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14701 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14702 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14705 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14706 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14707 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14708 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14712 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14713 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14714 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14715 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14716 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14717 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14718 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14719 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14725 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14726 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14728 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14729 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14731 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14732 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14733 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14735 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14736 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14737 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14741 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14742 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14743 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14744 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14745 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14746 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14747 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14748 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14749 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14750 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14751 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14752 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14753 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14755 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14759 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14760 .ops = &snd_hda_bind_vol,
14762 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14763 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14768 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14769 .ops = &snd_hda_bind_sw,
14771 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14772 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14777 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14778 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14779 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14785 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14786 .ops = &snd_hda_bind_sw,
14788 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14789 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14790 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14795 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14796 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14797 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14799 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14800 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14801 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14806 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14807 .ops = &snd_hda_bind_sw,
14809 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14810 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14811 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14816 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14817 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14818 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14821 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14822 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14826 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14827 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14828 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14831 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14832 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14833 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14837 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14838 .ops = &snd_hda_bind_vol,
14840 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14841 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14846 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14847 .ops = &snd_hda_bind_sw,
14849 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14850 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14855 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14856 HDA_BIND_VOL("Master Playback Volume",
14857 &alc663_asus_two_bind_master_vol),
14858 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14859 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14866 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14867 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14868 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14869 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14870 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14876 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14877 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14878 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14879 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14880 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14881 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14885 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14886 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14890 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14891 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14892 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14897 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14898 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14899 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14900 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14904 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14906 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14907 .name = "Channel Mode",
14908 .info = alc_ch_mode_info,
14909 .get = alc_ch_mode_get,
14910 .put = alc_ch_mode_put,
14915 static struct hda_verb alc662_init_verbs[] = {
14916 /* ADC: mute amp left and right */
14917 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14918 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14919 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14929 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14930 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14932 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14934 /* Front Pin: output 0 (0x0c) */
14935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14938 /* Rear Pin: output 1 (0x0d) */
14939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14942 /* CLFE Pin: output 2 (0x0e) */
14943 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14944 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14946 /* Mic (rear) pin: input vref at 80% */
14947 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14948 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14949 /* Front Mic pin: input vref at 80% */
14950 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14951 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14952 /* Line In pin: input */
14953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14954 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14955 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14956 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14957 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14958 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14959 /* CD pin widget for input */
14960 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14962 /* FIXME: use matrix-type input source selection */
14963 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14965 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14966 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14967 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14968 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14971 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14972 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14973 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14975 /* always trun on EAPD */
14976 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14977 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14982 static struct hda_verb alc662_sue_init_verbs[] = {
14983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14988 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14994 /* Set Unsolicited Event*/
14995 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14997 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15002 * generic initialization of ADC, input mixers and output mixers
15004 static struct hda_verb alc662_auto_init_verbs[] = {
15006 * Unmute ADC and set the default input to mic-in
15008 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15011 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15013 * Note: PASD motherboards uses the Line In 2 as the input for front
15014 * panel mic (mic 2)
15016 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15017 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15018 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15024 * Set up output mixers (0x0c - 0x0f)
15026 /* set vol=0 to output mixers */
15027 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15028 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15029 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15031 /* set up input amps for analog loopback */
15032 /* Amp Indices: DAC = 0, mixer = 1 */
15033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15034 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15035 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15036 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15037 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15038 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15041 /* FIXME: use matrix-type input source selection */
15042 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15049 /* additional verbs for ALC663 */
15050 static struct hda_verb alc663_auto_init_verbs[] = {
15051 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15052 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15056 static struct hda_verb alc663_m51va_init_verbs[] = {
15057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15059 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15060 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15061 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15064 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15065 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15069 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15070 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15071 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15072 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15075 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15076 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15080 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15081 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15082 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15083 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15084 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15087 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15088 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15092 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15094 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15096 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15098 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15099 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15103 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15104 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15105 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15106 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15107 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15108 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15113 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15114 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15115 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15119 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15120 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15121 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15122 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15123 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15124 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15126 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15129 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15130 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15135 static struct hda_verb alc663_g71v_init_verbs[] = {
15136 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15137 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15138 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15140 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15141 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15142 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15144 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15145 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15146 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15150 static struct hda_verb alc663_g50v_init_verbs[] = {
15151 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15152 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15153 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15155 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15156 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15160 static struct hda_verb alc662_ecs_init_verbs[] = {
15161 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15163 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15164 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15168 /* capture mixer elements */
15169 static struct snd_kcontrol_new alc662_capture_mixer[] = {
15170 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15171 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15174 /* The multiple "Capture Source" controls confuse alsamixer
15175 * So call somewhat different..
15177 /* .name = "Capture Source", */
15178 .name = "Input Source",
15180 .info = alc662_mux_enum_info,
15181 .get = alc662_mux_enum_get,
15182 .put = alc662_mux_enum_put,
15187 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15188 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15189 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15193 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15195 unsigned int present;
15196 unsigned char bits;
15198 present = snd_hda_codec_read(codec, 0x14, 0,
15199 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15200 bits = present ? HDA_AMP_MUTE : 0;
15201 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15202 HDA_AMP_MUTE, bits);
15205 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15207 unsigned int present;
15208 unsigned char bits;
15210 present = snd_hda_codec_read(codec, 0x1b, 0,
15211 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15212 bits = present ? HDA_AMP_MUTE : 0;
15213 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15214 HDA_AMP_MUTE, bits);
15215 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15216 HDA_AMP_MUTE, bits);
15219 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15222 if ((res >> 26) == ALC880_HP_EVENT)
15223 alc662_lenovo_101e_all_automute(codec);
15224 if ((res >> 26) == ALC880_FRONT_EVENT)
15225 alc662_lenovo_101e_ispeaker_automute(codec);
15228 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15230 unsigned int present;
15232 present = snd_hda_codec_read(codec, 0x18, 0,
15233 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15234 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15235 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15236 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15237 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15238 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15239 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15240 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15241 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15244 /* unsolicited event for HP jack sensing */
15245 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15248 if ((res >> 26) == ALC880_HP_EVENT)
15249 alc262_hippo1_automute( codec );
15251 if ((res >> 26) == ALC880_MIC_EVENT)
15252 alc662_eeepc_mic_automute(codec);
15255 static void alc662_eeepc_inithook(struct hda_codec *codec)
15257 alc262_hippo1_automute( codec );
15258 alc662_eeepc_mic_automute(codec);
15261 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15264 unsigned int present;
15266 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15267 present = snd_hda_codec_read(codec, 0x14, 0,
15268 AC_VERB_GET_PIN_SENSE, 0);
15269 present = (present & 0x80000000) != 0;
15271 /* mute internal speaker */
15272 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15273 HDA_AMP_MUTE, HDA_AMP_MUTE);
15275 /* unmute internal speaker if necessary */
15276 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15277 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15278 HDA_AMP_MUTE, mute);
15282 /* unsolicited event for HP jack sensing */
15283 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15286 if ((res >> 26) == ALC880_HP_EVENT)
15287 alc662_eeepc_ep20_automute(codec);
15290 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15292 alc662_eeepc_ep20_automute(codec);
15295 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15297 unsigned int present;
15298 unsigned char bits;
15300 present = snd_hda_codec_read(codec, 0x21, 0,
15301 AC_VERB_GET_PIN_SENSE, 0)
15302 & AC_PINSENSE_PRESENCE;
15303 bits = present ? HDA_AMP_MUTE : 0;
15304 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15305 AMP_IN_MUTE(0), bits);
15306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15307 AMP_IN_MUTE(0), bits);
15310 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15312 unsigned int present;
15313 unsigned char bits;
15315 present = snd_hda_codec_read(codec, 0x21, 0,
15316 AC_VERB_GET_PIN_SENSE, 0)
15317 & AC_PINSENSE_PRESENCE;
15318 bits = present ? HDA_AMP_MUTE : 0;
15319 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15320 AMP_IN_MUTE(0), bits);
15321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15322 AMP_IN_MUTE(0), bits);
15323 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15324 AMP_IN_MUTE(0), bits);
15325 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15326 AMP_IN_MUTE(0), bits);
15329 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15331 unsigned int present;
15332 unsigned char bits;
15334 present = snd_hda_codec_read(codec, 0x15, 0,
15335 AC_VERB_GET_PIN_SENSE, 0)
15336 & AC_PINSENSE_PRESENCE;
15337 bits = present ? HDA_AMP_MUTE : 0;
15338 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15339 AMP_IN_MUTE(0), bits);
15340 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15341 AMP_IN_MUTE(0), bits);
15342 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15343 AMP_IN_MUTE(0), bits);
15344 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15345 AMP_IN_MUTE(0), bits);
15348 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15350 unsigned int present;
15351 unsigned char bits;
15353 present = snd_hda_codec_read(codec, 0x1b, 0,
15354 AC_VERB_GET_PIN_SENSE, 0)
15355 & AC_PINSENSE_PRESENCE;
15356 bits = present ? 0 : PIN_OUT;
15357 snd_hda_codec_write(codec, 0x14, 0,
15358 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15361 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15363 unsigned int present1, present2;
15365 present1 = snd_hda_codec_read(codec, 0x21, 0,
15366 AC_VERB_GET_PIN_SENSE, 0)
15367 & AC_PINSENSE_PRESENCE;
15368 present2 = snd_hda_codec_read(codec, 0x15, 0,
15369 AC_VERB_GET_PIN_SENSE, 0)
15370 & AC_PINSENSE_PRESENCE;
15372 if (present1 || present2) {
15373 snd_hda_codec_write_cache(codec, 0x14, 0,
15374 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15376 snd_hda_codec_write_cache(codec, 0x14, 0,
15377 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15381 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15383 unsigned int present1, present2;
15385 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15386 AC_VERB_GET_PIN_SENSE, 0)
15387 & AC_PINSENSE_PRESENCE;
15388 present2 = snd_hda_codec_read(codec, 0x15, 0,
15389 AC_VERB_GET_PIN_SENSE, 0)
15390 & AC_PINSENSE_PRESENCE;
15392 if (present1 || present2) {
15393 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15394 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15395 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15396 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15398 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15399 AMP_IN_MUTE(0), 0);
15400 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15401 AMP_IN_MUTE(0), 0);
15405 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15407 unsigned int present;
15409 present = snd_hda_codec_read(codec, 0x18, 0,
15410 AC_VERB_GET_PIN_SENSE, 0)
15411 & AC_PINSENSE_PRESENCE;
15412 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15413 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15414 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15415 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15416 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15417 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15418 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15419 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15422 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15425 switch (res >> 26) {
15426 case ALC880_HP_EVENT:
15427 alc663_m51va_speaker_automute(codec);
15429 case ALC880_MIC_EVENT:
15430 alc663_m51va_mic_automute(codec);
15435 static void alc663_m51va_inithook(struct hda_codec *codec)
15437 alc663_m51va_speaker_automute(codec);
15438 alc663_m51va_mic_automute(codec);
15441 /* ***************** Mode1 ******************************/
15442 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15445 switch (res >> 26) {
15446 case ALC880_HP_EVENT:
15447 alc663_m51va_speaker_automute(codec);
15449 case ALC880_MIC_EVENT:
15450 alc662_eeepc_mic_automute(codec);
15455 static void alc663_mode1_inithook(struct hda_codec *codec)
15457 alc663_m51va_speaker_automute(codec);
15458 alc662_eeepc_mic_automute(codec);
15460 /* ***************** Mode2 ******************************/
15461 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15464 switch (res >> 26) {
15465 case ALC880_HP_EVENT:
15466 alc662_f5z_speaker_automute(codec);
15468 case ALC880_MIC_EVENT:
15469 alc662_eeepc_mic_automute(codec);
15474 static void alc662_mode2_inithook(struct hda_codec *codec)
15476 alc662_f5z_speaker_automute(codec);
15477 alc662_eeepc_mic_automute(codec);
15479 /* ***************** Mode3 ******************************/
15480 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15483 switch (res >> 26) {
15484 case ALC880_HP_EVENT:
15485 alc663_two_hp_m1_speaker_automute(codec);
15487 case ALC880_MIC_EVENT:
15488 alc662_eeepc_mic_automute(codec);
15493 static void alc663_mode3_inithook(struct hda_codec *codec)
15495 alc663_two_hp_m1_speaker_automute(codec);
15496 alc662_eeepc_mic_automute(codec);
15498 /* ***************** Mode4 ******************************/
15499 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15502 switch (res >> 26) {
15503 case ALC880_HP_EVENT:
15504 alc663_21jd_two_speaker_automute(codec);
15506 case ALC880_MIC_EVENT:
15507 alc662_eeepc_mic_automute(codec);
15512 static void alc663_mode4_inithook(struct hda_codec *codec)
15514 alc663_21jd_two_speaker_automute(codec);
15515 alc662_eeepc_mic_automute(codec);
15517 /* ***************** Mode5 ******************************/
15518 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15521 switch (res >> 26) {
15522 case ALC880_HP_EVENT:
15523 alc663_15jd_two_speaker_automute(codec);
15525 case ALC880_MIC_EVENT:
15526 alc662_eeepc_mic_automute(codec);
15531 static void alc663_mode5_inithook(struct hda_codec *codec)
15533 alc663_15jd_two_speaker_automute(codec);
15534 alc662_eeepc_mic_automute(codec);
15536 /* ***************** Mode6 ******************************/
15537 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15540 switch (res >> 26) {
15541 case ALC880_HP_EVENT:
15542 alc663_two_hp_m2_speaker_automute(codec);
15544 case ALC880_MIC_EVENT:
15545 alc662_eeepc_mic_automute(codec);
15550 static void alc663_mode6_inithook(struct hda_codec *codec)
15552 alc663_two_hp_m2_speaker_automute(codec);
15553 alc662_eeepc_mic_automute(codec);
15556 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15558 unsigned int present;
15559 unsigned char bits;
15561 present = snd_hda_codec_read(codec, 0x21, 0,
15562 AC_VERB_GET_PIN_SENSE, 0)
15563 & AC_PINSENSE_PRESENCE;
15564 bits = present ? HDA_AMP_MUTE : 0;
15565 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15566 HDA_AMP_MUTE, bits);
15567 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15568 HDA_AMP_MUTE, bits);
15571 static void alc663_g71v_front_automute(struct hda_codec *codec)
15573 unsigned int present;
15574 unsigned char bits;
15576 present = snd_hda_codec_read(codec, 0x15, 0,
15577 AC_VERB_GET_PIN_SENSE, 0)
15578 & AC_PINSENSE_PRESENCE;
15579 bits = present ? HDA_AMP_MUTE : 0;
15580 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15581 HDA_AMP_MUTE, bits);
15584 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15587 switch (res >> 26) {
15588 case ALC880_HP_EVENT:
15589 alc663_g71v_hp_automute(codec);
15591 case ALC880_FRONT_EVENT:
15592 alc663_g71v_front_automute(codec);
15594 case ALC880_MIC_EVENT:
15595 alc662_eeepc_mic_automute(codec);
15600 static void alc663_g71v_inithook(struct hda_codec *codec)
15602 alc663_g71v_front_automute(codec);
15603 alc663_g71v_hp_automute(codec);
15604 alc662_eeepc_mic_automute(codec);
15607 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15610 switch (res >> 26) {
15611 case ALC880_HP_EVENT:
15612 alc663_m51va_speaker_automute(codec);
15614 case ALC880_MIC_EVENT:
15615 alc662_eeepc_mic_automute(codec);
15620 static void alc663_g50v_inithook(struct hda_codec *codec)
15622 alc663_m51va_speaker_automute(codec);
15623 alc662_eeepc_mic_automute(codec);
15626 /* bind hp and internal speaker mute (with plug check) */
15627 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15628 struct snd_ctl_elem_value *ucontrol)
15630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15631 long *valp = ucontrol->value.integer.value;
15634 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15636 valp[0] ? 0 : HDA_AMP_MUTE);
15637 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15639 valp[1] ? 0 : HDA_AMP_MUTE);
15641 alc262_hippo1_automute(codec);
15645 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15646 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15648 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15649 .name = "Master Playback Switch",
15650 .info = snd_hda_mixer_amp_switch_info,
15651 .get = snd_hda_mixer_amp_switch_get,
15652 .put = alc662_ecs_master_sw_put,
15653 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15656 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15657 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15658 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15660 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15661 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15662 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15666 #ifdef CONFIG_SND_HDA_POWER_SAVE
15667 #define alc662_loopbacks alc880_loopbacks
15671 /* pcm configuration: identiacal with ALC880 */
15672 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15673 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15674 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15675 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15678 * configuration and preset
15680 static const char *alc662_models[ALC662_MODEL_LAST] = {
15681 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15682 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15683 [ALC662_3ST_6ch] = "3stack-6ch",
15684 [ALC662_5ST_DIG] = "6stack-dig",
15685 [ALC662_LENOVO_101E] = "lenovo-101e",
15686 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15687 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15688 [ALC662_ECS] = "ecs",
15689 [ALC663_ASUS_M51VA] = "m51va",
15690 [ALC663_ASUS_G71V] = "g71v",
15691 [ALC663_ASUS_H13] = "h13",
15692 [ALC663_ASUS_G50V] = "g50v",
15693 [ALC663_ASUS_MODE1] = "asus-mode1",
15694 [ALC662_ASUS_MODE2] = "asus-mode2",
15695 [ALC663_ASUS_MODE3] = "asus-mode3",
15696 [ALC663_ASUS_MODE4] = "asus-mode4",
15697 [ALC663_ASUS_MODE5] = "asus-mode5",
15698 [ALC663_ASUS_MODE6] = "asus-mode6",
15699 [ALC662_AUTO] = "auto",
15702 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15703 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15704 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15705 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15706 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15707 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15708 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15709 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15710 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15711 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15712 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15713 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15714 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15715 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15716 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15717 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15718 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15719 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15720 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15721 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15722 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15723 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15724 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15725 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15726 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15727 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15728 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15729 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15730 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15731 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15732 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15733 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15734 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15735 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15736 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15737 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15738 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15739 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15740 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15741 ALC662_3ST_6ch_DIG),
15742 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15743 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15744 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15745 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15746 ALC662_3ST_6ch_DIG),
15747 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15748 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15749 ALC662_3ST_6ch_DIG),
15750 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15751 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15752 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15756 static struct alc_config_preset alc662_presets[] = {
15757 [ALC662_3ST_2ch_DIG] = {
15758 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15759 .init_verbs = { alc662_init_verbs },
15760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15761 .dac_nids = alc662_dac_nids,
15762 .dig_out_nid = ALC662_DIGOUT_NID,
15763 .dig_in_nid = ALC662_DIGIN_NID,
15764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15765 .channel_mode = alc662_3ST_2ch_modes,
15766 .input_mux = &alc662_capture_source,
15768 [ALC662_3ST_6ch_DIG] = {
15769 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15770 alc662_capture_mixer },
15771 .init_verbs = { alc662_init_verbs },
15772 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15773 .dac_nids = alc662_dac_nids,
15774 .dig_out_nid = ALC662_DIGOUT_NID,
15775 .dig_in_nid = ALC662_DIGIN_NID,
15776 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15777 .channel_mode = alc662_3ST_6ch_modes,
15779 .input_mux = &alc662_capture_source,
15781 [ALC662_3ST_6ch] = {
15782 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15783 alc662_capture_mixer },
15784 .init_verbs = { alc662_init_verbs },
15785 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15786 .dac_nids = alc662_dac_nids,
15787 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15788 .channel_mode = alc662_3ST_6ch_modes,
15790 .input_mux = &alc662_capture_source,
15792 [ALC662_5ST_DIG] = {
15793 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15794 alc662_capture_mixer },
15795 .init_verbs = { alc662_init_verbs },
15796 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15797 .dac_nids = alc662_dac_nids,
15798 .dig_out_nid = ALC662_DIGOUT_NID,
15799 .dig_in_nid = ALC662_DIGIN_NID,
15800 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15801 .channel_mode = alc662_5stack_modes,
15802 .input_mux = &alc662_capture_source,
15804 [ALC662_LENOVO_101E] = {
15805 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15806 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15807 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15808 .dac_nids = alc662_dac_nids,
15809 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15810 .channel_mode = alc662_3ST_2ch_modes,
15811 .input_mux = &alc662_lenovo_101e_capture_source,
15812 .unsol_event = alc662_lenovo_101e_unsol_event,
15813 .init_hook = alc662_lenovo_101e_all_automute,
15815 [ALC662_ASUS_EEEPC_P701] = {
15816 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15817 .init_verbs = { alc662_init_verbs,
15818 alc662_eeepc_sue_init_verbs },
15819 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15820 .dac_nids = alc662_dac_nids,
15821 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15822 .channel_mode = alc662_3ST_2ch_modes,
15823 .input_mux = &alc662_eeepc_capture_source,
15824 .unsol_event = alc662_eeepc_unsol_event,
15825 .init_hook = alc662_eeepc_inithook,
15827 [ALC662_ASUS_EEEPC_EP20] = {
15828 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15829 alc662_chmode_mixer },
15830 .init_verbs = { alc662_init_verbs,
15831 alc662_eeepc_ep20_sue_init_verbs },
15832 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15833 .dac_nids = alc662_dac_nids,
15834 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15835 .channel_mode = alc662_3ST_6ch_modes,
15836 .input_mux = &alc662_lenovo_101e_capture_source,
15837 .unsol_event = alc662_eeepc_ep20_unsol_event,
15838 .init_hook = alc662_eeepc_ep20_inithook,
15841 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15842 .init_verbs = { alc662_init_verbs,
15843 alc662_ecs_init_verbs },
15844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15845 .dac_nids = alc662_dac_nids,
15846 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15847 .channel_mode = alc662_3ST_2ch_modes,
15848 .input_mux = &alc662_eeepc_capture_source,
15849 .unsol_event = alc662_eeepc_unsol_event,
15850 .init_hook = alc662_eeepc_inithook,
15852 [ALC663_ASUS_M51VA] = {
15853 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15854 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15855 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15856 .dac_nids = alc662_dac_nids,
15857 .dig_out_nid = ALC662_DIGOUT_NID,
15858 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15859 .channel_mode = alc662_3ST_2ch_modes,
15860 .input_mux = &alc663_m51va_capture_source,
15861 .unsol_event = alc663_m51va_unsol_event,
15862 .init_hook = alc663_m51va_inithook,
15864 [ALC663_ASUS_G71V] = {
15865 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15866 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15867 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15868 .dac_nids = alc662_dac_nids,
15869 .dig_out_nid = ALC662_DIGOUT_NID,
15870 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15871 .channel_mode = alc662_3ST_2ch_modes,
15872 .input_mux = &alc662_eeepc_capture_source,
15873 .unsol_event = alc663_g71v_unsol_event,
15874 .init_hook = alc663_g71v_inithook,
15876 [ALC663_ASUS_H13] = {
15877 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15878 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15879 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15880 .dac_nids = alc662_dac_nids,
15881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15882 .channel_mode = alc662_3ST_2ch_modes,
15883 .input_mux = &alc663_m51va_capture_source,
15884 .unsol_event = alc663_m51va_unsol_event,
15885 .init_hook = alc663_m51va_inithook,
15887 [ALC663_ASUS_G50V] = {
15888 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15889 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15891 .dac_nids = alc662_dac_nids,
15892 .dig_out_nid = ALC662_DIGOUT_NID,
15893 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15894 .channel_mode = alc662_3ST_6ch_modes,
15895 .input_mux = &alc663_capture_source,
15896 .unsol_event = alc663_g50v_unsol_event,
15897 .init_hook = alc663_g50v_inithook,
15899 [ALC663_ASUS_MODE1] = {
15900 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
15901 .init_verbs = { alc662_init_verbs,
15902 alc663_21jd_amic_init_verbs },
15903 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15905 .dac_nids = alc662_dac_nids,
15906 .dig_out_nid = ALC662_DIGOUT_NID,
15907 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15908 .channel_mode = alc662_3ST_2ch_modes,
15909 .input_mux = &alc662_eeepc_capture_source,
15910 .unsol_event = alc663_mode1_unsol_event,
15911 .init_hook = alc663_mode1_inithook,
15913 [ALC662_ASUS_MODE2] = {
15914 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
15915 .init_verbs = { alc662_init_verbs,
15916 alc662_1bjd_amic_init_verbs },
15917 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15918 .dac_nids = alc662_dac_nids,
15919 .dig_out_nid = ALC662_DIGOUT_NID,
15920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15921 .channel_mode = alc662_3ST_2ch_modes,
15922 .input_mux = &alc662_eeepc_capture_source,
15923 .unsol_event = alc662_mode2_unsol_event,
15924 .init_hook = alc662_mode2_inithook,
15926 [ALC663_ASUS_MODE3] = {
15927 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
15928 .init_verbs = { alc662_init_verbs,
15929 alc663_two_hp_amic_m1_init_verbs },
15930 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15932 .dac_nids = alc662_dac_nids,
15933 .dig_out_nid = ALC662_DIGOUT_NID,
15934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15935 .channel_mode = alc662_3ST_2ch_modes,
15936 .input_mux = &alc662_eeepc_capture_source,
15937 .unsol_event = alc663_mode3_unsol_event,
15938 .init_hook = alc663_mode3_inithook,
15940 [ALC663_ASUS_MODE4] = {
15941 .mixers = { alc663_asus_21jd_clfe_mixer,
15942 alc662_auto_capture_mixer},
15943 .init_verbs = { alc662_init_verbs,
15944 alc663_21jd_amic_init_verbs},
15945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15947 .dac_nids = alc662_dac_nids,
15948 .dig_out_nid = ALC662_DIGOUT_NID,
15949 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15950 .channel_mode = alc662_3ST_2ch_modes,
15951 .input_mux = &alc662_eeepc_capture_source,
15952 .unsol_event = alc663_mode4_unsol_event,
15953 .init_hook = alc663_mode4_inithook,
15955 [ALC663_ASUS_MODE5] = {
15956 .mixers = { alc663_asus_15jd_clfe_mixer,
15957 alc662_auto_capture_mixer },
15958 .init_verbs = { alc662_init_verbs,
15959 alc663_15jd_amic_init_verbs },
15960 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15962 .dac_nids = alc662_dac_nids,
15963 .dig_out_nid = ALC662_DIGOUT_NID,
15964 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15965 .channel_mode = alc662_3ST_2ch_modes,
15966 .input_mux = &alc662_eeepc_capture_source,
15967 .unsol_event = alc663_mode5_unsol_event,
15968 .init_hook = alc663_mode5_inithook,
15970 [ALC663_ASUS_MODE6] = {
15971 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
15972 .init_verbs = { alc662_init_verbs,
15973 alc663_two_hp_amic_m2_init_verbs },
15974 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15976 .dac_nids = alc662_dac_nids,
15977 .dig_out_nid = ALC662_DIGOUT_NID,
15978 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15979 .channel_mode = alc662_3ST_2ch_modes,
15980 .input_mux = &alc662_eeepc_capture_source,
15981 .unsol_event = alc663_mode6_unsol_event,
15982 .init_hook = alc663_mode6_inithook,
15988 * BIOS auto configuration
15991 /* add playback controls from the parsed DAC table */
15992 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15993 const struct auto_pin_cfg *cfg)
15996 static const char *chname[4] = {
15997 "Front", "Surround", NULL /*CLFE*/, "Side"
16002 for (i = 0; i < cfg->line_outs; i++) {
16003 if (!spec->multiout.dac_nids[i])
16005 nid = alc880_idx_to_dac(i);
16008 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16009 "Center Playback Volume",
16010 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16014 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16015 "LFE Playback Volume",
16016 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16020 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16021 "Center Playback Switch",
16022 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16026 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16027 "LFE Playback Switch",
16028 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16033 sprintf(name, "%s Playback Volume", chname[i]);
16034 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16035 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16039 sprintf(name, "%s Playback Switch", chname[i]);
16040 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16041 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16050 /* add playback controls for speaker and HP outputs */
16051 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16062 /* ALC663 has a mono output pin on 0x17 */
16063 sprintf(name, "%s Playback Switch", pfx);
16064 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16065 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16069 if (alc880_is_fixed_pin(pin)) {
16070 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16071 /* printk("DAC nid=%x\n",nid); */
16072 /* specify the DAC as the extra output */
16073 if (!spec->multiout.hp_nid)
16074 spec->multiout.hp_nid = nid;
16076 spec->multiout.extra_out_nid[0] = nid;
16077 /* control HP volume/switch on the output mixer amp */
16078 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16079 sprintf(name, "%s Playback Volume", pfx);
16080 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16081 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16084 sprintf(name, "%s Playback Switch", pfx);
16085 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16086 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16089 } else if (alc880_is_multi_pin(pin)) {
16090 /* set manual connection */
16091 /* we have only a switch on HP-out PIN */
16092 sprintf(name, "%s Playback Switch", pfx);
16093 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16094 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16101 /* create playback/capture controls for input pins */
16102 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16103 const struct auto_pin_cfg *cfg)
16105 struct hda_input_mux *imux = &spec->private_imux;
16108 for (i = 0; i < AUTO_PIN_LAST; i++) {
16109 if (alc880_is_input_pin(cfg->input_pins[i])) {
16110 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16111 err = new_analog_input(spec, cfg->input_pins[i],
16112 auto_pin_cfg_labels[i],
16116 imux->items[imux->num_items].label =
16117 auto_pin_cfg_labels[i];
16118 imux->items[imux->num_items].index =
16119 alc880_input_pin_idx(cfg->input_pins[i]);
16126 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16127 hda_nid_t nid, int pin_type,
16130 alc_set_pin_output(codec, nid, pin_type);
16131 /* need the manual connection? */
16132 if (alc880_is_multi_pin(nid)) {
16133 struct alc_spec *spec = codec->spec;
16134 int idx = alc880_multi_pin_idx(nid);
16135 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16136 AC_VERB_SET_CONNECT_SEL,
16137 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16141 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16143 struct alc_spec *spec = codec->spec;
16146 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16147 for (i = 0; i <= HDA_SIDE; i++) {
16148 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16149 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16151 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16156 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16158 struct alc_spec *spec = codec->spec;
16161 pin = spec->autocfg.hp_pins[0];
16162 if (pin) /* connect to front */
16164 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16165 pin = spec->autocfg.speaker_pins[0];
16167 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16170 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16171 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16173 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16175 struct alc_spec *spec = codec->spec;
16178 for (i = 0; i < AUTO_PIN_LAST; i++) {
16179 hda_nid_t nid = spec->autocfg.input_pins[i];
16180 if (alc662_is_input_pin(nid)) {
16181 snd_hda_codec_write(codec, nid, 0,
16182 AC_VERB_SET_PIN_WIDGET_CONTROL,
16183 (i <= AUTO_PIN_FRONT_MIC ?
16184 PIN_VREF80 : PIN_IN));
16185 if (nid != ALC662_PIN_CD_NID)
16186 snd_hda_codec_write(codec, nid, 0,
16187 AC_VERB_SET_AMP_GAIN_MUTE,
16193 #define alc662_auto_init_input_src alc882_auto_init_input_src
16195 static int alc662_parse_auto_config(struct hda_codec *codec)
16197 struct alc_spec *spec = codec->spec;
16199 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16201 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16205 if (!spec->autocfg.line_outs)
16206 return 0; /* can't find valid BIOS pin config */
16208 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16211 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16214 err = alc662_auto_create_extra_out(spec,
16215 spec->autocfg.speaker_pins[0],
16219 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16223 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16227 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16229 if (spec->autocfg.dig_out_pin)
16230 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16232 if (spec->kctls.list)
16233 spec->mixers[spec->num_mixers++] = spec->kctls.list;
16235 spec->num_mux_defs = 1;
16236 spec->input_mux = &spec->private_imux;
16238 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16239 if (codec->vendor_id == 0x10ec0663)
16240 spec->init_verbs[spec->num_init_verbs++] =
16241 alc663_auto_init_verbs;
16243 err = alc_auto_add_mic_boost(codec);
16247 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16248 spec->num_mixers++;
16252 /* additional initialization for auto-configuration model */
16253 static void alc662_auto_init(struct hda_codec *codec)
16255 struct alc_spec *spec = codec->spec;
16256 alc662_auto_init_multi_out(codec);
16257 alc662_auto_init_hp_out(codec);
16258 alc662_auto_init_analog_input(codec);
16259 alc662_auto_init_input_src(codec);
16260 if (spec->unsol_event)
16261 alc_inithook(codec);
16264 static int patch_alc662(struct hda_codec *codec)
16266 struct alc_spec *spec;
16267 int err, board_config;
16269 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16273 codec->spec = spec;
16275 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16277 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16280 if (board_config < 0) {
16281 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16282 "trying auto-probe from BIOS...\n");
16283 board_config = ALC662_AUTO;
16286 if (board_config == ALC662_AUTO) {
16287 /* automatic parse from the BIOS config */
16288 err = alc662_parse_auto_config(codec);
16294 "hda_codec: Cannot set up configuration "
16295 "from BIOS. Using base mode...\n");
16296 board_config = ALC662_3ST_2ch_DIG;
16300 if (board_config != ALC662_AUTO)
16301 setup_preset(spec, &alc662_presets[board_config]);
16303 if (codec->vendor_id == 0x10ec0663) {
16304 spec->stream_name_analog = "ALC663 Analog";
16305 spec->stream_name_digital = "ALC663 Digital";
16306 } else if (codec->vendor_id == 0x10ec0272) {
16307 spec->stream_name_analog = "ALC272 Analog";
16308 spec->stream_name_digital = "ALC272 Digital";
16310 spec->stream_name_analog = "ALC662 Analog";
16311 spec->stream_name_digital = "ALC662 Digital";
16314 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16315 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16317 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16318 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16320 spec->adc_nids = alc662_adc_nids;
16321 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16322 spec->capsrc_nids = alc662_capsrc_nids;
16324 spec->vmaster_nid = 0x02;
16326 codec->patch_ops = alc_patch_ops;
16327 if (board_config == ALC662_AUTO)
16328 spec->init_hook = alc662_auto_init;
16329 #ifdef CONFIG_SND_HDA_POWER_SAVE
16330 if (!spec->loopback.amplist)
16331 spec->loopback.amplist = alc662_loopbacks;
16340 struct hda_codec_preset snd_hda_preset_realtek[] = {
16341 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16342 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16343 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16344 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16345 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16346 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16347 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16348 .patch = patch_alc861 },
16349 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16350 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16351 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16352 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16353 .patch = patch_alc883 },
16354 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16355 .patch = patch_alc662 },
16356 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16357 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16358 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16359 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16360 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16361 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16362 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16363 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16364 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16365 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16366 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16367 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16368 .patch = patch_alc883 },
16369 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16370 {} /* terminator */