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;
310 #ifdef SND_HDA_NEEDS_RESUME
311 #define ALC_MAX_PINS 16
312 unsigned int num_pins;
313 hda_nid_t pin_nids[ALC_MAX_PINS];
314 unsigned int pin_cfgs[ALC_MAX_PINS];
319 * configuration template - to be copied to the spec instance
321 struct alc_config_preset {
322 struct snd_kcontrol_new *mixers[5]; /* should be identical size
325 const struct hda_verb *init_verbs[5];
326 unsigned int num_dacs;
328 hda_nid_t dig_out_nid; /* optional */
329 hda_nid_t hp_nid; /* optional */
330 unsigned int num_adc_nids;
332 hda_nid_t *capsrc_nids;
333 hda_nid_t dig_in_nid;
334 unsigned int num_channel_mode;
335 const struct hda_channel_mode *channel_mode;
337 unsigned int num_mux_defs;
338 const struct hda_input_mux *input_mux;
339 void (*unsol_event)(struct hda_codec *, unsigned int);
340 void (*init_hook)(struct hda_codec *);
341 #ifdef CONFIG_SND_HDA_POWER_SAVE
342 struct hda_amp_list *loopbacks;
350 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
351 struct snd_ctl_elem_info *uinfo)
353 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
354 struct alc_spec *spec = codec->spec;
355 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
356 if (mux_idx >= spec->num_mux_defs)
358 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
361 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365 struct alc_spec *spec = codec->spec;
366 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
368 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
372 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *ucontrol)
375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
376 struct alc_spec *spec = codec->spec;
377 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
378 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
379 hda_nid_t nid = spec->capsrc_nids ?
380 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
381 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
382 nid, &spec->cur_mux[adc_idx]);
387 * channel mode setting
389 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_info *uinfo)
392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
393 struct alc_spec *spec = codec->spec;
394 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
395 spec->num_channel_mode);
398 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_value *ucontrol)
401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
402 struct alc_spec *spec = codec->spec;
403 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
404 spec->num_channel_mode,
405 spec->multiout.max_channels);
408 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
409 struct snd_ctl_elem_value *ucontrol)
411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
412 struct alc_spec *spec = codec->spec;
413 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
414 spec->num_channel_mode,
415 &spec->multiout.max_channels);
416 if (err >= 0 && spec->need_dac_fix)
417 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
422 * Control the mode of pin widget settings via the mixer. "pc" is used
423 * instead of "%" to avoid consequences of accidently treating the % as
424 * being part of a format specifier. Maximum allowed length of a value is
425 * 63 characters plus NULL terminator.
427 * Note: some retasking pin complexes seem to ignore requests for input
428 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
429 * are requested. Therefore order this list so that this behaviour will not
430 * cause problems when mixer clients move through the enum sequentially.
431 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
434 static char *alc_pin_mode_names[] = {
435 "Mic 50pc bias", "Mic 80pc bias",
436 "Line in", "Line out", "Headphone out",
438 static unsigned char alc_pin_mode_values[] = {
439 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
441 /* The control can present all 5 options, or it can limit the options based
442 * in the pin being assumed to be exclusively an input or an output pin. In
443 * addition, "input" pins may or may not process the mic bias option
444 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
445 * accept requests for bias as of chip versions up to March 2006) and/or
446 * wiring in the computer.
448 #define ALC_PIN_DIR_IN 0x00
449 #define ALC_PIN_DIR_OUT 0x01
450 #define ALC_PIN_DIR_INOUT 0x02
451 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
452 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
454 /* Info about the pin modes supported by the different pin direction modes.
455 * For each direction the minimum and maximum values are given.
457 static signed char alc_pin_mode_dir_info[5][2] = {
458 { 0, 2 }, /* ALC_PIN_DIR_IN */
459 { 3, 4 }, /* ALC_PIN_DIR_OUT */
460 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
461 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
462 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
464 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
465 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
466 #define alc_pin_mode_n_items(_dir) \
467 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
469 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_info *uinfo)
472 unsigned int item_num = uinfo->value.enumerated.item;
473 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
477 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
479 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
480 item_num = alc_pin_mode_min(dir);
481 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
485 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 hda_nid_t nid = kcontrol->private_value & 0xffff;
491 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
492 long *valp = ucontrol->value.integer.value;
493 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
494 AC_VERB_GET_PIN_WIDGET_CONTROL,
497 /* Find enumerated value for current pinctl setting */
498 i = alc_pin_mode_min(dir);
499 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
501 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
505 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
506 struct snd_ctl_elem_value *ucontrol)
509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
510 hda_nid_t nid = kcontrol->private_value & 0xffff;
511 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
512 long val = *ucontrol->value.integer.value;
513 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
514 AC_VERB_GET_PIN_WIDGET_CONTROL,
517 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
518 val = alc_pin_mode_min(dir);
520 change = pinctl != alc_pin_mode_values[val];
522 /* Set pin mode to that requested */
523 snd_hda_codec_write_cache(codec, nid, 0,
524 AC_VERB_SET_PIN_WIDGET_CONTROL,
525 alc_pin_mode_values[val]);
527 /* Also enable the retasking pin's input/output as required
528 * for the requested pin mode. Enum values of 2 or less are
531 * Dynamically switching the input/output buffers probably
532 * reduces noise slightly (particularly on input) so we'll
533 * do it. However, having both input and output buffers
534 * enabled simultaneously doesn't seem to be problematic if
535 * this turns out to be necessary in the future.
538 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
539 HDA_AMP_MUTE, HDA_AMP_MUTE);
540 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
543 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
544 HDA_AMP_MUTE, HDA_AMP_MUTE);
545 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
552 #define ALC_PIN_MODE(xname, nid, dir) \
553 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
554 .info = alc_pin_mode_info, \
555 .get = alc_pin_mode_get, \
556 .put = alc_pin_mode_put, \
557 .private_value = nid | (dir<<16) }
559 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
560 * together using a mask with more than one bit set. This control is
561 * currently used only by the ALC260 test model. At this stage they are not
562 * needed for any "production" models.
564 #ifdef CONFIG_SND_DEBUG
565 #define alc_gpio_data_info snd_ctl_boolean_mono_info
567 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571 hda_nid_t nid = kcontrol->private_value & 0xffff;
572 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573 long *valp = ucontrol->value.integer.value;
574 unsigned int val = snd_hda_codec_read(codec, nid, 0,
575 AC_VERB_GET_GPIO_DATA, 0x00);
577 *valp = (val & mask) != 0;
580 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
588 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_GPIO_DATA,
592 /* Set/unset the masked GPIO bit(s) as needed */
593 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
598 snd_hda_codec_write_cache(codec, nid, 0,
599 AC_VERB_SET_GPIO_DATA, gpio_data);
603 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
604 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
605 .info = alc_gpio_data_info, \
606 .get = alc_gpio_data_get, \
607 .put = alc_gpio_data_put, \
608 .private_value = nid | (mask<<16) }
609 #endif /* CONFIG_SND_DEBUG */
611 /* A switch control to allow the enabling of the digital IO pins on the
612 * ALC260. This is incredibly simplistic; the intention of this control is
613 * to provide something in the test model allowing digital outputs to be
614 * identified if present. If models are found which can utilise these
615 * outputs a more complete mixer control can be devised for those models if
618 #ifdef CONFIG_SND_DEBUG
619 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
621 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
622 struct snd_ctl_elem_value *ucontrol)
624 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
625 hda_nid_t nid = kcontrol->private_value & 0xffff;
626 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
627 long *valp = ucontrol->value.integer.value;
628 unsigned int val = snd_hda_codec_read(codec, nid, 0,
629 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
631 *valp = (val & mask) != 0;
634 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
640 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
641 long val = *ucontrol->value.integer.value;
642 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
643 AC_VERB_GET_DIGI_CONVERT_1,
646 /* Set/unset the masked control bit(s) as needed */
647 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
652 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
657 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
658 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
659 .info = alc_spdif_ctrl_info, \
660 .get = alc_spdif_ctrl_get, \
661 .put = alc_spdif_ctrl_put, \
662 .private_value = nid | (mask<<16) }
663 #endif /* CONFIG_SND_DEBUG */
665 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
666 * Again, this is only used in the ALC26x test models to help identify when
667 * the EAPD line must be asserted for features to work.
669 #ifdef CONFIG_SND_DEBUG
670 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
672 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
676 hda_nid_t nid = kcontrol->private_value & 0xffff;
677 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
678 long *valp = ucontrol->value.integer.value;
679 unsigned int val = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
682 *valp = (val & mask) != 0;
686 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
690 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
691 hda_nid_t nid = kcontrol->private_value & 0xffff;
692 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
693 long val = *ucontrol->value.integer.value;
694 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
695 AC_VERB_GET_EAPD_BTLENABLE,
698 /* Set/unset the masked control bit(s) as needed */
699 change = (!val ? 0 : mask) != (ctrl_data & mask);
704 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
710 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
712 .info = alc_eapd_ctrl_info, \
713 .get = alc_eapd_ctrl_get, \
714 .put = alc_eapd_ctrl_put, \
715 .private_value = nid | (mask<<16) }
716 #endif /* CONFIG_SND_DEBUG */
720 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
722 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
724 spec->mixers[spec->num_mixers++] = mix;
727 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
729 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
731 spec->init_verbs[spec->num_init_verbs++] = verb;
735 * set up from the preset table
737 static void setup_preset(struct alc_spec *spec,
738 const struct alc_config_preset *preset)
742 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
743 add_mixer(spec, preset->mixers[i]);
744 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
746 add_verb(spec, preset->init_verbs[i]);
748 spec->channel_mode = preset->channel_mode;
749 spec->num_channel_mode = preset->num_channel_mode;
750 spec->need_dac_fix = preset->need_dac_fix;
752 spec->multiout.max_channels = spec->channel_mode[0].channels;
754 spec->multiout.num_dacs = preset->num_dacs;
755 spec->multiout.dac_nids = preset->dac_nids;
756 spec->multiout.dig_out_nid = preset->dig_out_nid;
757 spec->multiout.hp_nid = preset->hp_nid;
759 spec->num_mux_defs = preset->num_mux_defs;
760 if (!spec->num_mux_defs)
761 spec->num_mux_defs = 1;
762 spec->input_mux = preset->input_mux;
764 spec->num_adc_nids = preset->num_adc_nids;
765 spec->adc_nids = preset->adc_nids;
766 spec->capsrc_nids = preset->capsrc_nids;
767 spec->dig_in_nid = preset->dig_in_nid;
769 spec->unsol_event = preset->unsol_event;
770 spec->init_hook = preset->init_hook;
771 #ifdef CONFIG_SND_HDA_POWER_SAVE
772 spec->loopback.amplist = preset->loopbacks;
776 /* Enable GPIO mask and set output */
777 static struct hda_verb alc_gpio1_init_verbs[] = {
778 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
779 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
780 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
784 static struct hda_verb alc_gpio2_init_verbs[] = {
785 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
786 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
787 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
791 static struct hda_verb alc_gpio3_init_verbs[] = {
792 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
793 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
794 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
799 * Fix hardware PLL issue
800 * On some codecs, the analog PLL gating control must be off while
801 * the default value is 1.
803 static void alc_fix_pll(struct hda_codec *codec)
805 struct alc_spec *spec = codec->spec;
810 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
812 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
813 AC_VERB_GET_PROC_COEF, 0);
814 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
816 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
817 val & ~(1 << spec->pll_coef_bit));
820 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
821 unsigned int coef_idx, unsigned int coef_bit)
823 struct alc_spec *spec = codec->spec;
825 spec->pll_coef_idx = coef_idx;
826 spec->pll_coef_bit = coef_bit;
830 static void alc_sku_automute(struct hda_codec *codec)
832 struct alc_spec *spec = codec->spec;
833 unsigned int present;
834 unsigned int hp_nid = spec->autocfg.hp_pins[0];
835 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
837 /* need to execute and sync at first */
838 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
839 present = snd_hda_codec_read(codec, hp_nid, 0,
840 AC_VERB_GET_PIN_SENSE, 0);
841 spec->jack_present = (present & 0x80000000) != 0;
842 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
843 spec->jack_present ? 0 : PIN_OUT);
846 #if 0 /* it's broken in some acses -- temporarily disabled */
847 static void alc_mic_automute(struct hda_codec *codec)
849 struct alc_spec *spec = codec->spec;
850 unsigned int present;
851 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
852 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
853 unsigned int mix_nid = spec->capsrc_nids[0];
854 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
856 capsrc_idx_mic = mic_nid - 0x18;
857 capsrc_idx_fmic = fmic_nid - 0x18;
858 present = snd_hda_codec_read(codec, mic_nid, 0,
859 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
860 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
861 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
862 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
863 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
864 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
865 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
868 #define alc_mic_automute(codec) /* NOP */
869 #endif /* disabled */
871 /* unsolicited event for HP jack sensing */
872 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
874 if (codec->vendor_id == 0x10ec0880)
878 if (res == ALC880_HP_EVENT)
879 alc_sku_automute(codec);
881 if (res == ALC880_MIC_EVENT)
882 alc_mic_automute(codec);
885 static void alc_inithook(struct hda_codec *codec)
887 alc_sku_automute(codec);
888 alc_mic_automute(codec);
891 /* additional initialization for ALC888 variants */
892 static void alc888_coef_init(struct hda_codec *codec)
896 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
897 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
898 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
899 if ((tmp & 0xf0) == 2)
901 snd_hda_codec_read(codec, 0x20, 0,
902 AC_VERB_SET_PROC_COEF, 0x830);
905 snd_hda_codec_read(codec, 0x20, 0,
906 AC_VERB_SET_PROC_COEF, 0x3030);
909 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
910 * 31 ~ 16 : Manufacture ID
912 * 7 ~ 0 : Assembly ID
913 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
915 static void alc_subsystem_id(struct hda_codec *codec,
916 unsigned int porta, unsigned int porte,
919 unsigned int ass, tmp, i;
921 struct alc_spec *spec = codec->spec;
923 ass = codec->subsystem_id & 0xffff;
924 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
928 * 31~30 : port conetcivity
931 * 19~16 : Check sum (15:1)
936 if (codec->vendor_id == 0x10ec0260)
938 ass = snd_hda_codec_read(codec, nid, 0,
939 AC_VERB_GET_CONFIG_DEFAULT, 0);
940 if (!(ass & 1) && !(ass & 0x100000))
942 if ((ass >> 30) != 1) /* no physical connection */
947 for (i = 1; i < 16; i++) {
951 if (((ass >> 16) & 0xf) != tmp)
957 * 2 : 0 --> Desktop, 1 --> Laptop
958 * 3~5 : External Amplifier control
961 tmp = (ass & 0x38) >> 3; /* external Amp control */
964 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
967 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
970 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
972 case 5: /* set EAPD output high */
973 switch (codec->vendor_id) {
975 snd_hda_codec_write(codec, 0x0f, 0,
976 AC_VERB_SET_EAPD_BTLENABLE, 2);
977 snd_hda_codec_write(codec, 0x10, 0,
978 AC_VERB_SET_EAPD_BTLENABLE, 2);
989 snd_hda_codec_write(codec, 0x14, 0,
990 AC_VERB_SET_EAPD_BTLENABLE, 2);
991 snd_hda_codec_write(codec, 0x15, 0,
992 AC_VERB_SET_EAPD_BTLENABLE, 2);
995 switch (codec->vendor_id) {
997 snd_hda_codec_write(codec, 0x1a, 0,
998 AC_VERB_SET_COEF_INDEX, 7);
999 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1000 AC_VERB_GET_PROC_COEF, 0);
1001 snd_hda_codec_write(codec, 0x1a, 0,
1002 AC_VERB_SET_COEF_INDEX, 7);
1003 snd_hda_codec_write(codec, 0x1a, 0,
1004 AC_VERB_SET_PROC_COEF,
1013 snd_hda_codec_write(codec, 0x20, 0,
1014 AC_VERB_SET_COEF_INDEX, 7);
1015 tmp = snd_hda_codec_read(codec, 0x20, 0,
1016 AC_VERB_GET_PROC_COEF, 0);
1017 snd_hda_codec_write(codec, 0x20, 0,
1018 AC_VERB_SET_COEF_INDEX, 7);
1019 snd_hda_codec_write(codec, 0x20, 0,
1020 AC_VERB_SET_PROC_COEF,
1024 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1028 snd_hda_codec_write(codec, 0x20, 0,
1029 AC_VERB_SET_COEF_INDEX, 7);
1030 tmp = snd_hda_codec_read(codec, 0x20, 0,
1031 AC_VERB_GET_PROC_COEF, 0);
1032 snd_hda_codec_write(codec, 0x20, 0,
1033 AC_VERB_SET_COEF_INDEX, 7);
1034 snd_hda_codec_write(codec, 0x20, 0,
1035 AC_VERB_SET_PROC_COEF,
1043 /* is laptop or Desktop and enable the function "Mute internal speaker
1044 * when the external headphone out jack is plugged"
1046 if (!(ass & 0x8000))
1049 * 10~8 : Jack location
1050 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1052 * 15 : 1 --> enable the function "Mute internal speaker
1053 * when the external headphone out jack is plugged"
1055 if (!spec->autocfg.speaker_pins[0]) {
1056 if (spec->autocfg.line_out_pins[0])
1057 spec->autocfg.speaker_pins[0] =
1058 spec->autocfg.line_out_pins[0];
1063 if (!spec->autocfg.hp_pins[0]) {
1064 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1066 spec->autocfg.hp_pins[0] = porta;
1068 spec->autocfg.hp_pins[0] = porte;
1070 spec->autocfg.hp_pins[0] = portd;
1074 if (spec->autocfg.hp_pins[0])
1075 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1076 AC_VERB_SET_UNSOLICITED_ENABLE,
1077 AC_USRSP_EN | ALC880_HP_EVENT);
1079 #if 0 /* it's broken in some acses -- temporarily disabled */
1080 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1081 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1082 snd_hda_codec_write(codec,
1083 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1084 AC_VERB_SET_UNSOLICITED_ENABLE,
1085 AC_USRSP_EN | ALC880_MIC_EVENT);
1086 #endif /* disabled */
1088 spec->unsol_event = alc_sku_unsol_event;
1092 * Fix-up pin default configurations
1100 static void alc_fix_pincfg(struct hda_codec *codec,
1101 const struct snd_pci_quirk *quirk,
1102 const struct alc_pincfg **pinfix)
1104 const struct alc_pincfg *cfg;
1106 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1110 cfg = pinfix[quirk->value];
1111 for (; cfg->nid; cfg++) {
1114 for (i = 0; i < 4; i++) {
1115 snd_hda_codec_write(codec, cfg->nid, 0,
1116 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1124 * ALC880 3-stack model
1126 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1127 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1128 * F-Mic = 0x1b, HP = 0x19
1131 static hda_nid_t alc880_dac_nids[4] = {
1132 /* front, rear, clfe, rear_surr */
1133 0x02, 0x05, 0x04, 0x03
1136 static hda_nid_t alc880_adc_nids[3] = {
1141 /* The datasheet says the node 0x07 is connected from inputs,
1142 * but it shows zero connection in the real implementation on some devices.
1143 * Note: this is a 915GAV bug, fixed on 915GLV
1145 static hda_nid_t alc880_adc_nids_alt[2] = {
1150 #define ALC880_DIGOUT_NID 0x06
1151 #define ALC880_DIGIN_NID 0x0a
1153 static struct hda_input_mux alc880_capture_source = {
1157 { "Front Mic", 0x3 },
1163 /* channel source setting (2/6 channel selection for 3-stack) */
1165 static struct hda_verb alc880_threestack_ch2_init[] = {
1166 /* set line-in to input, mute it */
1167 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1168 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1169 /* set mic-in to input vref 80%, mute it */
1170 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1171 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1176 static struct hda_verb alc880_threestack_ch6_init[] = {
1177 /* set line-in to output, unmute it */
1178 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1179 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1180 /* set mic-in to output, unmute it */
1181 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1182 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1186 static struct hda_channel_mode alc880_threestack_modes[2] = {
1187 { 2, alc880_threestack_ch2_init },
1188 { 6, alc880_threestack_ch6_init },
1191 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1195 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1196 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1197 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1198 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1199 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1200 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1201 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1205 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1206 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1207 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1208 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1209 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1210 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Channel Mode",
1214 .info = alc_ch_mode_info,
1215 .get = alc_ch_mode_get,
1216 .put = alc_ch_mode_put,
1221 /* capture mixer elements */
1222 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1223 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1224 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1225 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1226 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1227 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1228 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1231 /* The multiple "Capture Source" controls confuse alsamixer
1232 * So call somewhat different..
1234 /* .name = "Capture Source", */
1235 .name = "Input Source",
1237 .info = alc_mux_enum_info,
1238 .get = alc_mux_enum_get,
1239 .put = alc_mux_enum_put,
1244 /* capture mixer elements (in case NID 0x07 not available) */
1245 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1246 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1247 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1248 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1249 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1252 /* The multiple "Capture Source" controls confuse alsamixer
1253 * So call somewhat different..
1255 /* .name = "Capture Source", */
1256 .name = "Input Source",
1258 .info = alc_mux_enum_info,
1259 .get = alc_mux_enum_get,
1260 .put = alc_mux_enum_put,
1267 * ALC880 5-stack model
1269 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1271 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1272 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1275 /* additional mixers to alc880_three_stack_mixer */
1276 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1277 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1278 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1282 /* channel source setting (6/8 channel selection for 5-stack) */
1284 static struct hda_verb alc880_fivestack_ch6_init[] = {
1285 /* set line-in to input, mute it */
1286 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1287 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1292 static struct hda_verb alc880_fivestack_ch8_init[] = {
1293 /* set line-in to output, unmute it */
1294 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1295 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1299 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1300 { 6, alc880_fivestack_ch6_init },
1301 { 8, alc880_fivestack_ch8_init },
1306 * ALC880 6-stack model
1308 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1309 * Side = 0x05 (0x0f)
1310 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1311 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1314 static hda_nid_t alc880_6st_dac_nids[4] = {
1315 /* front, rear, clfe, rear_surr */
1316 0x02, 0x03, 0x04, 0x05
1319 static struct hda_input_mux alc880_6stack_capture_source = {
1323 { "Front Mic", 0x1 },
1329 /* fixed 8-channels */
1330 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1334 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1335 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1336 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1337 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1338 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1339 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1340 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1341 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1342 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1344 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1345 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1346 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1347 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1348 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1351 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1352 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1353 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1354 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1357 .name = "Channel Mode",
1358 .info = alc_ch_mode_info,
1359 .get = alc_ch_mode_get,
1360 .put = alc_ch_mode_put,
1369 * W810 has rear IO for:
1372 * Center/LFE (DAC 04)
1375 * The system also has a pair of internal speakers, and a headphone jack.
1376 * These are both connected to Line2 on the codec, hence to DAC 02.
1378 * There is a variable resistor to control the speaker or headphone
1379 * volume. This is a hardware-only device without a software API.
1381 * Plugging headphones in will disable the internal speakers. This is
1382 * implemented in hardware, not via the driver using jack sense. In
1383 * a similar fashion, plugging into the rear socket marked "front" will
1384 * disable both the speakers and headphones.
1386 * For input, there's a microphone jack, and an "audio in" jack.
1387 * These may not do anything useful with this driver yet, because I
1388 * haven't setup any initialization verbs for these yet...
1391 static hda_nid_t alc880_w810_dac_nids[3] = {
1392 /* front, rear/surround, clfe */
1396 /* fixed 6 channels */
1397 static struct hda_channel_mode alc880_w810_modes[1] = {
1401 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1402 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1406 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1419 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1420 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1424 static hda_nid_t alc880_z71v_dac_nids[1] = {
1427 #define ALC880_Z71V_HP_DAC 0x03
1429 /* fixed 2 channels */
1430 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1434 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1436 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1437 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1438 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1448 * ALC880 F1734 model
1450 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1451 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1454 static hda_nid_t alc880_f1734_dac_nids[1] = {
1457 #define ALC880_F1734_HP_DAC 0x02
1459 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1460 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1461 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1462 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1463 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1471 static struct hda_input_mux alc880_f1734_capture_source = {
1483 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1484 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1485 * Mic = 0x18, Line = 0x1a
1488 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1489 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1491 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1494 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1495 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1496 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1497 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1498 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1502 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1503 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1505 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1508 .name = "Channel Mode",
1509 .info = alc_ch_mode_info,
1510 .get = alc_ch_mode_get,
1511 .put = alc_ch_mode_put,
1517 * ALC880 ASUS W1V model
1519 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1520 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1521 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1524 /* additional mixers to alc880_asus_mixer */
1525 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1526 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1527 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1531 /* additional mixers to alc880_asus_mixer */
1532 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1533 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1534 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1539 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1541 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1543 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1544 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1545 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1546 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1547 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1548 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1551 /* The multiple "Capture Source" controls confuse alsamixer
1552 * So call somewhat different..
1554 /* .name = "Capture Source", */
1555 .name = "Input Source",
1557 .info = alc_mux_enum_info,
1558 .get = alc_mux_enum_get,
1559 .put = alc_mux_enum_put,
1565 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1567 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1569 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1570 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1571 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1572 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1573 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1574 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1575 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1576 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1577 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1582 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1583 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586 .name = "Channel Mode",
1587 .info = alc_ch_mode_info,
1588 .get = alc_ch_mode_get,
1589 .put = alc_ch_mode_put,
1594 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1595 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1596 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1597 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1598 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1601 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1602 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1603 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1604 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1608 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1609 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1610 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1611 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1612 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1619 * virtual master controls
1623 * slave controls for virtual master
1625 static const char *alc_slave_vols[] = {
1626 "Front Playback Volume",
1627 "Surround Playback Volume",
1628 "Center Playback Volume",
1629 "LFE Playback Volume",
1630 "Side Playback Volume",
1631 "Headphone Playback Volume",
1632 "Speaker Playback Volume",
1633 "Mono Playback Volume",
1634 "Line-Out Playback Volume",
1638 static const char *alc_slave_sws[] = {
1639 "Front Playback Switch",
1640 "Surround Playback Switch",
1641 "Center Playback Switch",
1642 "LFE Playback Switch",
1643 "Side Playback Switch",
1644 "Headphone Playback Switch",
1645 "Speaker Playback Switch",
1646 "Mono Playback Switch",
1647 "IEC958 Playback Switch",
1652 * build control elements
1655 static void alc_free_kctls(struct hda_codec *codec);
1657 static int alc_build_controls(struct hda_codec *codec)
1659 struct alc_spec *spec = codec->spec;
1663 for (i = 0; i < spec->num_mixers; i++) {
1664 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1669 if (spec->multiout.dig_out_nid) {
1670 err = snd_hda_create_spdif_out_ctls(codec,
1671 spec->multiout.dig_out_nid);
1674 err = snd_hda_create_spdif_share_sw(codec,
1678 spec->multiout.share_spdif = 1;
1680 if (spec->dig_in_nid) {
1681 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1686 /* if we have no master control, let's create it */
1687 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1688 unsigned int vmaster_tlv[4];
1689 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1690 HDA_OUTPUT, vmaster_tlv);
1691 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1692 vmaster_tlv, alc_slave_vols);
1696 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1697 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1698 NULL, alc_slave_sws);
1703 alc_free_kctls(codec); /* no longer needed */
1709 * initialize the codec volumes, etc
1713 * generic initialization of ADC, input mixers and output mixers
1715 static struct hda_verb alc880_volume_init_verbs[] = {
1717 * Unmute ADC0-2 and set the default input to mic-in
1719 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1720 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1721 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1722 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1723 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1724 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1726 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1728 * Note: PASD motherboards uses the Line In 2 as the input for front
1731 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1732 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1733 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1734 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1735 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1736 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1737 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1741 * Set up output mixers (0x0c - 0x0f)
1743 /* set vol=0 to output mixers */
1744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1748 /* set up input amps for analog loopback */
1749 /* Amp Indices: DAC = 0, mixer = 1 */
1750 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1754 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1763 * 3-stack pin configuration:
1764 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1766 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1768 * preset connection lists of input pins
1769 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1771 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1772 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1773 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1776 * Set pin mode and muting
1778 /* set front pin widgets 0x14 for output */
1779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1781 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1784 /* Mic2 (as headphone out) for HP output */
1785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1787 /* Line In pin widget for input */
1788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1790 /* Line2 (as front mic) pin widget for input and vref at 80% */
1791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1792 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1793 /* CD pin widget for input */
1794 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1800 * 5-stack pin configuration:
1801 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1802 * line-in/side = 0x1a, f-mic = 0x1b
1804 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1806 * preset connection lists of input pins
1807 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1809 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1810 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1813 * Set pin mode and muting
1815 /* set pin widgets 0x14-0x17 for output */
1816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1820 /* unmute pins for output (no gain on this amp) */
1821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1823 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1826 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1829 /* Mic2 (as headphone out) for HP output */
1830 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1832 /* Line In pin widget for input */
1833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1835 /* Line2 (as front mic) pin widget for input and vref at 80% */
1836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1838 /* CD pin widget for input */
1839 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1845 * W810 pin configuration:
1846 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1848 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1849 /* hphone/speaker input selector: front DAC */
1850 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1852 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1853 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1856 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1857 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1860 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1866 * Z71V pin configuration:
1867 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1869 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1870 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1878 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1884 * 6-stack pin configuration:
1885 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1886 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1888 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1889 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1894 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1897 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1898 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1900 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1901 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1905 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1908 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1914 * Uniwill pin configuration:
1915 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1918 static struct hda_verb alc880_uniwill_init_verbs[] = {
1919 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1922 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1926 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1931 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1932 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1933 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1934 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1936 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1938 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1942 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1943 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1944 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1946 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1947 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1954 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1956 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1957 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1962 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1964 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1968 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1974 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1975 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1979 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1980 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1985 static struct hda_verb alc880_beep_init_verbs[] = {
1986 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1990 /* toggle speaker-output according to the hp-jack state */
1991 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1993 unsigned int present;
1996 present = snd_hda_codec_read(codec, 0x14, 0,
1997 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1998 bits = present ? HDA_AMP_MUTE : 0;
1999 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2000 HDA_AMP_MUTE, bits);
2001 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2002 HDA_AMP_MUTE, bits);
2005 /* auto-toggle front mic */
2006 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2008 unsigned int present;
2011 present = snd_hda_codec_read(codec, 0x18, 0,
2012 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2013 bits = present ? HDA_AMP_MUTE : 0;
2014 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2017 static void alc880_uniwill_automute(struct hda_codec *codec)
2019 alc880_uniwill_hp_automute(codec);
2020 alc880_uniwill_mic_automute(codec);
2023 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2026 /* Looks like the unsol event is incompatible with the standard
2027 * definition. 4bit tag is placed at 28 bit!
2029 switch (res >> 28) {
2030 case ALC880_HP_EVENT:
2031 alc880_uniwill_hp_automute(codec);
2033 case ALC880_MIC_EVENT:
2034 alc880_uniwill_mic_automute(codec);
2039 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2041 unsigned int present;
2044 present = snd_hda_codec_read(codec, 0x14, 0,
2045 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2046 bits = present ? HDA_AMP_MUTE : 0;
2047 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2050 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2052 unsigned int present;
2054 present = snd_hda_codec_read(codec, 0x21, 0,
2055 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2056 present &= HDA_AMP_VOLMASK;
2057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2058 HDA_AMP_VOLMASK, present);
2059 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2060 HDA_AMP_VOLMASK, present);
2063 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2066 /* Looks like the unsol event is incompatible with the standard
2067 * definition. 4bit tag is placed at 28 bit!
2069 if ((res >> 28) == ALC880_HP_EVENT)
2070 alc880_uniwill_p53_hp_automute(codec);
2071 if ((res >> 28) == ALC880_DCVOL_EVENT)
2072 alc880_uniwill_p53_dcvol_automute(codec);
2076 * F1734 pin configuration:
2077 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2079 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2080 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2081 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2082 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2083 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2084 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2088 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2093 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2098 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2099 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2101 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2102 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2108 * ASUS pin configuration:
2109 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2111 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2112 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2113 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2114 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2115 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2120 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2122 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2131 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2133 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2134 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2139 /* Enable GPIO mask and set output */
2140 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2141 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2143 /* Clevo m520g init */
2144 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2145 /* headphone output */
2146 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2154 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2155 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 /* Mic1 (rear panel) */
2157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2159 /* Mic2 (front panel) */
2160 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2161 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2165 /* change to EAPD mode */
2166 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2167 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2172 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2173 /* change to EAPD mode */
2174 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2175 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2177 /* Headphone output */
2178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2180 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2181 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2183 /* Line In pin widget for input */
2184 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2185 /* CD pin widget for input */
2186 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2187 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2188 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2190 /* change to EAPD mode */
2191 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2192 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2198 * LG m1 express dual
2201 * Rear Line-In/Out (blue): 0x14
2202 * Build-in Mic-In: 0x15
2204 * HP-Out (green): 0x1b
2205 * Mic-In/Out (red): 0x19
2209 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2210 static hda_nid_t alc880_lg_dac_nids[3] = {
2214 /* seems analog CD is not working */
2215 static struct hda_input_mux alc880_lg_capture_source = {
2220 { "Internal Mic", 0x6 },
2224 /* 2,4,6 channel modes */
2225 static struct hda_verb alc880_lg_ch2_init[] = {
2226 /* set line-in and mic-in to input */
2227 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2228 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2232 static struct hda_verb alc880_lg_ch4_init[] = {
2233 /* set line-in to out and mic-in to input */
2234 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2235 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2239 static struct hda_verb alc880_lg_ch6_init[] = {
2240 /* set line-in and mic-in to output */
2241 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2242 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2246 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2247 { 2, alc880_lg_ch2_init },
2248 { 4, alc880_lg_ch4_init },
2249 { 6, alc880_lg_ch6_init },
2252 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2254 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2256 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2257 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2258 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2259 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2260 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2266 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2268 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2269 .name = "Channel Mode",
2270 .info = alc_ch_mode_info,
2271 .get = alc_ch_mode_get,
2272 .put = alc_ch_mode_put,
2277 static struct hda_verb alc880_lg_init_verbs[] = {
2278 /* set capture source to mic-in */
2279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2281 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2282 /* mute all amp mixer inputs */
2283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2286 /* line-in to input */
2287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2293 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2294 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295 /* mic-in to input */
2296 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2302 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2304 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2308 /* toggle speaker-output according to the hp-jack state */
2309 static void alc880_lg_automute(struct hda_codec *codec)
2311 unsigned int present;
2314 present = snd_hda_codec_read(codec, 0x1b, 0,
2315 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2316 bits = present ? HDA_AMP_MUTE : 0;
2317 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2318 HDA_AMP_MUTE, bits);
2321 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2323 /* Looks like the unsol event is incompatible with the standard
2324 * definition. 4bit tag is placed at 28 bit!
2326 if ((res >> 28) == 0x01)
2327 alc880_lg_automute(codec);
2336 * Built-in Mic-In: 0x19
2342 static struct hda_input_mux alc880_lg_lw_capture_source = {
2346 { "Internal Mic", 0x1 },
2351 #define alc880_lg_lw_modes alc880_threestack_modes
2353 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2354 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2355 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2356 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2357 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2358 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2359 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2360 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2361 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2366 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2367 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2370 .name = "Channel Mode",
2371 .info = alc_ch_mode_info,
2372 .get = alc_ch_mode_get,
2373 .put = alc_ch_mode_put,
2378 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2379 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2380 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2381 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2383 /* set capture source to mic-in */
2384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2385 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394 /* mic-in to input */
2395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2405 /* toggle speaker-output according to the hp-jack state */
2406 static void alc880_lg_lw_automute(struct hda_codec *codec)
2408 unsigned int present;
2411 present = snd_hda_codec_read(codec, 0x1b, 0,
2412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2413 bits = present ? HDA_AMP_MUTE : 0;
2414 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2415 HDA_AMP_MUTE, bits);
2418 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2420 /* Looks like the unsol event is incompatible with the standard
2421 * definition. 4bit tag is placed at 28 bit!
2423 if ((res >> 28) == 0x01)
2424 alc880_lg_lw_automute(codec);
2427 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2428 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2429 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2433 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2437 static struct hda_input_mux alc880_medion_rim_capture_source = {
2441 { "Internal Mic", 0x1 },
2445 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2446 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2454 /* Mic2 (as headphone out) for HP output */
2455 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2456 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 /* Internal Speaker */
2458 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2459 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2461 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2462 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2464 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2468 /* toggle speaker-output according to the hp-jack state */
2469 static void alc880_medion_rim_automute(struct hda_codec *codec)
2471 unsigned int present;
2474 present = snd_hda_codec_read(codec, 0x14, 0,
2475 AC_VERB_GET_PIN_SENSE, 0)
2476 & AC_PINSENSE_PRESENCE;
2477 bits = present ? HDA_AMP_MUTE : 0;
2478 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2479 HDA_AMP_MUTE, bits);
2481 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2483 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2486 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2489 /* Looks like the unsol event is incompatible with the standard
2490 * definition. 4bit tag is placed at 28 bit!
2492 if ((res >> 28) == ALC880_HP_EVENT)
2493 alc880_medion_rim_automute(codec);
2496 #ifdef CONFIG_SND_HDA_POWER_SAVE
2497 static struct hda_amp_list alc880_loopbacks[] = {
2498 { 0x0b, HDA_INPUT, 0 },
2499 { 0x0b, HDA_INPUT, 1 },
2500 { 0x0b, HDA_INPUT, 2 },
2501 { 0x0b, HDA_INPUT, 3 },
2502 { 0x0b, HDA_INPUT, 4 },
2506 static struct hda_amp_list alc880_lg_loopbacks[] = {
2507 { 0x0b, HDA_INPUT, 1 },
2508 { 0x0b, HDA_INPUT, 6 },
2509 { 0x0b, HDA_INPUT, 7 },
2518 static int alc_init(struct hda_codec *codec)
2520 struct alc_spec *spec = codec->spec;
2524 if (codec->vendor_id == 0x10ec0888)
2525 alc888_coef_init(codec);
2527 for (i = 0; i < spec->num_init_verbs; i++)
2528 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2530 if (spec->init_hook)
2531 spec->init_hook(codec);
2536 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2538 struct alc_spec *spec = codec->spec;
2540 if (spec->unsol_event)
2541 spec->unsol_event(codec, res);
2544 #ifdef CONFIG_SND_HDA_POWER_SAVE
2545 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2547 struct alc_spec *spec = codec->spec;
2548 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2553 * Analog playback callbacks
2555 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2556 struct hda_codec *codec,
2557 struct snd_pcm_substream *substream)
2559 struct alc_spec *spec = codec->spec;
2560 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2564 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2565 struct hda_codec *codec,
2566 unsigned int stream_tag,
2567 unsigned int format,
2568 struct snd_pcm_substream *substream)
2570 struct alc_spec *spec = codec->spec;
2571 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2572 stream_tag, format, substream);
2575 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2576 struct hda_codec *codec,
2577 struct snd_pcm_substream *substream)
2579 struct alc_spec *spec = codec->spec;
2580 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2586 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2587 struct hda_codec *codec,
2588 struct snd_pcm_substream *substream)
2590 struct alc_spec *spec = codec->spec;
2591 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2594 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2595 struct hda_codec *codec,
2596 unsigned int stream_tag,
2597 unsigned int format,
2598 struct snd_pcm_substream *substream)
2600 struct alc_spec *spec = codec->spec;
2601 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2602 stream_tag, format, substream);
2605 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2606 struct hda_codec *codec,
2607 struct snd_pcm_substream *substream)
2609 struct alc_spec *spec = codec->spec;
2610 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2616 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2617 struct hda_codec *codec,
2618 unsigned int stream_tag,
2619 unsigned int format,
2620 struct snd_pcm_substream *substream)
2622 struct alc_spec *spec = codec->spec;
2624 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2625 stream_tag, 0, format);
2629 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2630 struct hda_codec *codec,
2631 struct snd_pcm_substream *substream)
2633 struct alc_spec *spec = codec->spec;
2635 snd_hda_codec_cleanup_stream(codec,
2636 spec->adc_nids[substream->number + 1]);
2643 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2647 /* NID is set in alc_build_pcms */
2649 .open = alc880_playback_pcm_open,
2650 .prepare = alc880_playback_pcm_prepare,
2651 .cleanup = alc880_playback_pcm_cleanup
2655 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2659 /* NID is set in alc_build_pcms */
2662 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2666 /* NID is set in alc_build_pcms */
2669 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2670 .substreams = 2, /* can be overridden */
2673 /* NID is set in alc_build_pcms */
2675 .prepare = alc880_alt_capture_pcm_prepare,
2676 .cleanup = alc880_alt_capture_pcm_cleanup
2680 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2684 /* NID is set in alc_build_pcms */
2686 .open = alc880_dig_playback_pcm_open,
2687 .close = alc880_dig_playback_pcm_close,
2688 .prepare = alc880_dig_playback_pcm_prepare
2692 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2696 /* NID is set in alc_build_pcms */
2699 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2700 static struct hda_pcm_stream alc_pcm_null_stream = {
2706 static int alc_build_pcms(struct hda_codec *codec)
2708 struct alc_spec *spec = codec->spec;
2709 struct hda_pcm *info = spec->pcm_rec;
2712 codec->num_pcms = 1;
2713 codec->pcm_info = info;
2715 info->name = spec->stream_name_analog;
2716 if (spec->stream_analog_playback) {
2717 if (snd_BUG_ON(!spec->multiout.dac_nids))
2719 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2720 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2722 if (spec->stream_analog_capture) {
2723 if (snd_BUG_ON(!spec->adc_nids))
2725 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2726 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2729 if (spec->channel_mode) {
2730 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2731 for (i = 0; i < spec->num_channel_mode; i++) {
2732 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2733 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2738 /* SPDIF for stream index #1 */
2739 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2740 codec->num_pcms = 2;
2741 info = spec->pcm_rec + 1;
2742 info->name = spec->stream_name_digital;
2743 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2744 if (spec->multiout.dig_out_nid &&
2745 spec->stream_digital_playback) {
2746 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2747 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2749 if (spec->dig_in_nid &&
2750 spec->stream_digital_capture) {
2751 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2752 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2754 /* FIXME: do we need this for all Realtek codec models? */
2755 codec->spdif_status_reset = 1;
2758 /* If the use of more than one ADC is requested for the current
2759 * model, configure a second analog capture-only PCM.
2761 /* Additional Analaog capture for index #2 */
2762 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2763 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2764 codec->num_pcms = 3;
2765 info = spec->pcm_rec + 2;
2766 info->name = spec->stream_name_analog;
2767 if (spec->alt_dac_nid) {
2768 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2769 *spec->stream_analog_alt_playback;
2770 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2773 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2774 alc_pcm_null_stream;
2775 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2777 if (spec->num_adc_nids > 1) {
2778 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2779 *spec->stream_analog_alt_capture;
2780 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2782 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2783 spec->num_adc_nids - 1;
2785 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2786 alc_pcm_null_stream;
2787 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2794 static void alc_free_kctls(struct hda_codec *codec)
2796 struct alc_spec *spec = codec->spec;
2798 if (spec->kctls.list) {
2799 struct snd_kcontrol_new *kctl = spec->kctls.list;
2801 for (i = 0; i < spec->kctls.used; i++)
2802 kfree(kctl[i].name);
2804 snd_array_free(&spec->kctls);
2807 static void alc_free(struct hda_codec *codec)
2809 struct alc_spec *spec = codec->spec;
2814 alc_free_kctls(codec);
2816 codec->spec = NULL; /* to be sure */
2819 #ifdef SND_HDA_NEEDS_RESUME
2820 static void store_pin_configs(struct hda_codec *codec)
2822 struct alc_spec *spec = codec->spec;
2823 hda_nid_t nid, end_nid;
2825 end_nid = codec->start_nid + codec->num_nodes;
2826 for (nid = codec->start_nid; nid < end_nid; nid++) {
2827 unsigned int wid_caps = get_wcaps(codec, nid);
2828 unsigned int wid_type =
2829 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2830 if (wid_type != AC_WID_PIN)
2832 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2834 spec->pin_nids[spec->num_pins] = nid;
2835 spec->pin_cfgs[spec->num_pins] =
2836 snd_hda_codec_read(codec, nid, 0,
2837 AC_VERB_GET_CONFIG_DEFAULT, 0);
2842 static void resume_pin_configs(struct hda_codec *codec)
2844 struct alc_spec *spec = codec->spec;
2847 for (i = 0; i < spec->num_pins; i++) {
2848 hda_nid_t pin_nid = spec->pin_nids[i];
2849 unsigned int pin_config = spec->pin_cfgs[i];
2850 snd_hda_codec_write(codec, pin_nid, 0,
2851 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2852 pin_config & 0x000000ff);
2853 snd_hda_codec_write(codec, pin_nid, 0,
2854 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2855 (pin_config & 0x0000ff00) >> 8);
2856 snd_hda_codec_write(codec, pin_nid, 0,
2857 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2858 (pin_config & 0x00ff0000) >> 16);
2859 snd_hda_codec_write(codec, pin_nid, 0,
2860 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2865 static int alc_resume(struct hda_codec *codec)
2867 resume_pin_configs(codec);
2868 codec->patch_ops.init(codec);
2869 snd_hda_codec_resume_amp(codec);
2870 snd_hda_codec_resume_cache(codec);
2874 #define store_pin_configs(codec)
2879 static struct hda_codec_ops alc_patch_ops = {
2880 .build_controls = alc_build_controls,
2881 .build_pcms = alc_build_pcms,
2884 .unsol_event = alc_unsol_event,
2885 #ifdef SND_HDA_NEEDS_RESUME
2886 .resume = alc_resume,
2888 #ifdef CONFIG_SND_HDA_POWER_SAVE
2889 .check_power_status = alc_check_power_status,
2895 * Test configuration for debugging
2897 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2900 #ifdef CONFIG_SND_DEBUG
2901 static hda_nid_t alc880_test_dac_nids[4] = {
2902 0x02, 0x03, 0x04, 0x05
2905 static struct hda_input_mux alc880_test_capture_source = {
2914 { "Surround", 0x6 },
2918 static struct hda_channel_mode alc880_test_modes[4] = {
2925 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2926 struct snd_ctl_elem_info *uinfo)
2928 static char *texts[] = {
2929 "N/A", "Line Out", "HP Out",
2930 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2932 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2934 uinfo->value.enumerated.items = 8;
2935 if (uinfo->value.enumerated.item >= 8)
2936 uinfo->value.enumerated.item = 7;
2937 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2941 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2942 struct snd_ctl_elem_value *ucontrol)
2944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2945 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2946 unsigned int pin_ctl, item = 0;
2948 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2949 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2950 if (pin_ctl & AC_PINCTL_OUT_EN) {
2951 if (pin_ctl & AC_PINCTL_HP_EN)
2955 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2956 switch (pin_ctl & AC_PINCTL_VREFEN) {
2957 case AC_PINCTL_VREF_HIZ: item = 3; break;
2958 case AC_PINCTL_VREF_50: item = 4; break;
2959 case AC_PINCTL_VREF_GRD: item = 5; break;
2960 case AC_PINCTL_VREF_80: item = 6; break;
2961 case AC_PINCTL_VREF_100: item = 7; break;
2964 ucontrol->value.enumerated.item[0] = item;
2968 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2969 struct snd_ctl_elem_value *ucontrol)
2971 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2972 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2973 static unsigned int ctls[] = {
2974 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2975 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2976 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2977 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2978 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2979 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2981 unsigned int old_ctl, new_ctl;
2983 old_ctl = snd_hda_codec_read(codec, nid, 0,
2984 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2985 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2986 if (old_ctl != new_ctl) {
2988 snd_hda_codec_write_cache(codec, nid, 0,
2989 AC_VERB_SET_PIN_WIDGET_CONTROL,
2991 val = ucontrol->value.enumerated.item[0] >= 3 ?
2993 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3000 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3001 struct snd_ctl_elem_info *uinfo)
3003 static char *texts[] = {
3004 "Front", "Surround", "CLFE", "Side"
3006 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3008 uinfo->value.enumerated.items = 4;
3009 if (uinfo->value.enumerated.item >= 4)
3010 uinfo->value.enumerated.item = 3;
3011 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3015 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3016 struct snd_ctl_elem_value *ucontrol)
3018 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3019 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3022 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3023 ucontrol->value.enumerated.item[0] = sel & 3;
3027 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3028 struct snd_ctl_elem_value *ucontrol)
3030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3031 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3034 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3035 if (ucontrol->value.enumerated.item[0] != sel) {
3036 sel = ucontrol->value.enumerated.item[0] & 3;
3037 snd_hda_codec_write_cache(codec, nid, 0,
3038 AC_VERB_SET_CONNECT_SEL, sel);
3044 #define PIN_CTL_TEST(xname,nid) { \
3045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3047 .info = alc_test_pin_ctl_info, \
3048 .get = alc_test_pin_ctl_get, \
3049 .put = alc_test_pin_ctl_put, \
3050 .private_value = nid \
3053 #define PIN_SRC_TEST(xname,nid) { \
3054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3056 .info = alc_test_pin_src_info, \
3057 .get = alc_test_pin_src_get, \
3058 .put = alc_test_pin_src_put, \
3059 .private_value = nid \
3062 static struct snd_kcontrol_new alc880_test_mixer[] = {
3063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3064 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3065 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3066 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3067 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3068 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3069 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3070 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3071 PIN_CTL_TEST("Front Pin Mode", 0x14),
3072 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3073 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3074 PIN_CTL_TEST("Side Pin Mode", 0x17),
3075 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3076 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3077 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3078 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3079 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3080 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3081 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3082 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3083 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3084 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3085 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3086 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3087 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3088 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3089 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3090 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3095 .name = "Channel Mode",
3096 .info = alc_ch_mode_info,
3097 .get = alc_ch_mode_get,
3098 .put = alc_ch_mode_put,
3103 static struct hda_verb alc880_test_init_verbs[] = {
3104 /* Unmute inputs of 0x0c - 0x0f */
3105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3111 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3113 /* Vol output for 0x0c-0x0f */
3114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3115 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3117 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3118 /* Set output pins 0x14-0x17 */
3119 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3120 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3122 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3123 /* Unmute output pins 0x14-0x17 */
3124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3128 /* Set input pins 0x18-0x1c */
3129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3133 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3134 /* Mute input pins 0x18-0x1b */
3135 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3138 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3141 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3143 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3145 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3146 /* Analog input/passthru */
3147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3159 static const char *alc880_models[ALC880_MODEL_LAST] = {
3160 [ALC880_3ST] = "3stack",
3161 [ALC880_TCL_S700] = "tcl",
3162 [ALC880_3ST_DIG] = "3stack-digout",
3163 [ALC880_CLEVO] = "clevo",
3164 [ALC880_5ST] = "5stack",
3165 [ALC880_5ST_DIG] = "5stack-digout",
3166 [ALC880_W810] = "w810",
3167 [ALC880_Z71V] = "z71v",
3168 [ALC880_6ST] = "6stack",
3169 [ALC880_6ST_DIG] = "6stack-digout",
3170 [ALC880_ASUS] = "asus",
3171 [ALC880_ASUS_W1V] = "asus-w1v",
3172 [ALC880_ASUS_DIG] = "asus-dig",
3173 [ALC880_ASUS_DIG2] = "asus-dig2",
3174 [ALC880_UNIWILL_DIG] = "uniwill",
3175 [ALC880_UNIWILL_P53] = "uniwill-p53",
3176 [ALC880_FUJITSU] = "fujitsu",
3177 [ALC880_F1734] = "F1734",
3179 [ALC880_LG_LW] = "lg-lw",
3180 [ALC880_MEDION_RIM] = "medion",
3181 #ifdef CONFIG_SND_DEBUG
3182 [ALC880_TEST] = "test",
3184 [ALC880_AUTO] = "auto",
3187 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3188 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3189 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3190 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3191 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3192 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3193 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3194 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3195 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3196 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3197 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3198 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3199 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3200 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3201 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3202 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3203 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3204 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3205 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3206 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3207 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3208 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3209 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3210 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3211 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3212 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3213 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3214 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3215 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3216 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3217 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3218 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3219 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3220 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3221 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3222 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3223 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3224 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3225 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3226 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3227 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3228 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3229 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3230 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3231 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3232 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3233 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3234 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3235 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3236 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3237 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3238 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3239 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3240 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3241 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3242 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3243 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3244 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3245 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3246 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3247 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3248 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3249 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3250 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3251 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3252 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3253 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3254 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3255 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3256 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3257 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3258 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3263 * ALC880 codec presets
3265 static struct alc_config_preset alc880_presets[] = {
3267 .mixers = { alc880_three_stack_mixer },
3268 .init_verbs = { alc880_volume_init_verbs,
3269 alc880_pin_3stack_init_verbs },
3270 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3271 .dac_nids = alc880_dac_nids,
3272 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3273 .channel_mode = alc880_threestack_modes,
3275 .input_mux = &alc880_capture_source,
3277 [ALC880_3ST_DIG] = {
3278 .mixers = { alc880_three_stack_mixer },
3279 .init_verbs = { alc880_volume_init_verbs,
3280 alc880_pin_3stack_init_verbs },
3281 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3282 .dac_nids = alc880_dac_nids,
3283 .dig_out_nid = ALC880_DIGOUT_NID,
3284 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3285 .channel_mode = alc880_threestack_modes,
3287 .input_mux = &alc880_capture_source,
3289 [ALC880_TCL_S700] = {
3290 .mixers = { alc880_tcl_s700_mixer },
3291 .init_verbs = { alc880_volume_init_verbs,
3292 alc880_pin_tcl_S700_init_verbs,
3293 alc880_gpio2_init_verbs },
3294 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3295 .dac_nids = alc880_dac_nids,
3297 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3298 .channel_mode = alc880_2_jack_modes,
3299 .input_mux = &alc880_capture_source,
3302 .mixers = { alc880_three_stack_mixer,
3303 alc880_five_stack_mixer},
3304 .init_verbs = { alc880_volume_init_verbs,
3305 alc880_pin_5stack_init_verbs },
3306 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3307 .dac_nids = alc880_dac_nids,
3308 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3309 .channel_mode = alc880_fivestack_modes,
3310 .input_mux = &alc880_capture_source,
3312 [ALC880_5ST_DIG] = {
3313 .mixers = { alc880_three_stack_mixer,
3314 alc880_five_stack_mixer },
3315 .init_verbs = { alc880_volume_init_verbs,
3316 alc880_pin_5stack_init_verbs },
3317 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3318 .dac_nids = alc880_dac_nids,
3319 .dig_out_nid = ALC880_DIGOUT_NID,
3320 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3321 .channel_mode = alc880_fivestack_modes,
3322 .input_mux = &alc880_capture_source,
3325 .mixers = { alc880_six_stack_mixer },
3326 .init_verbs = { alc880_volume_init_verbs,
3327 alc880_pin_6stack_init_verbs },
3328 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3329 .dac_nids = alc880_6st_dac_nids,
3330 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3331 .channel_mode = alc880_sixstack_modes,
3332 .input_mux = &alc880_6stack_capture_source,
3334 [ALC880_6ST_DIG] = {
3335 .mixers = { alc880_six_stack_mixer },
3336 .init_verbs = { alc880_volume_init_verbs,
3337 alc880_pin_6stack_init_verbs },
3338 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3339 .dac_nids = alc880_6st_dac_nids,
3340 .dig_out_nid = ALC880_DIGOUT_NID,
3341 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3342 .channel_mode = alc880_sixstack_modes,
3343 .input_mux = &alc880_6stack_capture_source,
3346 .mixers = { alc880_w810_base_mixer },
3347 .init_verbs = { alc880_volume_init_verbs,
3348 alc880_pin_w810_init_verbs,
3349 alc880_gpio2_init_verbs },
3350 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3351 .dac_nids = alc880_w810_dac_nids,
3352 .dig_out_nid = ALC880_DIGOUT_NID,
3353 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3354 .channel_mode = alc880_w810_modes,
3355 .input_mux = &alc880_capture_source,
3358 .mixers = { alc880_z71v_mixer },
3359 .init_verbs = { alc880_volume_init_verbs,
3360 alc880_pin_z71v_init_verbs },
3361 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3362 .dac_nids = alc880_z71v_dac_nids,
3363 .dig_out_nid = ALC880_DIGOUT_NID,
3365 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3366 .channel_mode = alc880_2_jack_modes,
3367 .input_mux = &alc880_capture_source,
3370 .mixers = { alc880_f1734_mixer },
3371 .init_verbs = { alc880_volume_init_verbs,
3372 alc880_pin_f1734_init_verbs },
3373 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3374 .dac_nids = alc880_f1734_dac_nids,
3376 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3377 .channel_mode = alc880_2_jack_modes,
3378 .input_mux = &alc880_f1734_capture_source,
3379 .unsol_event = alc880_uniwill_p53_unsol_event,
3380 .init_hook = alc880_uniwill_p53_hp_automute,
3383 .mixers = { alc880_asus_mixer },
3384 .init_verbs = { alc880_volume_init_verbs,
3385 alc880_pin_asus_init_verbs,
3386 alc880_gpio1_init_verbs },
3387 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3388 .dac_nids = alc880_asus_dac_nids,
3389 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3390 .channel_mode = alc880_asus_modes,
3392 .input_mux = &alc880_capture_source,
3394 [ALC880_ASUS_DIG] = {
3395 .mixers = { alc880_asus_mixer },
3396 .init_verbs = { alc880_volume_init_verbs,
3397 alc880_pin_asus_init_verbs,
3398 alc880_gpio1_init_verbs },
3399 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3400 .dac_nids = alc880_asus_dac_nids,
3401 .dig_out_nid = ALC880_DIGOUT_NID,
3402 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3403 .channel_mode = alc880_asus_modes,
3405 .input_mux = &alc880_capture_source,
3407 [ALC880_ASUS_DIG2] = {
3408 .mixers = { alc880_asus_mixer },
3409 .init_verbs = { alc880_volume_init_verbs,
3410 alc880_pin_asus_init_verbs,
3411 alc880_gpio2_init_verbs }, /* use GPIO2 */
3412 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3413 .dac_nids = alc880_asus_dac_nids,
3414 .dig_out_nid = ALC880_DIGOUT_NID,
3415 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3416 .channel_mode = alc880_asus_modes,
3418 .input_mux = &alc880_capture_source,
3420 [ALC880_ASUS_W1V] = {
3421 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3422 .init_verbs = { alc880_volume_init_verbs,
3423 alc880_pin_asus_init_verbs,
3424 alc880_gpio1_init_verbs },
3425 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3426 .dac_nids = alc880_asus_dac_nids,
3427 .dig_out_nid = ALC880_DIGOUT_NID,
3428 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3429 .channel_mode = alc880_asus_modes,
3431 .input_mux = &alc880_capture_source,
3433 [ALC880_UNIWILL_DIG] = {
3434 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3435 .init_verbs = { alc880_volume_init_verbs,
3436 alc880_pin_asus_init_verbs },
3437 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3438 .dac_nids = alc880_asus_dac_nids,
3439 .dig_out_nid = ALC880_DIGOUT_NID,
3440 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3441 .channel_mode = alc880_asus_modes,
3443 .input_mux = &alc880_capture_source,
3445 [ALC880_UNIWILL] = {
3446 .mixers = { alc880_uniwill_mixer },
3447 .init_verbs = { alc880_volume_init_verbs,
3448 alc880_uniwill_init_verbs },
3449 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3450 .dac_nids = alc880_asus_dac_nids,
3451 .dig_out_nid = ALC880_DIGOUT_NID,
3452 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3453 .channel_mode = alc880_threestack_modes,
3455 .input_mux = &alc880_capture_source,
3456 .unsol_event = alc880_uniwill_unsol_event,
3457 .init_hook = alc880_uniwill_automute,
3459 [ALC880_UNIWILL_P53] = {
3460 .mixers = { alc880_uniwill_p53_mixer },
3461 .init_verbs = { alc880_volume_init_verbs,
3462 alc880_uniwill_p53_init_verbs },
3463 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3464 .dac_nids = alc880_asus_dac_nids,
3465 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3466 .channel_mode = alc880_threestack_modes,
3467 .input_mux = &alc880_capture_source,
3468 .unsol_event = alc880_uniwill_p53_unsol_event,
3469 .init_hook = alc880_uniwill_p53_hp_automute,
3471 [ALC880_FUJITSU] = {
3472 .mixers = { alc880_fujitsu_mixer,
3473 alc880_pcbeep_mixer, },
3474 .init_verbs = { alc880_volume_init_verbs,
3475 alc880_uniwill_p53_init_verbs,
3476 alc880_beep_init_verbs },
3477 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3478 .dac_nids = alc880_dac_nids,
3479 .dig_out_nid = ALC880_DIGOUT_NID,
3480 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3481 .channel_mode = alc880_2_jack_modes,
3482 .input_mux = &alc880_capture_source,
3483 .unsol_event = alc880_uniwill_p53_unsol_event,
3484 .init_hook = alc880_uniwill_p53_hp_automute,
3487 .mixers = { alc880_three_stack_mixer },
3488 .init_verbs = { alc880_volume_init_verbs,
3489 alc880_pin_clevo_init_verbs },
3490 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3491 .dac_nids = alc880_dac_nids,
3493 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3494 .channel_mode = alc880_threestack_modes,
3496 .input_mux = &alc880_capture_source,
3499 .mixers = { alc880_lg_mixer },
3500 .init_verbs = { alc880_volume_init_verbs,
3501 alc880_lg_init_verbs },
3502 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3503 .dac_nids = alc880_lg_dac_nids,
3504 .dig_out_nid = ALC880_DIGOUT_NID,
3505 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3506 .channel_mode = alc880_lg_ch_modes,
3508 .input_mux = &alc880_lg_capture_source,
3509 .unsol_event = alc880_lg_unsol_event,
3510 .init_hook = alc880_lg_automute,
3511 #ifdef CONFIG_SND_HDA_POWER_SAVE
3512 .loopbacks = alc880_lg_loopbacks,
3516 .mixers = { alc880_lg_lw_mixer },
3517 .init_verbs = { alc880_volume_init_verbs,
3518 alc880_lg_lw_init_verbs },
3519 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3520 .dac_nids = alc880_dac_nids,
3521 .dig_out_nid = ALC880_DIGOUT_NID,
3522 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3523 .channel_mode = alc880_lg_lw_modes,
3524 .input_mux = &alc880_lg_lw_capture_source,
3525 .unsol_event = alc880_lg_lw_unsol_event,
3526 .init_hook = alc880_lg_lw_automute,
3528 [ALC880_MEDION_RIM] = {
3529 .mixers = { alc880_medion_rim_mixer },
3530 .init_verbs = { alc880_volume_init_verbs,
3531 alc880_medion_rim_init_verbs,
3532 alc_gpio2_init_verbs },
3533 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3534 .dac_nids = alc880_dac_nids,
3535 .dig_out_nid = ALC880_DIGOUT_NID,
3536 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3537 .channel_mode = alc880_2_jack_modes,
3538 .input_mux = &alc880_medion_rim_capture_source,
3539 .unsol_event = alc880_medion_rim_unsol_event,
3540 .init_hook = alc880_medion_rim_automute,
3542 #ifdef CONFIG_SND_DEBUG
3544 .mixers = { alc880_test_mixer },
3545 .init_verbs = { alc880_test_init_verbs },
3546 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3547 .dac_nids = alc880_test_dac_nids,
3548 .dig_out_nid = ALC880_DIGOUT_NID,
3549 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3550 .channel_mode = alc880_test_modes,
3551 .input_mux = &alc880_test_capture_source,
3557 * Automatic parse of I/O pins from the BIOS configuration
3562 ALC_CTL_WIDGET_MUTE,
3565 static struct snd_kcontrol_new alc880_control_templates[] = {
3566 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3567 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3568 HDA_BIND_MUTE(NULL, 0, 0, 0),
3571 /* add dynamic controls */
3572 static int add_control(struct alc_spec *spec, int type, const char *name,
3575 struct snd_kcontrol_new *knew;
3577 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3578 knew = snd_array_new(&spec->kctls);
3581 *knew = alc880_control_templates[type];
3582 knew->name = kstrdup(name, GFP_KERNEL);
3585 knew->private_value = val;
3589 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3590 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3591 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3592 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3593 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3594 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3595 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3596 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3597 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3598 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3599 #define ALC880_PIN_CD_NID 0x1c
3601 /* fill in the dac_nids table from the parsed pin configuration */
3602 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3603 const struct auto_pin_cfg *cfg)
3609 memset(assigned, 0, sizeof(assigned));
3610 spec->multiout.dac_nids = spec->private_dac_nids;
3612 /* check the pins hardwired to audio widget */
3613 for (i = 0; i < cfg->line_outs; i++) {
3614 nid = cfg->line_out_pins[i];
3615 if (alc880_is_fixed_pin(nid)) {
3616 int idx = alc880_fixed_pin_idx(nid);
3617 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3621 /* left pins can be connect to any audio widget */
3622 for (i = 0; i < cfg->line_outs; i++) {
3623 nid = cfg->line_out_pins[i];
3624 if (alc880_is_fixed_pin(nid))
3626 /* search for an empty channel */
3627 for (j = 0; j < cfg->line_outs; j++) {
3629 spec->multiout.dac_nids[i] =
3630 alc880_idx_to_dac(j);
3636 spec->multiout.num_dacs = cfg->line_outs;
3640 /* add playback controls from the parsed DAC table */
3641 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3642 const struct auto_pin_cfg *cfg)
3645 static const char *chname[4] = {
3646 "Front", "Surround", NULL /*CLFE*/, "Side"
3651 for (i = 0; i < cfg->line_outs; i++) {
3652 if (!spec->multiout.dac_nids[i])
3654 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3657 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3658 "Center Playback Volume",
3659 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3663 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3664 "LFE Playback Volume",
3665 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3669 err = add_control(spec, ALC_CTL_BIND_MUTE,
3670 "Center Playback Switch",
3671 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3675 err = add_control(spec, ALC_CTL_BIND_MUTE,
3676 "LFE Playback Switch",
3677 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3682 sprintf(name, "%s Playback Volume", chname[i]);
3683 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3684 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3688 sprintf(name, "%s Playback Switch", chname[i]);
3689 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3690 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3699 /* add playback controls for speaker and HP outputs */
3700 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3710 if (alc880_is_fixed_pin(pin)) {
3711 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3712 /* specify the DAC as the extra output */
3713 if (!spec->multiout.hp_nid)
3714 spec->multiout.hp_nid = nid;
3716 spec->multiout.extra_out_nid[0] = nid;
3717 /* control HP volume/switch on the output mixer amp */
3718 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3719 sprintf(name, "%s Playback Volume", pfx);
3720 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3721 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3724 sprintf(name, "%s Playback Switch", pfx);
3725 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3726 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3729 } else if (alc880_is_multi_pin(pin)) {
3730 /* set manual connection */
3731 /* we have only a switch on HP-out PIN */
3732 sprintf(name, "%s Playback Switch", pfx);
3733 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3734 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3741 /* create input playback/capture controls for the given pin */
3742 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3743 const char *ctlname,
3744 int idx, hda_nid_t mix_nid)
3749 sprintf(name, "%s Playback Volume", ctlname);
3750 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3751 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3754 sprintf(name, "%s Playback Switch", ctlname);
3755 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3756 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3762 /* create playback/capture controls for input pins */
3763 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3764 const struct auto_pin_cfg *cfg)
3766 struct hda_input_mux *imux = &spec->private_imux;
3769 for (i = 0; i < AUTO_PIN_LAST; i++) {
3770 if (alc880_is_input_pin(cfg->input_pins[i])) {
3771 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3772 err = new_analog_input(spec, cfg->input_pins[i],
3773 auto_pin_cfg_labels[i],
3777 imux->items[imux->num_items].label =
3778 auto_pin_cfg_labels[i];
3779 imux->items[imux->num_items].index =
3780 alc880_input_pin_idx(cfg->input_pins[i]);
3787 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3788 unsigned int pin_type)
3790 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3793 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3797 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3798 hda_nid_t nid, int pin_type,
3801 alc_set_pin_output(codec, nid, pin_type);
3802 /* need the manual connection? */
3803 if (alc880_is_multi_pin(nid)) {
3804 struct alc_spec *spec = codec->spec;
3805 int idx = alc880_multi_pin_idx(nid);
3806 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3807 AC_VERB_SET_CONNECT_SEL,
3808 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3812 static int get_pin_type(int line_out_type)
3814 if (line_out_type == AUTO_PIN_HP_OUT)
3820 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3822 struct alc_spec *spec = codec->spec;
3825 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3826 for (i = 0; i < spec->autocfg.line_outs; i++) {
3827 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3828 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3829 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3833 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3835 struct alc_spec *spec = codec->spec;
3838 pin = spec->autocfg.speaker_pins[0];
3839 if (pin) /* connect to front */
3840 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3841 pin = spec->autocfg.hp_pins[0];
3842 if (pin) /* connect to front */
3843 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3846 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3848 struct alc_spec *spec = codec->spec;
3851 for (i = 0; i < AUTO_PIN_LAST; i++) {
3852 hda_nid_t nid = spec->autocfg.input_pins[i];
3853 if (alc880_is_input_pin(nid)) {
3854 snd_hda_codec_write(codec, nid, 0,
3855 AC_VERB_SET_PIN_WIDGET_CONTROL,
3856 i <= AUTO_PIN_FRONT_MIC ?
3857 PIN_VREF80 : PIN_IN);
3858 if (nid != ALC880_PIN_CD_NID)
3859 snd_hda_codec_write(codec, nid, 0,
3860 AC_VERB_SET_AMP_GAIN_MUTE,
3866 /* parse the BIOS configuration and set up the alc_spec */
3867 /* return 1 if successful, 0 if the proper config is not found,
3868 * or a negative error code
3870 static int alc880_parse_auto_config(struct hda_codec *codec)
3872 struct alc_spec *spec = codec->spec;
3874 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3876 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3880 if (!spec->autocfg.line_outs)
3881 return 0; /* can't find valid BIOS pin config */
3883 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3886 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3889 err = alc880_auto_create_extra_out(spec,
3890 spec->autocfg.speaker_pins[0],
3894 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3898 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3902 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3904 if (spec->autocfg.dig_out_pin)
3905 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3906 if (spec->autocfg.dig_in_pin)
3907 spec->dig_in_nid = ALC880_DIGIN_NID;
3909 if (spec->kctls.list)
3910 add_mixer(spec, spec->kctls.list);
3912 add_verb(spec, alc880_volume_init_verbs);
3914 spec->num_mux_defs = 1;
3915 spec->input_mux = &spec->private_imux;
3917 store_pin_configs(codec);
3921 /* additional initialization for auto-configuration model */
3922 static void alc880_auto_init(struct hda_codec *codec)
3924 struct alc_spec *spec = codec->spec;
3925 alc880_auto_init_multi_out(codec);
3926 alc880_auto_init_extra_out(codec);
3927 alc880_auto_init_analog_input(codec);
3928 if (spec->unsol_event)
3929 alc_inithook(codec);
3933 * OK, here we have finally the patch for ALC880
3936 static int patch_alc880(struct hda_codec *codec)
3938 struct alc_spec *spec;
3942 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3948 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3951 if (board_config < 0) {
3952 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3953 "trying auto-probe from BIOS...\n");
3954 board_config = ALC880_AUTO;
3957 if (board_config == ALC880_AUTO) {
3958 /* automatic parse from the BIOS config */
3959 err = alc880_parse_auto_config(codec);
3965 "hda_codec: Cannot set up configuration "
3966 "from BIOS. Using 3-stack mode...\n");
3967 board_config = ALC880_3ST;
3971 if (board_config != ALC880_AUTO)
3972 setup_preset(spec, &alc880_presets[board_config]);
3974 spec->stream_name_analog = "ALC880 Analog";
3975 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3976 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3977 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3979 spec->stream_name_digital = "ALC880 Digital";
3980 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3981 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3983 if (!spec->adc_nids && spec->input_mux) {
3984 /* check whether NID 0x07 is valid */
3985 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3987 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3988 if (wcap != AC_WID_AUD_IN) {
3989 spec->adc_nids = alc880_adc_nids_alt;
3990 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3991 add_mixer(spec, alc880_capture_alt_mixer);
3993 spec->adc_nids = alc880_adc_nids;
3994 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3995 add_mixer(spec, alc880_capture_mixer);
3999 spec->vmaster_nid = 0x0c;
4001 codec->patch_ops = alc_patch_ops;
4002 if (board_config == ALC880_AUTO)
4003 spec->init_hook = alc880_auto_init;
4004 #ifdef CONFIG_SND_HDA_POWER_SAVE
4005 if (!spec->loopback.amplist)
4006 spec->loopback.amplist = alc880_loopbacks;
4017 static hda_nid_t alc260_dac_nids[1] = {
4022 static hda_nid_t alc260_adc_nids[1] = {
4027 static hda_nid_t alc260_adc_nids_alt[1] = {
4032 static hda_nid_t alc260_hp_adc_nids[2] = {
4037 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4038 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4040 static hda_nid_t alc260_dual_adc_nids[2] = {
4045 #define ALC260_DIGOUT_NID 0x03
4046 #define ALC260_DIGIN_NID 0x06
4048 static struct hda_input_mux alc260_capture_source = {
4052 { "Front Mic", 0x1 },
4058 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4059 * headphone jack and the internal CD lines since these are the only pins at
4060 * which audio can appear. For flexibility, also allow the option of
4061 * recording the mixer output on the second ADC (ADC0 doesn't have a
4062 * connection to the mixer output).
4064 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4068 { "Mic/Line", 0x0 },
4070 { "Headphone", 0x2 },
4076 { "Mic/Line", 0x0 },
4078 { "Headphone", 0x2 },
4085 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4086 * the Fujitsu S702x, but jacks are marked differently.
4088 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4095 { "Headphone", 0x5 },
4104 { "Headphone", 0x6 },
4110 * This is just place-holder, so there's something for alc_build_pcms to look
4111 * at when it calculates the maximum number of channels. ALC260 has no mixer
4112 * element which allows changing the channel mode, so the verb list is
4115 static struct hda_channel_mode alc260_modes[1] = {
4120 /* Mixer combinations
4122 * basic: base_output + input + pc_beep + capture
4123 * HP: base_output + input + capture_alt
4124 * HP_3013: hp_3013 + input + capture
4125 * fujitsu: fujitsu + capture
4126 * acer: acer + capture
4129 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4130 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4131 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4133 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4134 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4135 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4139 static struct snd_kcontrol_new alc260_input_mixer[] = {
4140 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4141 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4142 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4143 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4145 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4151 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4152 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4153 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4157 /* update HP, line and mono out pins according to the master switch */
4158 static void alc260_hp_master_update(struct hda_codec *codec,
4159 hda_nid_t hp, hda_nid_t line,
4162 struct alc_spec *spec = codec->spec;
4163 unsigned int val = spec->master_sw ? PIN_HP : 0;
4164 /* change HP and line-out pins */
4165 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4167 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4169 /* mono (speaker) depending on the HP jack sense */
4170 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4171 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4175 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4176 struct snd_ctl_elem_value *ucontrol)
4178 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4179 struct alc_spec *spec = codec->spec;
4180 *ucontrol->value.integer.value = spec->master_sw;
4184 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4185 struct snd_ctl_elem_value *ucontrol)
4187 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4188 struct alc_spec *spec = codec->spec;
4189 int val = !!*ucontrol->value.integer.value;
4190 hda_nid_t hp, line, mono;
4192 if (val == spec->master_sw)
4194 spec->master_sw = val;
4195 hp = (kcontrol->private_value >> 16) & 0xff;
4196 line = (kcontrol->private_value >> 8) & 0xff;
4197 mono = kcontrol->private_value & 0xff;
4198 alc260_hp_master_update(codec, hp, line, mono);
4202 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4205 .name = "Master Playback Switch",
4206 .info = snd_ctl_boolean_mono_info,
4207 .get = alc260_hp_master_sw_get,
4208 .put = alc260_hp_master_sw_put,
4209 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4221 static struct hda_verb alc260_hp_unsol_verbs[] = {
4222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4226 static void alc260_hp_automute(struct hda_codec *codec)
4228 struct alc_spec *spec = codec->spec;
4229 unsigned int present;
4231 present = snd_hda_codec_read(codec, 0x10, 0,
4232 AC_VERB_GET_PIN_SENSE, 0);
4233 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4234 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4237 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4239 if ((res >> 26) == ALC880_HP_EVENT)
4240 alc260_hp_automute(codec);
4243 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4246 .name = "Master Playback Switch",
4247 .info = snd_ctl_boolean_mono_info,
4248 .get = alc260_hp_master_sw_get,
4249 .put = alc260_hp_master_sw_put,
4250 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4252 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4253 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4254 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4255 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4256 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4257 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4258 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4259 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4263 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4264 .ops = &snd_hda_bind_vol,
4266 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4267 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4268 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4273 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4274 .ops = &snd_hda_bind_sw,
4276 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4277 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4282 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4283 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4284 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4290 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4295 static void alc260_hp_3013_automute(struct hda_codec *codec)
4297 struct alc_spec *spec = codec->spec;
4298 unsigned int present;
4300 present = snd_hda_codec_read(codec, 0x15, 0,
4301 AC_VERB_GET_PIN_SENSE, 0);
4302 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4303 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4306 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4309 if ((res >> 26) == ALC880_HP_EVENT)
4310 alc260_hp_3013_automute(codec);
4313 static void alc260_hp_3012_automute(struct hda_codec *codec)
4315 unsigned int present, bits;
4317 present = snd_hda_codec_read(codec, 0x10, 0,
4318 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4320 bits = present ? 0 : PIN_OUT;
4321 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4323 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4325 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4329 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4332 if ((res >> 26) == ALC880_HP_EVENT)
4333 alc260_hp_3012_automute(codec);
4336 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4337 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4339 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4341 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4342 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4343 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4344 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4345 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4346 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4347 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4348 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4349 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4350 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4351 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4355 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4356 * versions of the ALC260 don't act on requests to enable mic bias from NID
4357 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4358 * datasheet doesn't mention this restriction. At this stage it's not clear
4359 * whether this behaviour is intentional or is a hardware bug in chip
4360 * revisions available in early 2006. Therefore for now allow the
4361 * "Headphone Jack Mode" control to span all choices, but if it turns out
4362 * that the lack of mic bias for this NID is intentional we could change the
4363 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4365 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4366 * don't appear to make the mic bias available from the "line" jack, even
4367 * though the NID used for this jack (0x14) can supply it. The theory is
4368 * that perhaps Acer have included blocking capacitors between the ALC260
4369 * and the output jack. If this turns out to be the case for all such
4370 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4371 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4373 * The C20x Tablet series have a mono internal speaker which is controlled
4374 * via the chip's Mono sum widget and pin complex, so include the necessary
4375 * controls for such models. On models without a "mono speaker" the control
4376 * won't do anything.
4378 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4379 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4380 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4381 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4382 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4384 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4386 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4387 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4389 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4390 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4391 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4392 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4393 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4394 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4395 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4399 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4400 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4402 static struct snd_kcontrol_new alc260_will_mixer[] = {
4403 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4404 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4406 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4407 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4408 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4409 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4410 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4411 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4412 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4413 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4414 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4418 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4419 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4421 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4422 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4423 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4425 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4426 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4427 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4428 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4429 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4430 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4431 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4435 /* capture mixer elements */
4436 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4437 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4438 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4439 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4440 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4443 /* The multiple "Capture Source" controls confuse alsamixer
4444 * So call somewhat different..
4446 /* .name = "Capture Source", */
4447 .name = "Input Source",
4449 .info = alc_mux_enum_info,
4450 .get = alc_mux_enum_get,
4451 .put = alc_mux_enum_put,
4456 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4457 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4458 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4461 /* The multiple "Capture Source" controls confuse alsamixer
4462 * So call somewhat different..
4464 /* .name = "Capture Source", */
4465 .name = "Input Source",
4467 .info = alc_mux_enum_info,
4468 .get = alc_mux_enum_get,
4469 .put = alc_mux_enum_put,
4475 * initialization verbs
4477 static struct hda_verb alc260_init_verbs[] = {
4478 /* Line In pin widget for input */
4479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4480 /* CD pin widget for input */
4481 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4482 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4483 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4484 /* Mic2 (front panel) pin widget for input and vref at 80% */
4485 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4486 /* LINE-2 is used for line-out in rear */
4487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4488 /* select line-out */
4489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4491 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4495 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4496 /* mute capture amp left and right */
4497 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4498 /* set connection select to line in (default select for this ADC) */
4499 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4500 /* mute capture amp left and right */
4501 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4502 /* set connection select to line in (default select for this ADC) */
4503 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4504 /* set vol=0 Line-Out mixer amp left and right */
4505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4506 /* unmute pin widget amp left and right (no gain on this amp) */
4507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4508 /* set vol=0 HP mixer amp left and right */
4509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4510 /* unmute pin widget amp left and right (no gain on this amp) */
4511 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4512 /* set vol=0 Mono mixer amp left and right */
4513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4514 /* unmute pin widget amp left and right (no gain on this amp) */
4515 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4516 /* unmute LINE-2 out pin */
4517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4518 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4521 /* mute analog inputs */
4522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4527 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4528 /* mute Front out path */
4529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4531 /* mute Headphone out path */
4532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4534 /* mute Mono out path */
4535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4540 #if 0 /* should be identical with alc260_init_verbs? */
4541 static struct hda_verb alc260_hp_init_verbs[] = {
4542 /* Headphone and output */
4543 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4545 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4546 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4547 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4548 /* Mic2 (front panel) pin widget for input and vref at 80% */
4549 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4550 /* Line In pin widget for input */
4551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4552 /* Line-2 pin widget for output */
4553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4554 /* CD pin widget for input */
4555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4556 /* unmute amp left and right */
4557 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4558 /* set connection select to line in (default select for this ADC) */
4559 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4560 /* unmute Line-Out mixer amp left and right (volume = 0) */
4561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4562 /* mute pin widget amp left and right (no gain on this amp) */
4563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4564 /* unmute HP mixer amp left and right (volume = 0) */
4565 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4566 /* mute pin widget amp left and right (no gain on this amp) */
4567 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4568 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4571 /* mute analog inputs */
4572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4577 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4578 /* Unmute Front out path */
4579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4581 /* Unmute Headphone out path */
4582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4584 /* Unmute Mono out path */
4585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4591 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4592 /* Line out and output */
4593 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4595 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4596 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4597 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4598 /* Mic2 (front panel) pin widget for input and vref at 80% */
4599 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4600 /* Line In pin widget for input */
4601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4602 /* Headphone pin widget for output */
4603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4604 /* CD pin widget for input */
4605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4606 /* unmute amp left and right */
4607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4608 /* set connection select to line in (default select for this ADC) */
4609 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4610 /* unmute Line-Out mixer amp left and right (volume = 0) */
4611 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4612 /* mute pin widget amp left and right (no gain on this amp) */
4613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4614 /* unmute HP mixer amp left and right (volume = 0) */
4615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4616 /* mute pin widget amp left and right (no gain on this amp) */
4617 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4618 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4621 /* mute analog inputs */
4622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4627 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4628 /* Unmute Front out path */
4629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4630 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4631 /* Unmute Headphone out path */
4632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4634 /* Unmute Mono out path */
4635 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4636 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4640 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4641 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4642 * audio = 0x16, internal speaker = 0x10.
4644 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4645 /* Disable all GPIOs */
4646 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4647 /* Internal speaker is connected to headphone pin */
4648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4649 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4651 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4652 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4653 /* Ensure all other unused pins are disabled and muted. */
4654 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4656 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4657 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4658 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4661 {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 Line1 pin widget takes its input from the OUT1 sum bus
4668 * when acting as an output.
4670 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4672 /* Start with output sum widgets muted and their output gains at min */
4673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4676 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4679 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4680 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4681 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4683 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4685 /* Unmute Line1 pin widget output buffer since it starts as an output.
4686 * If the pin mode is changed by the user the pin mode control will
4687 * take care of enabling the pin's input/output buffers as needed.
4688 * Therefore there's no need to enable the input buffer at this
4691 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4692 /* Unmute input buffer of pin widget used for Line-in (no equiv
4695 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4697 /* Mute capture amp left and right */
4698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4699 /* Set ADC connection select to match default mixer setting - line
4702 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4704 /* Do the same for the second ADC: mute capture input amp and
4705 * set ADC connection to line in (on mic1 pin)
4707 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4708 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4710 /* Mute all inputs to mixer widget (even unconnected ones) */
4711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4723 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4724 * similar laptops (adapted from Fujitsu init verbs).
4726 static struct hda_verb alc260_acer_init_verbs[] = {
4727 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4728 * the headphone jack. Turn this on and rely on the standard mute
4729 * methods whenever the user wants to turn these outputs off.
4731 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4732 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4733 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4734 /* Internal speaker/Headphone jack is connected to Line-out pin */
4735 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4736 /* Internal microphone/Mic jack is connected to Mic1 pin */
4737 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4738 /* Line In jack is connected to Line1 pin */
4739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4740 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4741 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4742 /* Ensure all other unused pins are disabled and muted. */
4743 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4744 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4745 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4746 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4749 /* Disable digital (SPDIF) pins */
4750 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4751 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4753 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4754 * bus when acting as outputs.
4756 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4757 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4759 /* Start with output sum widgets muted and their output gains at min */
4760 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4762 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4763 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4764 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4765 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4766 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4767 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4768 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4770 /* Unmute Line-out pin widget amp left and right
4771 * (no equiv mixer ctrl)
4773 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4774 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4775 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4776 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4777 * inputs. If the pin mode is changed by the user the pin mode control
4778 * will take care of enabling the pin's input/output buffers as needed.
4779 * Therefore there's no need to enable the input buffer at this
4782 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4785 /* Mute capture amp left and right */
4786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4787 /* Set ADC connection select to match default mixer setting - mic
4790 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4792 /* Do similar with the second ADC: mute capture input amp and
4793 * set ADC connection to mic to match ALSA's default state.
4795 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4796 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4798 /* Mute all inputs to mixer widget (even unconnected ones) */
4799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4802 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4803 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4805 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4811 static struct hda_verb alc260_will_verbs[] = {
4812 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4813 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4814 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4815 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4816 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4817 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4821 static struct hda_verb alc260_replacer_672v_verbs[] = {
4822 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4823 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4824 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4826 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4827 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4828 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4830 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4834 /* toggle speaker-output according to the hp-jack state */
4835 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4837 unsigned int present;
4839 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4840 present = snd_hda_codec_read(codec, 0x0f, 0,
4841 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4843 snd_hda_codec_write_cache(codec, 0x01, 0,
4844 AC_VERB_SET_GPIO_DATA, 1);
4845 snd_hda_codec_write_cache(codec, 0x0f, 0,
4846 AC_VERB_SET_PIN_WIDGET_CONTROL,
4849 snd_hda_codec_write_cache(codec, 0x01, 0,
4850 AC_VERB_SET_GPIO_DATA, 0);
4851 snd_hda_codec_write_cache(codec, 0x0f, 0,
4852 AC_VERB_SET_PIN_WIDGET_CONTROL,
4857 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4860 if ((res >> 26) == ALC880_HP_EVENT)
4861 alc260_replacer_672v_automute(codec);
4864 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4865 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4867 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4868 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4869 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4871 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4872 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4873 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4878 /* Test configuration for debugging, modelled after the ALC880 test
4881 #ifdef CONFIG_SND_DEBUG
4882 static hda_nid_t alc260_test_dac_nids[1] = {
4885 static hda_nid_t alc260_test_adc_nids[2] = {
4888 /* For testing the ALC260, each input MUX needs its own definition since
4889 * the signal assignments are different. This assumes that the first ADC
4892 static struct hda_input_mux alc260_test_capture_sources[2] = {
4896 { "MIC1 pin", 0x0 },
4897 { "MIC2 pin", 0x1 },
4898 { "LINE1 pin", 0x2 },
4899 { "LINE2 pin", 0x3 },
4901 { "LINE-OUT pin", 0x5 },
4902 { "HP-OUT pin", 0x6 },
4908 { "MIC1 pin", 0x0 },
4909 { "MIC2 pin", 0x1 },
4910 { "LINE1 pin", 0x2 },
4911 { "LINE2 pin", 0x3 },
4914 { "LINE-OUT pin", 0x6 },
4915 { "HP-OUT pin", 0x7 },
4919 static struct snd_kcontrol_new alc260_test_mixer[] = {
4920 /* Output driver widgets */
4921 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4922 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4923 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4924 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4925 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4926 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4928 /* Modes for retasking pin widgets
4929 * Note: the ALC260 doesn't seem to act on requests to enable mic
4930 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4931 * mention this restriction. At this stage it's not clear whether
4932 * this behaviour is intentional or is a hardware bug in chip
4933 * revisions available at least up until early 2006. Therefore for
4934 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4935 * choices, but if it turns out that the lack of mic bias for these
4936 * NIDs is intentional we could change their modes from
4937 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4939 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4940 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4941 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4942 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4943 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4944 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4946 /* Loopback mixer controls */
4947 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4948 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4949 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4950 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4951 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4952 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4953 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4954 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4955 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4956 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4957 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4958 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4959 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4960 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4961 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4962 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4964 /* Controls for GPIO pins, assuming they are configured as outputs */
4965 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4966 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4967 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4968 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4970 /* Switches to allow the digital IO pins to be enabled. The datasheet
4971 * is ambigious as to which NID is which; testing on laptops which
4972 * make this output available should provide clarification.
4974 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4975 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4977 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4978 * this output to turn on an external amplifier.
4980 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4981 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4985 static struct hda_verb alc260_test_init_verbs[] = {
4986 /* Enable all GPIOs as outputs with an initial value of 0 */
4987 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4988 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4989 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4991 /* Enable retasking pins as output, initially without power amp */
4992 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4993 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4996 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4997 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4999 /* Disable digital (SPDIF) pins initially, but users can enable
5000 * them via a mixer switch. In the case of SPDIF-out, this initverb
5001 * payload also sets the generation to 0, output to be in "consumer"
5002 * PCM format, copyright asserted, no pre-emphasis and no validity
5005 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5006 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5008 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5009 * OUT1 sum bus when acting as an output.
5011 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5012 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5013 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5014 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5016 /* Start with output sum widgets muted and their output gains at min */
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5025 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5027 /* Unmute retasking pin widget output buffers since the default
5028 * state appears to be output. As the pin mode is changed by the
5029 * user the pin mode control will take care of enabling the pin's
5030 * input/output buffers as needed.
5032 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5033 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5035 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5036 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5037 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5038 /* Also unmute the mono-out pin widget */
5039 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5041 /* Mute capture amp left and right */
5042 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5043 /* Set ADC connection select to match default mixer setting (mic1
5046 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5048 /* Do the same for the second ADC: mute capture input amp and
5049 * set ADC connection to mic1 pin
5051 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5052 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5054 /* Mute all inputs to mixer widget (even unconnected ones) */
5055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5068 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5069 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5071 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5072 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5075 * for BIOS auto-configuration
5078 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5079 const char *pfx, int *vol_bits)
5082 unsigned long vol_val, sw_val;
5086 if (nid >= 0x0f && nid < 0x11) {
5087 nid_vol = nid - 0x7;
5088 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5089 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5090 } else if (nid == 0x11) {
5091 nid_vol = nid - 0x7;
5092 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5093 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5094 } else if (nid >= 0x12 && nid <= 0x15) {
5096 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5097 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5101 if (!(*vol_bits & (1 << nid_vol))) {
5102 /* first control for the volume widget */
5103 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5104 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5107 *vol_bits |= (1 << nid_vol);
5109 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5110 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5116 /* add playback controls from the parsed DAC table */
5117 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5118 const struct auto_pin_cfg *cfg)
5124 spec->multiout.num_dacs = 1;
5125 spec->multiout.dac_nids = spec->private_dac_nids;
5126 spec->multiout.dac_nids[0] = 0x02;
5128 nid = cfg->line_out_pins[0];
5130 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5135 nid = cfg->speaker_pins[0];
5137 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5142 nid = cfg->hp_pins[0];
5144 err = alc260_add_playback_controls(spec, nid, "Headphone",
5152 /* create playback/capture controls for input pins */
5153 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5154 const struct auto_pin_cfg *cfg)
5156 struct hda_input_mux *imux = &spec->private_imux;
5159 for (i = 0; i < AUTO_PIN_LAST; i++) {
5160 if (cfg->input_pins[i] >= 0x12) {
5161 idx = cfg->input_pins[i] - 0x12;
5162 err = new_analog_input(spec, cfg->input_pins[i],
5163 auto_pin_cfg_labels[i], idx,
5167 imux->items[imux->num_items].label =
5168 auto_pin_cfg_labels[i];
5169 imux->items[imux->num_items].index = idx;
5172 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5173 idx = cfg->input_pins[i] - 0x09;
5174 err = new_analog_input(spec, cfg->input_pins[i],
5175 auto_pin_cfg_labels[i], idx,
5179 imux->items[imux->num_items].label =
5180 auto_pin_cfg_labels[i];
5181 imux->items[imux->num_items].index = idx;
5188 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5189 hda_nid_t nid, int pin_type,
5192 alc_set_pin_output(codec, nid, pin_type);
5193 /* need the manual connection? */
5195 int idx = nid - 0x12;
5196 snd_hda_codec_write(codec, idx + 0x0b, 0,
5197 AC_VERB_SET_CONNECT_SEL, sel_idx);
5201 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5203 struct alc_spec *spec = codec->spec;
5206 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5207 nid = spec->autocfg.line_out_pins[0];
5209 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5210 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5213 nid = spec->autocfg.speaker_pins[0];
5215 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5217 nid = spec->autocfg.hp_pins[0];
5219 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5222 #define ALC260_PIN_CD_NID 0x16
5223 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5225 struct alc_spec *spec = codec->spec;
5228 for (i = 0; i < AUTO_PIN_LAST; i++) {
5229 hda_nid_t nid = spec->autocfg.input_pins[i];
5231 snd_hda_codec_write(codec, nid, 0,
5232 AC_VERB_SET_PIN_WIDGET_CONTROL,
5233 i <= AUTO_PIN_FRONT_MIC ?
5234 PIN_VREF80 : PIN_IN);
5235 if (nid != ALC260_PIN_CD_NID)
5236 snd_hda_codec_write(codec, nid, 0,
5237 AC_VERB_SET_AMP_GAIN_MUTE,
5244 * generic initialization of ADC, input mixers and output mixers
5246 static struct hda_verb alc260_volume_init_verbs[] = {
5248 * Unmute ADC0-1 and set the default input to mic-in
5250 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5251 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5252 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5253 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5255 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5257 * Note: PASD motherboards uses the Line In 2 as the input for
5258 * front panel mic (mic 2)
5260 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5261 /* mute analog inputs */
5262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5269 * Set up output mixers (0x08 - 0x0a)
5271 /* set vol=0 to output mixers */
5272 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5274 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5275 /* set up input amps for analog loopback */
5276 /* Amp Indices: DAC = 0, mixer = 1 */
5277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5278 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5281 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5282 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5287 static int alc260_parse_auto_config(struct hda_codec *codec)
5289 struct alc_spec *spec = codec->spec;
5292 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5298 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5301 if (!spec->kctls.list)
5302 return 0; /* can't find valid BIOS pin config */
5303 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5307 spec->multiout.max_channels = 2;
5309 if (spec->autocfg.dig_out_pin)
5310 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5311 if (spec->kctls.list)
5312 add_mixer(spec, spec->kctls.list);
5314 add_verb(spec, alc260_volume_init_verbs);
5316 spec->num_mux_defs = 1;
5317 spec->input_mux = &spec->private_imux;
5319 /* check whether NID 0x04 is valid */
5320 wcap = get_wcaps(codec, 0x04);
5321 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5322 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5323 spec->adc_nids = alc260_adc_nids_alt;
5324 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5325 add_mixer(spec, alc260_capture_alt_mixer);
5327 spec->adc_nids = alc260_adc_nids;
5328 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5329 add_mixer(spec, alc260_capture_mixer);
5332 store_pin_configs(codec);
5336 /* additional initialization for auto-configuration model */
5337 static void alc260_auto_init(struct hda_codec *codec)
5339 struct alc_spec *spec = codec->spec;
5340 alc260_auto_init_multi_out(codec);
5341 alc260_auto_init_analog_input(codec);
5342 if (spec->unsol_event)
5343 alc_inithook(codec);
5346 #ifdef CONFIG_SND_HDA_POWER_SAVE
5347 static struct hda_amp_list alc260_loopbacks[] = {
5348 { 0x07, HDA_INPUT, 0 },
5349 { 0x07, HDA_INPUT, 1 },
5350 { 0x07, HDA_INPUT, 2 },
5351 { 0x07, HDA_INPUT, 3 },
5352 { 0x07, HDA_INPUT, 4 },
5358 * ALC260 configurations
5360 static const char *alc260_models[ALC260_MODEL_LAST] = {
5361 [ALC260_BASIC] = "basic",
5363 [ALC260_HP_3013] = "hp-3013",
5364 [ALC260_HP_DC7600] = "hp-dc7600",
5365 [ALC260_FUJITSU_S702X] = "fujitsu",
5366 [ALC260_ACER] = "acer",
5367 [ALC260_WILL] = "will",
5368 [ALC260_REPLACER_672V] = "replacer",
5369 #ifdef CONFIG_SND_DEBUG
5370 [ALC260_TEST] = "test",
5372 [ALC260_AUTO] = "auto",
5375 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5376 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5377 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5378 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5379 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5380 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5381 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5382 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5383 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5384 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5385 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5386 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5387 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5388 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5389 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5390 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5391 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5392 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5393 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5397 static struct alc_config_preset alc260_presets[] = {
5399 .mixers = { alc260_base_output_mixer,
5401 alc260_pc_beep_mixer,
5402 alc260_capture_mixer },
5403 .init_verbs = { alc260_init_verbs },
5404 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5405 .dac_nids = alc260_dac_nids,
5406 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5407 .adc_nids = alc260_adc_nids,
5408 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5409 .channel_mode = alc260_modes,
5410 .input_mux = &alc260_capture_source,
5413 .mixers = { alc260_hp_output_mixer,
5415 alc260_capture_alt_mixer },
5416 .init_verbs = { alc260_init_verbs,
5417 alc260_hp_unsol_verbs },
5418 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5419 .dac_nids = alc260_dac_nids,
5420 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5421 .adc_nids = alc260_hp_adc_nids,
5422 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5423 .channel_mode = alc260_modes,
5424 .input_mux = &alc260_capture_source,
5425 .unsol_event = alc260_hp_unsol_event,
5426 .init_hook = alc260_hp_automute,
5428 [ALC260_HP_DC7600] = {
5429 .mixers = { alc260_hp_dc7600_mixer,
5431 alc260_capture_alt_mixer },
5432 .init_verbs = { alc260_init_verbs,
5433 alc260_hp_dc7600_verbs },
5434 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5435 .dac_nids = alc260_dac_nids,
5436 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5437 .adc_nids = alc260_hp_adc_nids,
5438 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5439 .channel_mode = alc260_modes,
5440 .input_mux = &alc260_capture_source,
5441 .unsol_event = alc260_hp_3012_unsol_event,
5442 .init_hook = alc260_hp_3012_automute,
5444 [ALC260_HP_3013] = {
5445 .mixers = { alc260_hp_3013_mixer,
5447 alc260_capture_alt_mixer },
5448 .init_verbs = { alc260_hp_3013_init_verbs,
5449 alc260_hp_3013_unsol_verbs },
5450 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5451 .dac_nids = alc260_dac_nids,
5452 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5453 .adc_nids = alc260_hp_adc_nids,
5454 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5455 .channel_mode = alc260_modes,
5456 .input_mux = &alc260_capture_source,
5457 .unsol_event = alc260_hp_3013_unsol_event,
5458 .init_hook = alc260_hp_3013_automute,
5460 [ALC260_FUJITSU_S702X] = {
5461 .mixers = { alc260_fujitsu_mixer,
5462 alc260_capture_mixer },
5463 .init_verbs = { alc260_fujitsu_init_verbs },
5464 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5465 .dac_nids = alc260_dac_nids,
5466 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5467 .adc_nids = alc260_dual_adc_nids,
5468 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5469 .channel_mode = alc260_modes,
5470 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5471 .input_mux = alc260_fujitsu_capture_sources,
5474 .mixers = { alc260_acer_mixer,
5475 alc260_capture_mixer },
5476 .init_verbs = { alc260_acer_init_verbs },
5477 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5478 .dac_nids = alc260_dac_nids,
5479 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5480 .adc_nids = alc260_dual_adc_nids,
5481 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5482 .channel_mode = alc260_modes,
5483 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5484 .input_mux = alc260_acer_capture_sources,
5487 .mixers = { alc260_will_mixer,
5488 alc260_capture_mixer },
5489 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5490 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5491 .dac_nids = alc260_dac_nids,
5492 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5493 .adc_nids = alc260_adc_nids,
5494 .dig_out_nid = ALC260_DIGOUT_NID,
5495 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5496 .channel_mode = alc260_modes,
5497 .input_mux = &alc260_capture_source,
5499 [ALC260_REPLACER_672V] = {
5500 .mixers = { alc260_replacer_672v_mixer,
5501 alc260_capture_mixer },
5502 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5503 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5504 .dac_nids = alc260_dac_nids,
5505 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5506 .adc_nids = alc260_adc_nids,
5507 .dig_out_nid = ALC260_DIGOUT_NID,
5508 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5509 .channel_mode = alc260_modes,
5510 .input_mux = &alc260_capture_source,
5511 .unsol_event = alc260_replacer_672v_unsol_event,
5512 .init_hook = alc260_replacer_672v_automute,
5514 #ifdef CONFIG_SND_DEBUG
5516 .mixers = { alc260_test_mixer,
5517 alc260_capture_mixer },
5518 .init_verbs = { alc260_test_init_verbs },
5519 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5520 .dac_nids = alc260_test_dac_nids,
5521 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5522 .adc_nids = alc260_test_adc_nids,
5523 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5524 .channel_mode = alc260_modes,
5525 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5526 .input_mux = alc260_test_capture_sources,
5531 static int patch_alc260(struct hda_codec *codec)
5533 struct alc_spec *spec;
5534 int err, board_config;
5536 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5542 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5545 if (board_config < 0) {
5546 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5547 "trying auto-probe from BIOS...\n");
5548 board_config = ALC260_AUTO;
5551 if (board_config == ALC260_AUTO) {
5552 /* automatic parse from the BIOS config */
5553 err = alc260_parse_auto_config(codec);
5559 "hda_codec: Cannot set up configuration "
5560 "from BIOS. Using base mode...\n");
5561 board_config = ALC260_BASIC;
5565 if (board_config != ALC260_AUTO)
5566 setup_preset(spec, &alc260_presets[board_config]);
5568 spec->stream_name_analog = "ALC260 Analog";
5569 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5570 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5572 spec->stream_name_digital = "ALC260 Digital";
5573 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5574 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5576 spec->vmaster_nid = 0x08;
5578 codec->patch_ops = alc_patch_ops;
5579 if (board_config == ALC260_AUTO)
5580 spec->init_hook = alc260_auto_init;
5581 #ifdef CONFIG_SND_HDA_POWER_SAVE
5582 if (!spec->loopback.amplist)
5583 spec->loopback.amplist = alc260_loopbacks;
5593 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5594 * configuration. Each pin widget can choose any input DACs and a mixer.
5595 * Each ADC is connected from a mixer of all inputs. This makes possible
5596 * 6-channel independent captures.
5598 * In addition, an independent DAC for the multi-playback (not used in this
5601 #define ALC882_DIGOUT_NID 0x06
5602 #define ALC882_DIGIN_NID 0x0a
5604 static struct hda_channel_mode alc882_ch_modes[1] = {
5608 static hda_nid_t alc882_dac_nids[4] = {
5609 /* front, rear, clfe, rear_surr */
5610 0x02, 0x03, 0x04, 0x05
5613 /* identical with ALC880 */
5614 #define alc882_adc_nids alc880_adc_nids
5615 #define alc882_adc_nids_alt alc880_adc_nids_alt
5617 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5618 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5621 /* FIXME: should be a matrix-type input source selection */
5623 static struct hda_input_mux alc882_capture_source = {
5627 { "Front Mic", 0x1 },
5632 #define alc882_mux_enum_info alc_mux_enum_info
5633 #define alc882_mux_enum_get alc_mux_enum_get
5635 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5636 struct snd_ctl_elem_value *ucontrol)
5638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5639 struct alc_spec *spec = codec->spec;
5640 const struct hda_input_mux *imux = spec->input_mux;
5641 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5642 hda_nid_t nid = spec->capsrc_nids ?
5643 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5644 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5645 unsigned int i, idx;
5647 idx = ucontrol->value.enumerated.item[0];
5648 if (idx >= imux->num_items)
5649 idx = imux->num_items - 1;
5650 if (*cur_val == idx)
5652 for (i = 0; i < imux->num_items; i++) {
5653 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5654 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5655 imux->items[i].index,
5665 static struct hda_verb alc882_3ST_ch2_init[] = {
5666 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5667 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5668 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5669 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5676 static struct hda_verb alc882_3ST_ch6_init[] = {
5677 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5678 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5679 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5682 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5686 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5687 { 2, alc882_3ST_ch2_init },
5688 { 6, alc882_3ST_ch6_init },
5694 static struct hda_verb alc882_sixstack_ch6_init[] = {
5695 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5697 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5698 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5705 static struct hda_verb alc882_sixstack_ch8_init[] = {
5706 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5707 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5708 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5709 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5713 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5714 { 6, alc882_sixstack_ch6_init },
5715 { 8, alc882_sixstack_ch8_init },
5719 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5725 static struct hda_verb alc885_mbp_ch2_init[] = {
5726 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5727 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5728 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5735 static struct hda_verb alc885_mbp_ch6_init[] = {
5736 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5737 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5738 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5739 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5740 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5744 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5745 { 2, alc885_mbp_ch2_init },
5746 { 6, alc885_mbp_ch6_init },
5750 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5751 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5753 static struct snd_kcontrol_new alc882_base_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_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5757 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5758 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5759 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5760 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5761 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5762 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5763 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5772 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5773 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5775 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5776 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5780 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5781 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5782 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5783 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5784 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5785 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5786 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5788 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5789 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5793 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5795 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5796 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5797 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5803 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5804 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5808 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5810 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5817 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5820 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5821 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5825 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5826 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5828 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5830 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5832 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5833 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5834 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5835 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5836 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5837 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5838 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5840 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5845 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5847 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5849 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5850 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5856 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5857 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5861 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5864 .name = "Channel Mode",
5865 .info = alc_ch_mode_info,
5866 .get = alc_ch_mode_get,
5867 .put = alc_ch_mode_put,
5872 static struct hda_verb alc882_init_verbs[] = {
5873 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5878 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5884 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5886 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5887 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5890 /* Front Pin: output 0 (0x0c) */
5891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5893 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5894 /* Rear Pin: output 1 (0x0d) */
5895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5896 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5898 /* CLFE Pin: output 2 (0x0e) */
5899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5901 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5902 /* Side Pin: output 3 (0x0f) */
5903 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5904 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5905 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5906 /* Mic (rear) pin: input vref at 80% */
5907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5909 /* Front Mic pin: input vref at 80% */
5910 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5911 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5912 /* Line In pin: input */
5913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5915 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5919 /* CD pin widget for input */
5920 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5922 /* FIXME: use matrix-type input source selection */
5923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5924 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5925 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5939 /* ADC1: mute amp left and right */
5940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5941 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5942 /* ADC2: mute amp left and right */
5943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5944 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5945 /* ADC3: mute amp left and right */
5946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5947 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5952 static struct hda_verb alc882_eapd_verbs[] = {
5953 /* change to EAPD mode */
5954 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5955 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5960 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5964 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5965 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5966 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5967 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5971 static struct hda_verb alc882_macpro_init_verbs[] = {
5972 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5975 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5976 /* Front Pin: output 0 (0x0c) */
5977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5980 /* Front Mic pin: input vref at 80% */
5981 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5982 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5983 /* Speaker: output */
5984 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5985 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5986 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5987 /* Headphone output (output 0 - 0x0c) */
5988 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5989 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5990 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5992 /* FIXME: use matrix-type input source selection */
5993 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5994 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6009 /* ADC1: mute amp left and right */
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6011 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6012 /* ADC2: mute amp left and right */
6013 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6014 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6015 /* ADC3: mute amp left and right */
6016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6017 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6022 /* Macbook Pro rev3 */
6023 static struct hda_verb alc885_mbp3_init_verbs[] = {
6024 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6032 /* Front Pin: output 0 (0x0c) */
6033 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6035 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6036 /* HP Pin: output 0 (0x0d) */
6037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6039 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6040 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6041 /* Mic (rear) pin: input vref at 80% */
6042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6043 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6044 /* Front Mic pin: input vref at 80% */
6045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6047 /* Line In pin: use output 1 when in LineOut mode */
6048 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6050 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6052 /* FIXME: use matrix-type input source selection */
6053 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6054 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6055 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6060 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6069 /* ADC1: mute amp left and right */
6070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6071 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6072 /* ADC2: mute amp left and right */
6073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6074 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6075 /* ADC3: mute amp left and right */
6076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6077 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6082 /* iMac 24 mixer. */
6083 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6084 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6085 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6089 /* iMac 24 init verbs. */
6090 static struct hda_verb alc885_imac24_init_verbs[] = {
6091 /* Internal speakers: output 0 (0x0c) */
6092 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6093 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6094 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6095 /* Internal speakers: output 0 (0x0c) */
6096 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6097 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6098 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6099 /* Headphone: output 0 (0x0c) */
6100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6103 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6104 /* Front Mic: input vref at 80% */
6105 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6106 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6110 /* Toggle speaker-output according to the hp-jack state */
6111 static void alc885_imac24_automute(struct hda_codec *codec)
6113 unsigned int present;
6115 present = snd_hda_codec_read(codec, 0x14, 0,
6116 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6117 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6118 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6119 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6120 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6123 /* Processes unsolicited events. */
6124 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6127 /* Headphone insertion or removal. */
6128 if ((res >> 26) == ALC880_HP_EVENT)
6129 alc885_imac24_automute(codec);
6132 static void alc885_mbp3_automute(struct hda_codec *codec)
6134 unsigned int present;
6136 present = snd_hda_codec_read(codec, 0x15, 0,
6137 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6138 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6139 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6140 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6141 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6144 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6147 /* Headphone insertion or removal. */
6148 if ((res >> 26) == ALC880_HP_EVENT)
6149 alc885_mbp3_automute(codec);
6153 static struct hda_verb alc882_targa_verbs[] = {
6154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6160 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6161 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6164 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6165 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6166 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6167 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6171 /* toggle speaker-output according to the hp-jack state */
6172 static void alc882_targa_automute(struct hda_codec *codec)
6174 unsigned int present;
6176 present = snd_hda_codec_read(codec, 0x14, 0,
6177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6178 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6179 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6180 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6184 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6186 /* Looks like the unsol event is incompatible with the standard
6187 * definition. 4bit tag is placed at 26 bit!
6189 if (((res >> 26) == ALC880_HP_EVENT)) {
6190 alc882_targa_automute(codec);
6194 static struct hda_verb alc882_asus_a7j_verbs[] = {
6195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6198 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6200 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6202 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6204 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6206 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6207 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6208 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6212 static struct hda_verb alc882_asus_a7m_verbs[] = {
6213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6216 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6218 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6220 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6222 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6224 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6226 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6230 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6232 unsigned int gpiostate, gpiomask, gpiodir;
6234 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6235 AC_VERB_GET_GPIO_DATA, 0);
6238 gpiostate |= (1 << pin);
6240 gpiostate &= ~(1 << pin);
6242 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6243 AC_VERB_GET_GPIO_MASK, 0);
6244 gpiomask |= (1 << pin);
6246 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6247 AC_VERB_GET_GPIO_DIRECTION, 0);
6248 gpiodir |= (1 << pin);
6251 snd_hda_codec_write(codec, codec->afg, 0,
6252 AC_VERB_SET_GPIO_MASK, gpiomask);
6253 snd_hda_codec_write(codec, codec->afg, 0,
6254 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6258 snd_hda_codec_write(codec, codec->afg, 0,
6259 AC_VERB_SET_GPIO_DATA, gpiostate);
6262 /* set up GPIO at initialization */
6263 static void alc885_macpro_init_hook(struct hda_codec *codec)
6265 alc882_gpio_mute(codec, 0, 0);
6266 alc882_gpio_mute(codec, 1, 0);
6269 /* set up GPIO and update auto-muting at initialization */
6270 static void alc885_imac24_init_hook(struct hda_codec *codec)
6272 alc885_macpro_init_hook(codec);
6273 alc885_imac24_automute(codec);
6277 * generic initialization of ADC, input mixers and output mixers
6279 static struct hda_verb alc882_auto_init_verbs[] = {
6281 * Unmute ADC0-2 and set the default input to mic-in
6283 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6285 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6287 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6290 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6292 * Note: PASD motherboards uses the Line In 2 as the input for
6293 * front panel mic (mic 2)
6295 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6303 * Set up output mixers (0x0c - 0x0f)
6305 /* set vol=0 to output mixers */
6306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6310 /* set up input amps for analog loopback */
6311 /* Amp Indices: DAC = 0, mixer = 1 */
6312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6318 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6320 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6321 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6323 /* FIXME: use matrix-type input source selection */
6324 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6325 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6344 /* capture mixer elements */
6345 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6346 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6347 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6348 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6349 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6352 /* The multiple "Capture Source" controls confuse alsamixer
6353 * So call somewhat different..
6355 /* .name = "Capture Source", */
6356 .name = "Input Source",
6358 .info = alc882_mux_enum_info,
6359 .get = alc882_mux_enum_get,
6360 .put = alc882_mux_enum_put,
6365 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6366 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6367 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6368 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6370 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6371 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6374 /* The multiple "Capture Source" controls confuse alsamixer
6375 * So call somewhat different..
6377 /* .name = "Capture Source", */
6378 .name = "Input Source",
6380 .info = alc882_mux_enum_info,
6381 .get = alc882_mux_enum_get,
6382 .put = alc882_mux_enum_put,
6387 #ifdef CONFIG_SND_HDA_POWER_SAVE
6388 #define alc882_loopbacks alc880_loopbacks
6391 /* pcm configuration: identiacal with ALC880 */
6392 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6393 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6394 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6395 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6398 * configuration and preset
6400 static const char *alc882_models[ALC882_MODEL_LAST] = {
6401 [ALC882_3ST_DIG] = "3stack-dig",
6402 [ALC882_6ST_DIG] = "6stack-dig",
6403 [ALC882_ARIMA] = "arima",
6404 [ALC882_W2JC] = "w2jc",
6405 [ALC882_TARGA] = "targa",
6406 [ALC882_ASUS_A7J] = "asus-a7j",
6407 [ALC882_ASUS_A7M] = "asus-a7m",
6408 [ALC885_MACPRO] = "macpro",
6409 [ALC885_MBP3] = "mbp3",
6410 [ALC885_IMAC24] = "imac24",
6411 [ALC882_AUTO] = "auto",
6414 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6415 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6416 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6417 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6418 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6419 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6420 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6421 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6422 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6423 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6424 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6425 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6426 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6430 static struct alc_config_preset alc882_presets[] = {
6431 [ALC882_3ST_DIG] = {
6432 .mixers = { alc882_base_mixer },
6433 .init_verbs = { alc882_init_verbs },
6434 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6435 .dac_nids = alc882_dac_nids,
6436 .dig_out_nid = ALC882_DIGOUT_NID,
6437 .dig_in_nid = ALC882_DIGIN_NID,
6438 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6439 .channel_mode = alc882_ch_modes,
6441 .input_mux = &alc882_capture_source,
6443 [ALC882_6ST_DIG] = {
6444 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6445 .init_verbs = { alc882_init_verbs },
6446 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6447 .dac_nids = alc882_dac_nids,
6448 .dig_out_nid = ALC882_DIGOUT_NID,
6449 .dig_in_nid = ALC882_DIGIN_NID,
6450 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6451 .channel_mode = alc882_sixstack_modes,
6452 .input_mux = &alc882_capture_source,
6455 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6456 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6457 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6458 .dac_nids = alc882_dac_nids,
6459 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6460 .channel_mode = alc882_sixstack_modes,
6461 .input_mux = &alc882_capture_source,
6464 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6465 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6466 alc880_gpio1_init_verbs },
6467 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6468 .dac_nids = alc882_dac_nids,
6469 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6470 .channel_mode = alc880_threestack_modes,
6472 .input_mux = &alc882_capture_source,
6473 .dig_out_nid = ALC882_DIGOUT_NID,
6476 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6477 .init_verbs = { alc885_mbp3_init_verbs,
6478 alc880_gpio1_init_verbs },
6479 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6480 .dac_nids = alc882_dac_nids,
6481 .channel_mode = alc885_mbp_6ch_modes,
6482 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6483 .input_mux = &alc882_capture_source,
6484 .dig_out_nid = ALC882_DIGOUT_NID,
6485 .dig_in_nid = ALC882_DIGIN_NID,
6486 .unsol_event = alc885_mbp3_unsol_event,
6487 .init_hook = alc885_mbp3_automute,
6490 .mixers = { alc882_macpro_mixer },
6491 .init_verbs = { alc882_macpro_init_verbs },
6492 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6493 .dac_nids = alc882_dac_nids,
6494 .dig_out_nid = ALC882_DIGOUT_NID,
6495 .dig_in_nid = ALC882_DIGIN_NID,
6496 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6497 .channel_mode = alc882_ch_modes,
6498 .input_mux = &alc882_capture_source,
6499 .init_hook = alc885_macpro_init_hook,
6502 .mixers = { alc885_imac24_mixer },
6503 .init_verbs = { alc885_imac24_init_verbs },
6504 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6505 .dac_nids = alc882_dac_nids,
6506 .dig_out_nid = ALC882_DIGOUT_NID,
6507 .dig_in_nid = ALC882_DIGIN_NID,
6508 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6509 .channel_mode = alc882_ch_modes,
6510 .input_mux = &alc882_capture_source,
6511 .unsol_event = alc885_imac24_unsol_event,
6512 .init_hook = alc885_imac24_init_hook,
6515 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6516 alc882_capture_mixer },
6517 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6518 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6519 .dac_nids = alc882_dac_nids,
6520 .dig_out_nid = ALC882_DIGOUT_NID,
6521 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6522 .adc_nids = alc882_adc_nids,
6523 .capsrc_nids = alc882_capsrc_nids,
6524 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6525 .channel_mode = alc882_3ST_6ch_modes,
6527 .input_mux = &alc882_capture_source,
6528 .unsol_event = alc882_targa_unsol_event,
6529 .init_hook = alc882_targa_automute,
6531 [ALC882_ASUS_A7J] = {
6532 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6533 alc882_capture_mixer },
6534 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6535 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6536 .dac_nids = alc882_dac_nids,
6537 .dig_out_nid = ALC882_DIGOUT_NID,
6538 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6539 .adc_nids = alc882_adc_nids,
6540 .capsrc_nids = alc882_capsrc_nids,
6541 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6542 .channel_mode = alc882_3ST_6ch_modes,
6544 .input_mux = &alc882_capture_source,
6546 [ALC882_ASUS_A7M] = {
6547 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6548 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6549 alc880_gpio1_init_verbs,
6550 alc882_asus_a7m_verbs },
6551 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6552 .dac_nids = alc882_dac_nids,
6553 .dig_out_nid = ALC882_DIGOUT_NID,
6554 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6555 .channel_mode = alc880_threestack_modes,
6557 .input_mux = &alc882_capture_source,
6566 PINFIX_ABIT_AW9D_MAX
6569 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6570 { 0x15, 0x01080104 }, /* side */
6571 { 0x16, 0x01011012 }, /* rear */
6572 { 0x17, 0x01016011 }, /* clfe */
6576 static const struct alc_pincfg *alc882_pin_fixes[] = {
6577 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6580 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6581 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6586 * BIOS auto configuration
6588 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6589 hda_nid_t nid, int pin_type,
6593 struct alc_spec *spec = codec->spec;
6596 alc_set_pin_output(codec, nid, pin_type);
6597 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6600 idx = spec->multiout.dac_nids[dac_idx] - 2;
6601 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6605 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6607 struct alc_spec *spec = codec->spec;
6610 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6611 for (i = 0; i <= HDA_SIDE; i++) {
6612 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6613 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6615 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6620 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6622 struct alc_spec *spec = codec->spec;
6625 pin = spec->autocfg.hp_pins[0];
6626 if (pin) /* connect to front */
6628 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6629 pin = spec->autocfg.speaker_pins[0];
6631 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6634 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6635 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6637 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6639 struct alc_spec *spec = codec->spec;
6642 for (i = 0; i < AUTO_PIN_LAST; i++) {
6643 hda_nid_t nid = spec->autocfg.input_pins[i];
6648 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6649 unsigned int pincap;
6650 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6651 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6655 snd_hda_codec_write(codec, nid, 0,
6656 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6657 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6658 snd_hda_codec_write(codec, nid, 0,
6659 AC_VERB_SET_AMP_GAIN_MUTE,
6664 static void alc882_auto_init_input_src(struct hda_codec *codec)
6666 struct alc_spec *spec = codec->spec;
6667 const struct hda_input_mux *imux = spec->input_mux;
6670 for (c = 0; c < spec->num_adc_nids; c++) {
6671 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6672 hda_nid_t nid = spec->capsrc_nids[c];
6673 int conns, mute, idx, item;
6675 conns = snd_hda_get_connections(codec, nid, conn_list,
6676 ARRAY_SIZE(conn_list));
6679 for (idx = 0; idx < conns; idx++) {
6680 /* if the current connection is the selected one,
6681 * unmute it as default - otherwise mute it
6683 mute = AMP_IN_MUTE(idx);
6684 for (item = 0; item < imux->num_items; item++) {
6685 if (imux->items[item].index == idx) {
6686 if (spec->cur_mux[c] == item)
6687 mute = AMP_IN_UNMUTE(idx);
6691 snd_hda_codec_write(codec, nid, 0,
6692 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6697 /* add mic boosts if needed */
6698 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6700 struct alc_spec *spec = codec->spec;
6704 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6705 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6706 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6708 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6712 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6713 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6714 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6716 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6723 /* almost identical with ALC880 parser... */
6724 static int alc882_parse_auto_config(struct hda_codec *codec)
6726 struct alc_spec *spec = codec->spec;
6727 int err = alc880_parse_auto_config(codec);
6732 return 0; /* no config found */
6734 err = alc_auto_add_mic_boost(codec);
6738 /* hack - override the init verbs */
6739 spec->init_verbs[0] = alc882_auto_init_verbs;
6741 return 1; /* config found */
6744 /* additional initialization for auto-configuration model */
6745 static void alc882_auto_init(struct hda_codec *codec)
6747 struct alc_spec *spec = codec->spec;
6748 alc882_auto_init_multi_out(codec);
6749 alc882_auto_init_hp_out(codec);
6750 alc882_auto_init_analog_input(codec);
6751 alc882_auto_init_input_src(codec);
6752 if (spec->unsol_event)
6753 alc_inithook(codec);
6756 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6758 static int patch_alc882(struct hda_codec *codec)
6760 struct alc_spec *spec;
6761 int err, board_config;
6763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6769 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6773 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6774 /* Pick up systems that don't supply PCI SSID */
6775 switch (codec->subsystem_id) {
6776 case 0x106b0c00: /* Mac Pro */
6777 board_config = ALC885_MACPRO;
6779 case 0x106b1000: /* iMac 24 */
6780 case 0x106b2800: /* AppleTV */
6781 board_config = ALC885_IMAC24;
6783 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6784 case 0x106b00a4: /* MacbookPro4,1 */
6785 case 0x106b2c00: /* Macbook Pro rev3 */
6786 case 0x106b3600: /* Macbook 3.1 */
6787 board_config = ALC885_MBP3;
6790 /* ALC889A is handled better as ALC888-compatible */
6791 if (codec->revision_id == 0x100101 ||
6792 codec->revision_id == 0x100103) {
6794 return patch_alc883(codec);
6796 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6797 "trying auto-probe from BIOS...\n");
6798 board_config = ALC882_AUTO;
6802 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6804 if (board_config == ALC882_AUTO) {
6805 /* automatic parse from the BIOS config */
6806 err = alc882_parse_auto_config(codec);
6812 "hda_codec: Cannot set up configuration "
6813 "from BIOS. Using base mode...\n");
6814 board_config = ALC882_3ST_DIG;
6818 if (board_config != ALC882_AUTO)
6819 setup_preset(spec, &alc882_presets[board_config]);
6821 if (codec->vendor_id == 0x10ec0885) {
6822 spec->stream_name_analog = "ALC885 Analog";
6823 spec->stream_name_digital = "ALC885 Digital";
6825 spec->stream_name_analog = "ALC882 Analog";
6826 spec->stream_name_digital = "ALC882 Digital";
6829 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6830 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6831 /* FIXME: setup DAC5 */
6832 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6833 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6835 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6836 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6838 if (!spec->adc_nids && spec->input_mux) {
6839 /* check whether NID 0x07 is valid */
6840 unsigned int wcap = get_wcaps(codec, 0x07);
6842 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6843 if (wcap != AC_WID_AUD_IN) {
6844 spec->adc_nids = alc882_adc_nids_alt;
6845 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6846 spec->capsrc_nids = alc882_capsrc_nids_alt;
6847 add_mixer(spec, alc882_capture_alt_mixer);
6849 spec->adc_nids = alc882_adc_nids;
6850 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6851 spec->capsrc_nids = alc882_capsrc_nids;
6852 add_mixer(spec, alc882_capture_mixer);
6856 spec->vmaster_nid = 0x0c;
6858 codec->patch_ops = alc_patch_ops;
6859 if (board_config == ALC882_AUTO)
6860 spec->init_hook = alc882_auto_init;
6861 #ifdef CONFIG_SND_HDA_POWER_SAVE
6862 if (!spec->loopback.amplist)
6863 spec->loopback.amplist = alc882_loopbacks;
6872 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6873 * configuration. Each pin widget can choose any input DACs and a mixer.
6874 * Each ADC is connected from a mixer of all inputs. This makes possible
6875 * 6-channel independent captures.
6877 * In addition, an independent DAC for the multi-playback (not used in this
6880 #define ALC883_DIGOUT_NID 0x06
6881 #define ALC883_DIGIN_NID 0x0a
6883 static hda_nid_t alc883_dac_nids[4] = {
6884 /* front, rear, clfe, rear_surr */
6885 0x02, 0x03, 0x04, 0x05
6888 static hda_nid_t alc883_adc_nids[2] = {
6893 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6896 /* FIXME: should be a matrix-type input source selection */
6898 static struct hda_input_mux alc883_capture_source = {
6902 { "Front Mic", 0x1 },
6908 static struct hda_input_mux alc883_3stack_6ch_intel = {
6912 { "Front Mic", 0x0 },
6918 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6926 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6936 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6944 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6948 { "Front Mic", 0x1 },
6953 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6961 #define alc883_mux_enum_info alc_mux_enum_info
6962 #define alc883_mux_enum_get alc_mux_enum_get
6963 /* ALC883 has the ALC882-type input selection */
6964 #define alc883_mux_enum_put alc882_mux_enum_put
6969 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6976 static struct hda_verb alc883_3ST_ch2_init[] = {
6977 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6978 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6979 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6980 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6987 static struct hda_verb alc883_3ST_ch4_init[] = {
6988 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6989 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6990 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6991 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6992 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6999 static struct hda_verb alc883_3ST_ch6_init[] = {
7000 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7001 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7002 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7003 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7004 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7005 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7009 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7010 { 2, alc883_3ST_ch2_init },
7011 { 4, alc883_3ST_ch4_init },
7012 { 6, alc883_3ST_ch6_init },
7018 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7019 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7020 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7021 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7022 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7029 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7030 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7031 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7033 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7034 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7041 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7042 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7043 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7044 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7045 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7046 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7047 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7051 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7052 { 2, alc883_3ST_ch2_intel_init },
7053 { 4, alc883_3ST_ch4_intel_init },
7054 { 6, alc883_3ST_ch6_intel_init },
7060 static struct hda_verb alc883_sixstack_ch6_init[] = {
7061 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7062 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7063 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7064 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7071 static struct hda_verb alc883_sixstack_ch8_init[] = {
7072 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7073 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7074 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7075 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7079 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7080 { 6, alc883_sixstack_ch6_init },
7081 { 8, alc883_sixstack_ch8_init },
7084 static struct hda_verb alc883_medion_eapd_verbs[] = {
7085 /* eanable EAPD on medion laptop */
7086 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7087 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7091 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7092 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7095 static struct snd_kcontrol_new alc883_base_mixer[] = {
7096 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7097 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7098 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7099 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7100 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7101 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7102 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7103 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7105 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7106 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7112 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7115 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7117 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7118 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7119 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7120 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7121 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7122 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7125 /* .name = "Capture Source", */
7126 .name = "Input Source",
7128 .info = alc883_mux_enum_info,
7129 .get = alc883_mux_enum_get,
7130 .put = alc883_mux_enum_put,
7135 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7139 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7140 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7141 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7144 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7147 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7149 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7150 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7151 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7152 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7155 /* .name = "Capture Source", */
7156 .name = "Input Source",
7158 .info = alc883_mux_enum_info,
7159 .get = alc883_mux_enum_get,
7160 .put = alc883_mux_enum_put,
7165 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7166 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7167 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7169 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7171 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7174 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7175 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7177 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7178 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7179 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7182 /* .name = "Capture Source", */
7183 .name = "Input Source",
7185 .info = alc883_mux_enum_info,
7186 .get = alc883_mux_enum_get,
7187 .put = alc883_mux_enum_put,
7192 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7194 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7195 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7196 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7198 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7200 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7201 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7202 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7203 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7204 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7205 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7206 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7209 /* .name = "Capture Source", */
7210 .name = "Input Source",
7212 .info = alc883_mux_enum_info,
7213 .get = alc883_mux_enum_get,
7214 .put = alc883_mux_enum_put,
7219 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7223 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7224 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7225 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7226 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7227 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7230 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7231 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7233 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7234 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7235 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7236 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7237 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7238 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7241 /* .name = "Capture Source", */
7242 .name = "Input Source",
7244 .info = alc883_mux_enum_info,
7245 .get = alc883_mux_enum_get,
7246 .put = alc883_mux_enum_put,
7251 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7253 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7255 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7256 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7257 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7258 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7259 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7260 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7261 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7262 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7265 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7266 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7268 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7269 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7271 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7272 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7273 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7274 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7277 /* .name = "Capture Source", */
7278 .name = "Input Source",
7280 .info = alc883_mux_enum_info,
7281 .get = alc883_mux_enum_get,
7282 .put = alc883_mux_enum_put,
7287 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7289 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7290 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7291 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7292 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7294 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7295 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7296 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7303 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7304 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7305 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7306 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7307 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7308 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7309 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7312 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7313 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7316 /* .name = "Capture Source", */
7317 .name = "Input Source",
7319 .info = alc883_mux_enum_info,
7320 .get = alc883_mux_enum_get,
7321 .put = alc883_mux_enum_put,
7326 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7328 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7329 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7330 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7331 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7332 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7333 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7334 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7336 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7337 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7338 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7339 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7341 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7342 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7343 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7344 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7345 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7346 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7347 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7348 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7349 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7353 /* .name = "Capture Source", */
7354 .name = "Input Source",
7356 .info = alc883_mux_enum_info,
7357 .get = alc883_mux_enum_get,
7358 .put = alc883_mux_enum_put,
7363 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7364 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7366 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7371 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7372 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7375 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7376 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7378 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7380 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7381 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7382 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7383 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7386 /* .name = "Capture Source", */
7387 .name = "Input Source",
7389 .info = alc883_mux_enum_info,
7390 .get = alc883_mux_enum_get,
7391 .put = alc883_mux_enum_put,
7396 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7398 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7399 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7405 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7406 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7407 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7408 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7409 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7410 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7411 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7414 /* .name = "Capture Source", */
7415 .name = "Input Source",
7417 .info = alc883_mux_enum_info,
7418 .get = alc883_mux_enum_get,
7419 .put = alc883_mux_enum_put,
7424 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7426 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7427 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7428 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7433 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7434 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7437 /* .name = "Capture Source", */
7438 .name = "Input Source",
7440 .info = alc883_mux_enum_info,
7441 .get = alc883_mux_enum_get,
7442 .put = alc883_mux_enum_put,
7447 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7448 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7449 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7451 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7452 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7455 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7456 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7458 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7459 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7460 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7463 /* .name = "Capture Source", */
7464 .name = "Input Source",
7466 .info = alc883_mux_enum_info,
7467 .get = alc883_mux_enum_get,
7468 .put = alc883_mux_enum_put,
7473 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7476 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7477 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7478 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7483 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7484 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7485 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7486 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7489 /* .name = "Capture Source", */
7490 .name = "Input Source",
7492 .info = alc883_mux_enum_info,
7493 .get = alc883_mux_enum_get,
7494 .put = alc883_mux_enum_put,
7499 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7506 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7508 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7509 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7510 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7511 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7514 /* .name = "Capture Source", */
7515 .name = "Input Source",
7517 .info = alc883_mux_enum_info,
7518 .get = alc883_mux_enum_get,
7519 .put = alc883_mux_enum_put,
7524 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7525 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7526 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7527 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7528 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7529 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7530 0x0d, 1, 0x0, HDA_OUTPUT),
7531 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7532 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7533 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7534 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7535 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7537 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7538 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7539 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7540 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7541 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7543 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7544 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7547 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7549 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7550 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7551 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7554 /* .name = "Capture Source", */
7555 .name = "Input Source",
7557 .info = alc883_mux_enum_info,
7558 .get = alc883_mux_enum_get,
7559 .put = alc883_mux_enum_put,
7564 static struct hda_bind_ctls alc883_bind_cap_vol = {
7565 .ops = &snd_hda_bind_vol,
7567 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7568 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7573 static struct hda_bind_ctls alc883_bind_cap_switch = {
7574 .ops = &snd_hda_bind_sw,
7576 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7577 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7582 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7583 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7584 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7585 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7591 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7592 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7595 /* .name = "Capture Source", */
7596 .name = "Input Source",
7598 .info = alc883_mux_enum_info,
7599 .get = alc883_mux_enum_get,
7600 .put = alc883_mux_enum_put,
7605 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7608 .name = "Channel Mode",
7609 .info = alc_ch_mode_info,
7610 .get = alc_ch_mode_get,
7611 .put = alc_ch_mode_put,
7616 static struct hda_verb alc883_init_verbs[] = {
7617 /* ADC1: mute amp left and right */
7618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7619 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 /* ADC2: mute amp left and right */
7621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7622 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7623 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7628 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7640 /* mute analog input loopbacks */
7641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7647 /* Front Pin: output 0 (0x0c) */
7648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7651 /* Rear Pin: output 1 (0x0d) */
7652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7655 /* CLFE Pin: output 2 (0x0e) */
7656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7659 /* Side Pin: output 3 (0x0f) */
7660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7662 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7663 /* Mic (rear) pin: input vref at 80% */
7664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7666 /* Front Mic pin: input vref at 80% */
7667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7669 /* Line In pin: input */
7670 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7671 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7672 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7674 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7675 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7676 /* CD pin widget for input */
7677 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7679 /* FIXME: use matrix-type input source selection */
7680 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7682 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7690 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7694 /* toggle speaker-output according to the hp-jack state */
7695 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7697 unsigned int present;
7699 present = snd_hda_codec_read(codec, 0x15, 0,
7700 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7701 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7702 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7703 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7704 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7707 /* auto-toggle front mic */
7709 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7711 unsigned int present;
7714 present = snd_hda_codec_read(codec, 0x18, 0,
7715 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7716 bits = present ? HDA_AMP_MUTE : 0;
7717 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7721 static void alc883_mitac_automute(struct hda_codec *codec)
7723 alc883_mitac_hp_automute(codec);
7724 /* alc883_mitac_mic_automute(codec); */
7727 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7730 switch (res >> 26) {
7731 case ALC880_HP_EVENT:
7732 alc883_mitac_hp_automute(codec);
7734 case ALC880_MIC_EVENT:
7735 /* alc883_mitac_mic_automute(codec); */
7740 static struct hda_verb alc883_mitac_verbs[] = {
7742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7745 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7746 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7748 /* enable unsolicited event */
7749 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7750 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7755 static struct hda_verb alc883_clevo_m720_verbs[] = {
7757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7763 /* enable unsolicited event */
7764 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7765 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7770 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7772 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7773 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7775 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7778 /* enable unsolicited event */
7779 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7784 static struct hda_verb alc883_tagra_verbs[] = {
7785 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7792 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7793 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7796 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7797 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7798 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7803 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7805 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7806 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7810 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7813 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7818 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7822 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7823 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7827 static struct hda_verb alc883_haier_w66_verbs[] = {
7828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7831 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7833 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7840 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7846 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7847 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7848 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7852 static struct hda_verb alc888_3st_hp_verbs[] = {
7853 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7854 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7855 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7859 static struct hda_verb alc888_6st_dell_verbs[] = {
7860 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7864 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7868 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7872 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7876 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7880 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7881 { 2, alc888_3st_hp_2ch_init },
7882 { 6, alc888_3st_hp_6ch_init },
7885 /* toggle front-jack and RCA according to the hp-jack state */
7886 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7888 unsigned int present;
7890 present = snd_hda_codec_read(codec, 0x1b, 0,
7891 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7892 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7893 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7894 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7895 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7898 /* toggle RCA according to the front-jack state */
7899 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7901 unsigned int present;
7903 present = snd_hda_codec_read(codec, 0x14, 0,
7904 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7905 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7906 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7909 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7912 if ((res >> 26) == ALC880_HP_EVENT)
7913 alc888_lenovo_ms7195_front_automute(codec);
7914 if ((res >> 26) == ALC880_FRONT_EVENT)
7915 alc888_lenovo_ms7195_rca_automute(codec);
7918 static struct hda_verb alc883_medion_md2_verbs[] = {
7919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7924 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7928 /* toggle speaker-output according to the hp-jack state */
7929 static void alc883_medion_md2_automute(struct hda_codec *codec)
7931 unsigned int present;
7933 present = snd_hda_codec_read(codec, 0x14, 0,
7934 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7935 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7936 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7939 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7942 if ((res >> 26) == ALC880_HP_EVENT)
7943 alc883_medion_md2_automute(codec);
7946 /* toggle speaker-output according to the hp-jack state */
7947 static void alc883_tagra_automute(struct hda_codec *codec)
7949 unsigned int present;
7952 present = snd_hda_codec_read(codec, 0x14, 0,
7953 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7954 bits = present ? HDA_AMP_MUTE : 0;
7955 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7956 HDA_AMP_MUTE, bits);
7957 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7961 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7963 if ((res >> 26) == ALC880_HP_EVENT)
7964 alc883_tagra_automute(codec);
7967 /* toggle speaker-output according to the hp-jack state */
7968 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7970 unsigned int present;
7973 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7974 & AC_PINSENSE_PRESENCE;
7975 bits = present ? HDA_AMP_MUTE : 0;
7976 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7977 HDA_AMP_MUTE, bits);
7980 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7982 unsigned int present;
7984 present = snd_hda_codec_read(codec, 0x18, 0,
7985 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7986 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7987 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7990 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7992 alc883_clevo_m720_hp_automute(codec);
7993 alc883_clevo_m720_mic_automute(codec);
7996 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7999 switch (res >> 26) {
8000 case ALC880_HP_EVENT:
8001 alc883_clevo_m720_hp_automute(codec);
8003 case ALC880_MIC_EVENT:
8004 alc883_clevo_m720_mic_automute(codec);
8009 /* toggle speaker-output according to the hp-jack state */
8010 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8012 unsigned int present;
8015 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8016 & AC_PINSENSE_PRESENCE;
8017 bits = present ? HDA_AMP_MUTE : 0;
8018 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8019 HDA_AMP_MUTE, bits);
8022 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8025 if ((res >> 26) == ALC880_HP_EVENT)
8026 alc883_2ch_fujitsu_pi2515_automute(codec);
8029 static void alc883_haier_w66_automute(struct hda_codec *codec)
8031 unsigned int present;
8034 present = snd_hda_codec_read(codec, 0x1b, 0,
8035 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8036 bits = present ? 0x80 : 0;
8037 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8041 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8044 if ((res >> 26) == ALC880_HP_EVENT)
8045 alc883_haier_w66_automute(codec);
8048 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8050 unsigned int present;
8053 present = snd_hda_codec_read(codec, 0x14, 0,
8054 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8055 bits = present ? HDA_AMP_MUTE : 0;
8056 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8057 HDA_AMP_MUTE, bits);
8060 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8062 unsigned int present;
8065 present = snd_hda_codec_read(codec, 0x1b, 0,
8066 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8067 bits = present ? HDA_AMP_MUTE : 0;
8068 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8069 HDA_AMP_MUTE, bits);
8070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8071 HDA_AMP_MUTE, bits);
8074 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8077 if ((res >> 26) == ALC880_HP_EVENT)
8078 alc883_lenovo_101e_all_automute(codec);
8079 if ((res >> 26) == ALC880_FRONT_EVENT)
8080 alc883_lenovo_101e_ispeaker_automute(codec);
8083 /* toggle speaker-output according to the hp-jack state */
8084 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8086 unsigned int present;
8088 present = snd_hda_codec_read(codec, 0x14, 0,
8089 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8090 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8091 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8092 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8093 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8096 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8099 if ((res >> 26) == ALC880_HP_EVENT)
8100 alc883_acer_aspire_automute(codec);
8103 static struct hda_verb alc883_acer_eapd_verbs[] = {
8104 /* HP Pin: output 0 (0x0c) */
8105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8108 /* Front Pin: output 0 (0x0c) */
8109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8111 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8112 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8113 /* eanable EAPD on medion laptop */
8114 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8115 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8116 /* enable unsolicited event */
8117 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8121 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8123 unsigned int present;
8125 present = snd_hda_codec_read(codec, 0x1b, 0,
8126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8127 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8128 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8129 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8130 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8131 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8132 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8133 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8134 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8137 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8140 switch (res >> 26) {
8141 case ALC880_HP_EVENT:
8142 printk("hp_event\n");
8143 alc888_6st_dell_front_automute(codec);
8148 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8151 unsigned int present;
8153 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8154 present = snd_hda_codec_read(codec, 0x1b, 0,
8155 AC_VERB_GET_PIN_SENSE, 0);
8156 present = (present & 0x80000000) != 0;
8158 /* mute internal speaker */
8159 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8160 HDA_AMP_MUTE, HDA_AMP_MUTE);
8161 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8162 HDA_AMP_MUTE, HDA_AMP_MUTE);
8163 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8164 HDA_AMP_MUTE, HDA_AMP_MUTE);
8165 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8166 HDA_AMP_MUTE, HDA_AMP_MUTE);
8167 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8168 HDA_AMP_MUTE, HDA_AMP_MUTE);
8170 /* unmute internal speaker if necessary */
8171 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8172 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8173 HDA_AMP_MUTE, mute);
8174 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8175 HDA_AMP_MUTE, mute);
8176 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8177 HDA_AMP_MUTE, mute);
8178 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8179 HDA_AMP_MUTE, mute);
8180 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8181 HDA_AMP_MUTE, mute);
8185 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8188 if ((res >> 26) == ALC880_HP_EVENT)
8189 alc888_lenovo_sky_front_automute(codec);
8193 * generic initialization of ADC, input mixers and output mixers
8195 static struct hda_verb alc883_auto_init_verbs[] = {
8197 * Unmute ADC0-2 and set the default input to mic-in
8199 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8204 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8206 * Note: PASD motherboards uses the Line In 2 as the input for
8207 * front panel mic (mic 2)
8209 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8217 * Set up output mixers (0x0c - 0x0f)
8219 /* set vol=0 to output mixers */
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8223 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8224 /* set up input amps for analog loopback */
8225 /* Amp Indices: DAC = 0, mixer = 1 */
8226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8228 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8231 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8234 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8235 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8237 /* FIXME: use matrix-type input source selection */
8238 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8243 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8249 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8255 /* capture mixer elements */
8256 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8257 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8258 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8259 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8260 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8263 /* The multiple "Capture Source" controls confuse alsamixer
8264 * So call somewhat different..
8266 /* .name = "Capture Source", */
8267 .name = "Input Source",
8269 .info = alc882_mux_enum_info,
8270 .get = alc882_mux_enum_get,
8271 .put = alc882_mux_enum_put,
8276 static struct hda_verb alc888_asus_m90v_verbs[] = {
8277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8278 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8279 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8280 /* enable unsolicited event */
8281 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8282 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8286 static void alc883_nb_mic_automute(struct hda_codec *codec)
8288 unsigned int present;
8290 present = snd_hda_codec_read(codec, 0x18, 0,
8291 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8292 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8293 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8294 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8295 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8298 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8300 unsigned int present;
8303 present = snd_hda_codec_read(codec, 0x1b, 0,
8304 AC_VERB_GET_PIN_SENSE, 0)
8305 & AC_PINSENSE_PRESENCE;
8306 bits = present ? 0 : PIN_OUT;
8307 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8309 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8311 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8315 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8318 switch (res >> 26) {
8319 case ALC880_HP_EVENT:
8320 alc883_M90V_speaker_automute(codec);
8322 case ALC880_MIC_EVENT:
8323 alc883_nb_mic_automute(codec);
8328 static void alc883_mode2_inithook(struct hda_codec *codec)
8330 alc883_M90V_speaker_automute(codec);
8331 alc883_nb_mic_automute(codec);
8334 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8336 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8339 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8340 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8341 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8342 /* enable unsolicited event */
8343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8347 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8349 unsigned int present;
8352 present = snd_hda_codec_read(codec, 0x14, 0,
8353 AC_VERB_GET_PIN_SENSE, 0)
8354 & AC_PINSENSE_PRESENCE;
8355 bits = present ? 0 : PIN_OUT;
8356 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8360 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8363 switch (res >> 26) {
8364 case ALC880_HP_EVENT:
8365 alc883_eee1601_speaker_automute(codec);
8370 static void alc883_eee1601_inithook(struct hda_codec *codec)
8372 alc883_eee1601_speaker_automute(codec);
8375 #ifdef CONFIG_SND_HDA_POWER_SAVE
8376 #define alc883_loopbacks alc880_loopbacks
8379 /* pcm configuration: identiacal with ALC880 */
8380 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8381 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8382 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8383 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8384 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8387 * configuration and preset
8389 static const char *alc883_models[ALC883_MODEL_LAST] = {
8390 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8391 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8392 [ALC883_3ST_6ch] = "3stack-6ch",
8393 [ALC883_6ST_DIG] = "6stack-dig",
8394 [ALC883_TARGA_DIG] = "targa-dig",
8395 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8396 [ALC883_ACER] = "acer",
8397 [ALC883_ACER_ASPIRE] = "acer-aspire",
8398 [ALC883_MEDION] = "medion",
8399 [ALC883_MEDION_MD2] = "medion-md2",
8400 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8401 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8402 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8403 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8404 [ALC888_LENOVO_SKY] = "lenovo-sky",
8405 [ALC883_HAIER_W66] = "haier-w66",
8406 [ALC888_3ST_HP] = "3stack-hp",
8407 [ALC888_6ST_DELL] = "6stack-dell",
8408 [ALC883_MITAC] = "mitac",
8409 [ALC883_CLEVO_M720] = "clevo-m720",
8410 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8411 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8412 [ALC883_AUTO] = "auto",
8415 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8416 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8417 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8418 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8419 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8420 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8421 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8422 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8423 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8424 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8425 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8426 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8427 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8428 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8429 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8430 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8431 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8432 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8433 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8434 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8435 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8436 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8437 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8438 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8439 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8440 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8441 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8442 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8443 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8444 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8445 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8446 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8447 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8448 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8449 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8450 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8451 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8452 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8453 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8454 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8455 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8456 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8457 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8458 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8459 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8460 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8461 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8462 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8463 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8464 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8465 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8466 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8467 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8468 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8469 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8470 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8471 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8472 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8473 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8474 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8475 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8476 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8480 static struct alc_config_preset alc883_presets[] = {
8481 [ALC883_3ST_2ch_DIG] = {
8482 .mixers = { alc883_3ST_2ch_mixer },
8483 .init_verbs = { alc883_init_verbs },
8484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8485 .dac_nids = alc883_dac_nids,
8486 .dig_out_nid = ALC883_DIGOUT_NID,
8487 .dig_in_nid = ALC883_DIGIN_NID,
8488 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8489 .channel_mode = alc883_3ST_2ch_modes,
8490 .input_mux = &alc883_capture_source,
8492 [ALC883_3ST_6ch_DIG] = {
8493 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8494 .init_verbs = { alc883_init_verbs },
8495 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8496 .dac_nids = alc883_dac_nids,
8497 .dig_out_nid = ALC883_DIGOUT_NID,
8498 .dig_in_nid = ALC883_DIGIN_NID,
8499 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8500 .channel_mode = alc883_3ST_6ch_modes,
8502 .input_mux = &alc883_capture_source,
8504 [ALC883_3ST_6ch] = {
8505 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8506 .init_verbs = { alc883_init_verbs },
8507 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8508 .dac_nids = alc883_dac_nids,
8509 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8510 .channel_mode = alc883_3ST_6ch_modes,
8512 .input_mux = &alc883_capture_source,
8514 [ALC883_3ST_6ch_INTEL] = {
8515 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8516 .init_verbs = { alc883_init_verbs },
8517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8518 .dac_nids = alc883_dac_nids,
8519 .dig_out_nid = ALC883_DIGOUT_NID,
8520 .dig_in_nid = ALC883_DIGIN_NID,
8521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8522 .channel_mode = alc883_3ST_6ch_intel_modes,
8524 .input_mux = &alc883_3stack_6ch_intel,
8526 [ALC883_6ST_DIG] = {
8527 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8528 .init_verbs = { alc883_init_verbs },
8529 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8530 .dac_nids = alc883_dac_nids,
8531 .dig_out_nid = ALC883_DIGOUT_NID,
8532 .dig_in_nid = ALC883_DIGIN_NID,
8533 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8534 .channel_mode = alc883_sixstack_modes,
8535 .input_mux = &alc883_capture_source,
8537 [ALC883_TARGA_DIG] = {
8538 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8539 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8541 .dac_nids = alc883_dac_nids,
8542 .dig_out_nid = ALC883_DIGOUT_NID,
8543 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8544 .channel_mode = alc883_3ST_6ch_modes,
8546 .input_mux = &alc883_capture_source,
8547 .unsol_event = alc883_tagra_unsol_event,
8548 .init_hook = alc883_tagra_automute,
8550 [ALC883_TARGA_2ch_DIG] = {
8551 .mixers = { alc883_tagra_2ch_mixer},
8552 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8553 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8554 .dac_nids = alc883_dac_nids,
8555 .dig_out_nid = ALC883_DIGOUT_NID,
8556 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8557 .channel_mode = alc883_3ST_2ch_modes,
8558 .input_mux = &alc883_capture_source,
8559 .unsol_event = alc883_tagra_unsol_event,
8560 .init_hook = alc883_tagra_automute,
8563 .mixers = { alc883_base_mixer },
8564 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8565 * and the headphone jack. Turn this on and rely on the
8566 * standard mute methods whenever the user wants to turn
8567 * these outputs off.
8569 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8571 .dac_nids = alc883_dac_nids,
8572 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8573 .channel_mode = alc883_3ST_2ch_modes,
8574 .input_mux = &alc883_capture_source,
8576 [ALC883_ACER_ASPIRE] = {
8577 .mixers = { alc883_acer_aspire_mixer },
8578 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8579 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8580 .dac_nids = alc883_dac_nids,
8581 .dig_out_nid = ALC883_DIGOUT_NID,
8582 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8583 .channel_mode = alc883_3ST_2ch_modes,
8584 .input_mux = &alc883_capture_source,
8585 .unsol_event = alc883_acer_aspire_unsol_event,
8586 .init_hook = alc883_acer_aspire_automute,
8589 .mixers = { alc883_fivestack_mixer,
8590 alc883_chmode_mixer },
8591 .init_verbs = { alc883_init_verbs,
8592 alc883_medion_eapd_verbs },
8593 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8594 .dac_nids = alc883_dac_nids,
8595 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8596 .channel_mode = alc883_sixstack_modes,
8597 .input_mux = &alc883_capture_source,
8599 [ALC883_MEDION_MD2] = {
8600 .mixers = { alc883_medion_md2_mixer},
8601 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8602 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8603 .dac_nids = alc883_dac_nids,
8604 .dig_out_nid = ALC883_DIGOUT_NID,
8605 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8606 .channel_mode = alc883_3ST_2ch_modes,
8607 .input_mux = &alc883_capture_source,
8608 .unsol_event = alc883_medion_md2_unsol_event,
8609 .init_hook = alc883_medion_md2_automute,
8611 [ALC883_LAPTOP_EAPD] = {
8612 .mixers = { alc883_base_mixer },
8613 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8614 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8615 .dac_nids = alc883_dac_nids,
8616 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8617 .channel_mode = alc883_3ST_2ch_modes,
8618 .input_mux = &alc883_capture_source,
8620 [ALC883_CLEVO_M720] = {
8621 .mixers = { alc883_clevo_m720_mixer },
8622 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8623 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8624 .dac_nids = alc883_dac_nids,
8625 .dig_out_nid = ALC883_DIGOUT_NID,
8626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8627 .channel_mode = alc883_3ST_2ch_modes,
8628 .input_mux = &alc883_capture_source,
8629 .unsol_event = alc883_clevo_m720_unsol_event,
8630 .init_hook = alc883_clevo_m720_automute,
8632 [ALC883_LENOVO_101E_2ch] = {
8633 .mixers = { alc883_lenovo_101e_2ch_mixer},
8634 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8635 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8636 .dac_nids = alc883_dac_nids,
8637 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8638 .channel_mode = alc883_3ST_2ch_modes,
8639 .input_mux = &alc883_lenovo_101e_capture_source,
8640 .unsol_event = alc883_lenovo_101e_unsol_event,
8641 .init_hook = alc883_lenovo_101e_all_automute,
8643 [ALC883_LENOVO_NB0763] = {
8644 .mixers = { alc883_lenovo_nb0763_mixer },
8645 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8646 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8647 .dac_nids = alc883_dac_nids,
8648 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8649 .channel_mode = alc883_3ST_2ch_modes,
8651 .input_mux = &alc883_lenovo_nb0763_capture_source,
8652 .unsol_event = alc883_medion_md2_unsol_event,
8653 .init_hook = alc883_medion_md2_automute,
8655 [ALC888_LENOVO_MS7195_DIG] = {
8656 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8657 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8658 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8659 .dac_nids = alc883_dac_nids,
8660 .dig_out_nid = ALC883_DIGOUT_NID,
8661 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8662 .channel_mode = alc883_3ST_6ch_modes,
8664 .input_mux = &alc883_capture_source,
8665 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8666 .init_hook = alc888_lenovo_ms7195_front_automute,
8668 [ALC883_HAIER_W66] = {
8669 .mixers = { alc883_tagra_2ch_mixer},
8670 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8671 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8672 .dac_nids = alc883_dac_nids,
8673 .dig_out_nid = ALC883_DIGOUT_NID,
8674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8675 .channel_mode = alc883_3ST_2ch_modes,
8676 .input_mux = &alc883_capture_source,
8677 .unsol_event = alc883_haier_w66_unsol_event,
8678 .init_hook = alc883_haier_w66_automute,
8681 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8682 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8683 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8684 .dac_nids = alc883_dac_nids,
8685 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8686 .channel_mode = alc888_3st_hp_modes,
8688 .input_mux = &alc883_capture_source,
8690 [ALC888_6ST_DELL] = {
8691 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8692 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8694 .dac_nids = alc883_dac_nids,
8695 .dig_out_nid = ALC883_DIGOUT_NID,
8696 .dig_in_nid = ALC883_DIGIN_NID,
8697 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8698 .channel_mode = alc883_sixstack_modes,
8699 .input_mux = &alc883_capture_source,
8700 .unsol_event = alc888_6st_dell_unsol_event,
8701 .init_hook = alc888_6st_dell_front_automute,
8704 .mixers = { alc883_mitac_mixer },
8705 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8707 .dac_nids = alc883_dac_nids,
8708 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8709 .channel_mode = alc883_3ST_2ch_modes,
8710 .input_mux = &alc883_capture_source,
8711 .unsol_event = alc883_mitac_unsol_event,
8712 .init_hook = alc883_mitac_automute,
8714 [ALC883_FUJITSU_PI2515] = {
8715 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8716 .init_verbs = { alc883_init_verbs,
8717 alc883_2ch_fujitsu_pi2515_verbs},
8718 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8719 .dac_nids = alc883_dac_nids,
8720 .dig_out_nid = ALC883_DIGOUT_NID,
8721 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8722 .channel_mode = alc883_3ST_2ch_modes,
8723 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8724 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8725 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8727 [ALC888_LENOVO_SKY] = {
8728 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8729 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8730 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8731 .dac_nids = alc883_dac_nids,
8732 .dig_out_nid = ALC883_DIGOUT_NID,
8733 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8734 .adc_nids = alc883_adc_nids,
8735 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8736 .channel_mode = alc883_sixstack_modes,
8738 .input_mux = &alc883_lenovo_sky_capture_source,
8739 .unsol_event = alc883_lenovo_sky_unsol_event,
8740 .init_hook = alc888_lenovo_sky_front_automute,
8742 [ALC888_ASUS_M90V] = {
8743 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8744 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8745 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8746 .dac_nids = alc883_dac_nids,
8747 .dig_out_nid = ALC883_DIGOUT_NID,
8748 .dig_in_nid = ALC883_DIGIN_NID,
8749 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8750 .channel_mode = alc883_3ST_6ch_modes,
8752 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8753 .unsol_event = alc883_mode2_unsol_event,
8754 .init_hook = alc883_mode2_inithook,
8756 [ALC888_ASUS_EEE1601] = {
8757 .mixers = { alc883_asus_eee1601_mixer },
8758 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8760 .dac_nids = alc883_dac_nids,
8761 .dig_out_nid = ALC883_DIGOUT_NID,
8762 .dig_in_nid = ALC883_DIGIN_NID,
8763 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8764 .channel_mode = alc883_3ST_2ch_modes,
8766 .input_mux = &alc883_asus_eee1601_capture_source,
8767 .unsol_event = alc883_eee1601_unsol_event,
8768 .init_hook = alc883_eee1601_inithook,
8774 * BIOS auto configuration
8776 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8777 hda_nid_t nid, int pin_type,
8781 struct alc_spec *spec = codec->spec;
8784 alc_set_pin_output(codec, nid, pin_type);
8785 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8788 idx = spec->multiout.dac_nids[dac_idx] - 2;
8789 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8793 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8795 struct alc_spec *spec = codec->spec;
8798 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8799 for (i = 0; i <= HDA_SIDE; i++) {
8800 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8801 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8803 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8808 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8810 struct alc_spec *spec = codec->spec;
8813 pin = spec->autocfg.hp_pins[0];
8814 if (pin) /* connect to front */
8816 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8817 pin = spec->autocfg.speaker_pins[0];
8819 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8822 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8823 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8825 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8827 struct alc_spec *spec = codec->spec;
8830 for (i = 0; i < AUTO_PIN_LAST; i++) {
8831 hda_nid_t nid = spec->autocfg.input_pins[i];
8832 if (alc883_is_input_pin(nid)) {
8833 snd_hda_codec_write(codec, nid, 0,
8834 AC_VERB_SET_PIN_WIDGET_CONTROL,
8835 (i <= AUTO_PIN_FRONT_MIC ?
8836 PIN_VREF80 : PIN_IN));
8837 if (nid != ALC883_PIN_CD_NID)
8838 snd_hda_codec_write(codec, nid, 0,
8839 AC_VERB_SET_AMP_GAIN_MUTE,
8845 #define alc883_auto_init_input_src alc882_auto_init_input_src
8847 /* almost identical with ALC880 parser... */
8848 static int alc883_parse_auto_config(struct hda_codec *codec)
8850 struct alc_spec *spec = codec->spec;
8851 int err = alc880_parse_auto_config(codec);
8856 return 0; /* no config found */
8858 err = alc_auto_add_mic_boost(codec);
8862 /* hack - override the init verbs */
8863 spec->init_verbs[0] = alc883_auto_init_verbs;
8864 add_mixer(spec, alc883_capture_mixer);
8866 return 1; /* config found */
8869 /* additional initialization for auto-configuration model */
8870 static void alc883_auto_init(struct hda_codec *codec)
8872 struct alc_spec *spec = codec->spec;
8873 alc883_auto_init_multi_out(codec);
8874 alc883_auto_init_hp_out(codec);
8875 alc883_auto_init_analog_input(codec);
8876 alc883_auto_init_input_src(codec);
8877 if (spec->unsol_event)
8878 alc_inithook(codec);
8881 static int patch_alc883(struct hda_codec *codec)
8883 struct alc_spec *spec;
8884 int err, board_config;
8886 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8892 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8894 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8897 if (board_config < 0) {
8898 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8899 "trying auto-probe from BIOS...\n");
8900 board_config = ALC883_AUTO;
8903 if (board_config == ALC883_AUTO) {
8904 /* automatic parse from the BIOS config */
8905 err = alc883_parse_auto_config(codec);
8911 "hda_codec: Cannot set up configuration "
8912 "from BIOS. Using base mode...\n");
8913 board_config = ALC883_3ST_2ch_DIG;
8917 if (board_config != ALC883_AUTO)
8918 setup_preset(spec, &alc883_presets[board_config]);
8920 switch (codec->vendor_id) {
8922 if (codec->revision_id == 0x100101) {
8923 spec->stream_name_analog = "ALC1200 Analog";
8924 spec->stream_name_digital = "ALC1200 Digital";
8926 spec->stream_name_analog = "ALC888 Analog";
8927 spec->stream_name_digital = "ALC888 Digital";
8931 spec->stream_name_analog = "ALC889 Analog";
8932 spec->stream_name_digital = "ALC889 Digital";
8935 spec->stream_name_analog = "ALC883 Analog";
8936 spec->stream_name_digital = "ALC883 Digital";
8940 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8941 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8942 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8944 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8945 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8947 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8948 spec->adc_nids = alc883_adc_nids;
8949 spec->capsrc_nids = alc883_capsrc_nids;
8951 spec->vmaster_nid = 0x0c;
8953 codec->patch_ops = alc_patch_ops;
8954 if (board_config == ALC883_AUTO)
8955 spec->init_hook = alc883_auto_init;
8957 #ifdef CONFIG_SND_HDA_POWER_SAVE
8958 if (!spec->loopback.amplist)
8959 spec->loopback.amplist = alc883_loopbacks;
8969 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8970 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8972 #define alc262_dac_nids alc260_dac_nids
8973 #define alc262_adc_nids alc882_adc_nids
8974 #define alc262_adc_nids_alt alc882_adc_nids_alt
8975 #define alc262_capsrc_nids alc882_capsrc_nids
8976 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8978 #define alc262_modes alc260_modes
8979 #define alc262_capture_source alc882_capture_source
8981 static hda_nid_t alc262_dmic_adc_nids[1] = {
8986 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8988 static struct snd_kcontrol_new alc262_base_mixer[] = {
8989 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9001 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9002 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9005 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9006 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9010 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9011 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9015 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9016 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9022 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9023 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9024 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9025 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9030 /* update HP, line and mono-out pins according to the master switch */
9031 static void alc262_hp_master_update(struct hda_codec *codec)
9033 struct alc_spec *spec = codec->spec;
9034 int val = spec->master_sw;
9037 snd_hda_codec_write_cache(codec, 0x1b, 0,
9038 AC_VERB_SET_PIN_WIDGET_CONTROL,
9040 snd_hda_codec_write_cache(codec, 0x15, 0,
9041 AC_VERB_SET_PIN_WIDGET_CONTROL,
9043 /* mono (speaker) depending on the HP jack sense */
9044 val = val && !spec->jack_present;
9045 snd_hda_codec_write_cache(codec, 0x16, 0,
9046 AC_VERB_SET_PIN_WIDGET_CONTROL,
9050 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9052 struct alc_spec *spec = codec->spec;
9053 unsigned int presence;
9054 presence = snd_hda_codec_read(codec, 0x1b, 0,
9055 AC_VERB_GET_PIN_SENSE, 0);
9056 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9057 alc262_hp_master_update(codec);
9060 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9062 if ((res >> 26) != ALC880_HP_EVENT)
9064 alc262_hp_bpc_automute(codec);
9067 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9069 struct alc_spec *spec = codec->spec;
9070 unsigned int presence;
9071 presence = snd_hda_codec_read(codec, 0x15, 0,
9072 AC_VERB_GET_PIN_SENSE, 0);
9073 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9074 alc262_hp_master_update(codec);
9077 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9080 if ((res >> 26) != ALC880_HP_EVENT)
9082 alc262_hp_wildwest_automute(codec);
9085 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9086 struct snd_ctl_elem_value *ucontrol)
9088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9089 struct alc_spec *spec = codec->spec;
9090 *ucontrol->value.integer.value = spec->master_sw;
9094 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9095 struct snd_ctl_elem_value *ucontrol)
9097 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9098 struct alc_spec *spec = codec->spec;
9099 int val = !!*ucontrol->value.integer.value;
9101 if (val == spec->master_sw)
9103 spec->master_sw = val;
9104 alc262_hp_master_update(codec);
9108 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9111 .name = "Master Playback Switch",
9112 .info = snd_ctl_boolean_mono_info,
9113 .get = alc262_hp_master_sw_get,
9114 .put = alc262_hp_master_sw_put,
9116 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9117 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9119 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9121 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9127 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9133 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9134 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9135 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9136 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9140 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9143 .name = "Master Playback Switch",
9144 .info = snd_ctl_boolean_mono_info,
9145 .get = alc262_hp_master_sw_get,
9146 .put = alc262_hp_master_sw_put,
9148 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9149 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9150 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9152 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9154 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9156 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9157 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9158 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9160 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9161 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9163 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9164 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9168 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9169 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9170 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9175 /* mute/unmute internal speaker according to the hp jack and mute state */
9176 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9178 struct alc_spec *spec = codec->spec;
9180 if (force || !spec->sense_updated) {
9181 unsigned int present;
9182 present = snd_hda_codec_read(codec, 0x15, 0,
9183 AC_VERB_GET_PIN_SENSE, 0);
9184 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9185 spec->sense_updated = 1;
9187 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9188 spec->jack_present ? HDA_AMP_MUTE : 0);
9191 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9194 if ((res >> 26) != ALC880_HP_EVENT)
9196 alc262_hp_t5735_automute(codec, 1);
9199 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9201 alc262_hp_t5735_automute(codec, 1);
9204 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9210 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9215 static struct hda_verb alc262_hp_t5735_verbs[] = {
9216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9219 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9223 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9225 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9226 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9227 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9228 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9229 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9233 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9234 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9235 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9236 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9237 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9238 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9239 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9241 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9243 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9247 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9254 /* bind hp and internal speaker mute (with plug check) */
9255 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9256 struct snd_ctl_elem_value *ucontrol)
9258 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9259 long *valp = ucontrol->value.integer.value;
9262 /* change hp mute */
9263 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9265 valp[0] ? 0 : HDA_AMP_MUTE);
9266 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9268 valp[1] ? 0 : HDA_AMP_MUTE);
9270 /* change speaker according to HP jack state */
9271 struct alc_spec *spec = codec->spec;
9273 if (spec->jack_present)
9274 mute = HDA_AMP_MUTE;
9276 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9278 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9279 HDA_AMP_MUTE, mute);
9284 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9285 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9288 .name = "Master Playback Switch",
9289 .info = snd_hda_mixer_amp_switch_info,
9290 .get = snd_hda_mixer_amp_switch_get,
9291 .put = alc262_sony_master_sw_put,
9292 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9296 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9297 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9301 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9303 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9307 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9308 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9312 #define alc262_capture_mixer alc882_capture_mixer
9313 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9316 * generic initialization of ADC, input mixers and output mixers
9318 static struct hda_verb alc262_init_verbs[] = {
9320 * Unmute ADC0-2 and set the default input to mic-in
9322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9331 * Note: PASD motherboards uses the Line In 2 as the input for
9332 * front panel mic (mic 2)
9334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9342 * Set up output mixers (0x0c - 0x0e)
9344 /* set vol=0 to output mixers */
9345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9348 /* set up input amps for analog loopback */
9349 /* Amp Indices: DAC = 0, mixer = 1 */
9350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9359 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9360 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9362 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9367 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9368 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9370 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9373 /* FIXME: use matrix-type input source selection */
9374 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9375 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9394 static struct hda_verb alc262_eapd_verbs[] = {
9395 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9396 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9400 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9402 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9406 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9408 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9416 static struct hda_verb alc262_sony_unsol_verbs[] = {
9417 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9419 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9421 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9426 static struct hda_input_mux alc262_dmic_capture_source = {
9429 { "Int DMic", 0x9 },
9434 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9436 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9441 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9444 /* The multiple "Capture Source" controls confuse alsamixer
9445 * So call somewhat different..
9447 /* .name = "Capture Source", */
9448 .name = "Input Source",
9450 .info = alc_mux_enum_info,
9451 .get = alc_mux_enum_get,
9452 .put = alc_mux_enum_put,
9457 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9458 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9462 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9463 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9469 static void alc262_dmic_automute(struct hda_codec *codec)
9471 unsigned int present;
9473 present = snd_hda_codec_read(codec, 0x18, 0,
9474 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9475 snd_hda_codec_write(codec, 0x22, 0,
9476 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9479 /* toggle speaker-output according to the hp-jack state */
9480 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9482 unsigned int present;
9485 present = snd_hda_codec_read(codec, 0x15, 0,
9486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9487 bits = present ? 0 : PIN_OUT;
9488 snd_hda_codec_write(codec, 0x14, 0,
9489 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9494 /* unsolicited event for HP jack sensing */
9495 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9498 if ((res >> 26) == ALC880_HP_EVENT)
9499 alc262_toshiba_s06_speaker_automute(codec);
9500 if ((res >> 26) == ALC880_MIC_EVENT)
9501 alc262_dmic_automute(codec);
9505 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9507 alc262_toshiba_s06_speaker_automute(codec);
9508 alc262_dmic_automute(codec);
9511 /* mute/unmute internal speaker according to the hp jack and mute state */
9512 static void alc262_hippo_automute(struct hda_codec *codec)
9514 struct alc_spec *spec = codec->spec;
9516 unsigned int present;
9518 /* need to execute and sync at first */
9519 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9520 present = snd_hda_codec_read(codec, 0x15, 0,
9521 AC_VERB_GET_PIN_SENSE, 0);
9522 spec->jack_present = (present & 0x80000000) != 0;
9523 if (spec->jack_present) {
9524 /* mute internal speaker */
9525 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9526 HDA_AMP_MUTE, HDA_AMP_MUTE);
9528 /* unmute internal speaker if necessary */
9529 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9530 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9531 HDA_AMP_MUTE, mute);
9535 /* unsolicited event for HP jack sensing */
9536 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9539 if ((res >> 26) != ALC880_HP_EVENT)
9541 alc262_hippo_automute(codec);
9544 static void alc262_hippo1_automute(struct hda_codec *codec)
9547 unsigned int present;
9549 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9550 present = snd_hda_codec_read(codec, 0x1b, 0,
9551 AC_VERB_GET_PIN_SENSE, 0);
9552 present = (present & 0x80000000) != 0;
9554 /* mute internal speaker */
9555 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9556 HDA_AMP_MUTE, HDA_AMP_MUTE);
9558 /* unmute internal speaker if necessary */
9559 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9560 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9561 HDA_AMP_MUTE, mute);
9565 /* unsolicited event for HP jack sensing */
9566 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9569 if ((res >> 26) != ALC880_HP_EVENT)
9571 alc262_hippo1_automute(codec);
9577 * 0x16 = internal speaker
9578 * 0x18 = external mic
9581 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9582 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9583 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9587 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9589 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9594 static struct hda_verb alc262_nec_verbs[] = {
9595 /* Unmute Speaker */
9596 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9599 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9602 /* External mic to headphone */
9603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9604 /* External mic to speaker */
9605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9611 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9612 * 0x1b = port replicator headphone out
9615 #define ALC_HP_EVENT 0x37
9617 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9621 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9625 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9631 static struct hda_input_mux alc262_fujitsu_capture_source = {
9640 static struct hda_input_mux alc262_HP_capture_source = {
9644 { "Front Mic", 0x1 },
9651 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9655 { "Front Mic", 0x2 },
9661 /* mute/unmute internal speaker according to the hp jacks and mute state */
9662 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9664 struct alc_spec *spec = codec->spec;
9667 if (force || !spec->sense_updated) {
9668 unsigned int present;
9669 /* need to execute and sync at first */
9670 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9671 /* check laptop HP jack */
9672 present = snd_hda_codec_read(codec, 0x14, 0,
9673 AC_VERB_GET_PIN_SENSE, 0);
9674 /* need to execute and sync at first */
9675 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9676 /* check docking HP jack */
9677 present |= snd_hda_codec_read(codec, 0x1b, 0,
9678 AC_VERB_GET_PIN_SENSE, 0);
9679 if (present & AC_PINSENSE_PRESENCE)
9680 spec->jack_present = 1;
9682 spec->jack_present = 0;
9683 spec->sense_updated = 1;
9685 /* unmute internal speaker only if both HPs are unplugged and
9686 * master switch is on
9688 if (spec->jack_present)
9689 mute = HDA_AMP_MUTE;
9691 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9692 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9693 HDA_AMP_MUTE, mute);
9696 /* unsolicited event for HP jack sensing */
9697 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9700 if ((res >> 26) != ALC_HP_EVENT)
9702 alc262_fujitsu_automute(codec, 1);
9705 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9707 alc262_fujitsu_automute(codec, 1);
9710 /* bind volumes of both NID 0x0c and 0x0d */
9711 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9712 .ops = &snd_hda_bind_vol,
9714 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9715 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9720 /* mute/unmute internal speaker according to the hp jack and mute state */
9721 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9723 struct alc_spec *spec = codec->spec;
9726 if (force || !spec->sense_updated) {
9727 unsigned int present_int_hp;
9728 /* need to execute and sync at first */
9729 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9730 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9731 AC_VERB_GET_PIN_SENSE, 0);
9732 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9733 spec->sense_updated = 1;
9735 if (spec->jack_present) {
9736 /* mute internal speaker */
9737 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9738 HDA_AMP_MUTE, HDA_AMP_MUTE);
9739 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9740 HDA_AMP_MUTE, HDA_AMP_MUTE);
9742 /* unmute internal speaker if necessary */
9743 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9745 HDA_AMP_MUTE, mute);
9746 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9747 HDA_AMP_MUTE, mute);
9751 /* unsolicited event for HP jack sensing */
9752 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9755 if ((res >> 26) != ALC_HP_EVENT)
9757 alc262_lenovo_3000_automute(codec, 1);
9760 /* bind hp and internal speaker mute (with plug check) */
9761 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9762 struct snd_ctl_elem_value *ucontrol)
9764 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9765 long *valp = ucontrol->value.integer.value;
9768 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9770 valp ? 0 : HDA_AMP_MUTE);
9771 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9773 valp ? 0 : HDA_AMP_MUTE);
9776 alc262_fujitsu_automute(codec, 0);
9780 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9781 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9784 .name = "Master Playback Switch",
9785 .info = snd_hda_mixer_amp_switch_info,
9786 .get = snd_hda_mixer_amp_switch_get,
9787 .put = alc262_fujitsu_master_sw_put,
9788 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9790 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9791 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9792 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9793 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9797 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9798 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9799 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9803 /* bind hp and internal speaker mute (with plug check) */
9804 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9805 struct snd_ctl_elem_value *ucontrol)
9807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9808 long *valp = ucontrol->value.integer.value;
9811 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9813 valp ? 0 : HDA_AMP_MUTE);
9816 alc262_lenovo_3000_automute(codec, 0);
9820 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9821 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9824 .name = "Master Playback Switch",
9825 .info = snd_hda_mixer_amp_switch_info,
9826 .get = snd_hda_mixer_amp_switch_get,
9827 .put = alc262_lenovo_3000_master_sw_put,
9828 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9830 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9831 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9835 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9836 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9837 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9841 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9842 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9845 .name = "Master Playback Switch",
9846 .info = snd_hda_mixer_amp_switch_info,
9847 .get = snd_hda_mixer_amp_switch_get,
9848 .put = alc262_sony_master_sw_put,
9849 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9854 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9855 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9856 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9860 /* additional init verbs for Benq laptops */
9861 static struct hda_verb alc262_EAPD_verbs[] = {
9862 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9863 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9867 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9871 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9872 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9876 /* Samsung Q1 Ultra Vista model setup */
9877 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9878 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9879 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9882 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9883 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9887 static struct hda_verb alc262_ultra_verbs[] = {
9889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9895 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9896 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9899 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9901 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9902 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9904 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9905 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9906 /* ADC, choose mic */
9907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9908 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9910 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9911 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9912 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9913 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9914 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9915 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9916 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9920 /* mute/unmute internal speaker according to the hp jack and mute state */
9921 static void alc262_ultra_automute(struct hda_codec *codec)
9923 struct alc_spec *spec = codec->spec;
9927 /* auto-mute only when HP is used as HP */
9928 if (!spec->cur_mux[0]) {
9929 unsigned int present;
9930 /* need to execute and sync at first */
9931 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9932 present = snd_hda_codec_read(codec, 0x15, 0,
9933 AC_VERB_GET_PIN_SENSE, 0);
9934 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9935 if (spec->jack_present)
9936 mute = HDA_AMP_MUTE;
9938 /* mute/unmute internal speaker */
9939 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9940 HDA_AMP_MUTE, mute);
9941 /* mute/unmute HP */
9942 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9943 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9946 /* unsolicited event for HP jack sensing */
9947 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9950 if ((res >> 26) != ALC880_HP_EVENT)
9952 alc262_ultra_automute(codec);
9955 static struct hda_input_mux alc262_ultra_capture_source = {
9959 { "Headphone", 0x7 },
9963 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9964 struct snd_ctl_elem_value *ucontrol)
9966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9967 struct alc_spec *spec = codec->spec;
9970 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9973 /* reprogram the HP pin as mic or HP according to the input source */
9974 snd_hda_codec_write_cache(codec, 0x15, 0,
9975 AC_VERB_SET_PIN_WIDGET_CONTROL,
9976 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9977 alc262_ultra_automute(codec); /* mute/unmute HP */
9981 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9982 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9983 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9985 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9986 .name = "Capture Source",
9987 .info = alc882_mux_enum_info,
9988 .get = alc882_mux_enum_get,
9989 .put = alc262_ultra_mux_enum_put,
9994 /* add playback controls from the parsed DAC table */
9995 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9996 const struct auto_pin_cfg *cfg)
10001 spec->multiout.num_dacs = 1; /* only use one dac */
10002 spec->multiout.dac_nids = spec->private_dac_nids;
10003 spec->multiout.dac_nids[0] = 2;
10005 nid = cfg->line_out_pins[0];
10007 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10008 "Front Playback Volume",
10009 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10012 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10013 "Front Playback Switch",
10014 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10019 nid = cfg->speaker_pins[0];
10022 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10023 "Speaker Playback Volume",
10024 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10028 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10029 "Speaker Playback Switch",
10030 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10035 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10036 "Speaker Playback Switch",
10037 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10043 nid = cfg->hp_pins[0];
10045 /* spec->multiout.hp_nid = 2; */
10047 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10048 "Headphone Playback Volume",
10049 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10053 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10054 "Headphone Playback Switch",
10055 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10060 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10061 "Headphone Playback Switch",
10062 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10071 /* identical with ALC880 */
10072 #define alc262_auto_create_analog_input_ctls \
10073 alc880_auto_create_analog_input_ctls
10076 * generic initialization of ADC, input mixers and output mixers
10078 static struct hda_verb alc262_volume_init_verbs[] = {
10080 * Unmute ADC0-2 and set the default input to mic-in
10082 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10084 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10085 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10086 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10087 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10089 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10091 * Note: PASD motherboards uses the Line In 2 as the input for
10092 * front panel mic (mic 2)
10094 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10102 * Set up output mixers (0x0c - 0x0f)
10104 /* set vol=0 to output mixers */
10105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10109 /* set up input amps for analog loopback */
10110 /* Amp Indices: DAC = 0, mixer = 1 */
10111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10112 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10114 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10118 /* FIXME: use matrix-type input source selection */
10119 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10120 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10129 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10134 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10139 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10141 * Unmute ADC0-2 and set the default input to mic-in
10143 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10145 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10148 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10150 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10152 * Note: PASD motherboards uses the Line In 2 as the input for
10153 * front panel mic (mic 2)
10155 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10159 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10160 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10161 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10162 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10165 * Set up output mixers (0x0c - 0x0e)
10167 /* set vol=0 to output mixers */
10168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10170 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10172 /* set up input amps for analog loopback */
10173 /* Amp Indices: DAC = 0, mixer = 1 */
10174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10178 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10185 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10189 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10191 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10194 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10195 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
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 },
10205 /* FIXME: use matrix-type input source selection */
10206 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10207 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10228 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10230 * Unmute ADC0-2 and set the default input to mic-in
10232 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10234 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10236 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10239 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10241 * Note: PASD motherboards uses the Line In 2 as the input for front
10242 * panel mic (mic 2)
10244 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10254 * Set up output mixers (0x0c - 0x0e)
10256 /* set vol=0 to output mixers */
10257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10261 /* set up input amps for analog loopback */
10262 /* Amp Indices: DAC = 0, mixer = 1 */
10263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10267 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10276 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10277 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10279 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10282 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10285 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10286 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10287 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10288 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10289 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10290 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10292 /* FIXME: use matrix-type input source selection */
10293 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10294 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10300 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10308 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10316 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10324 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10328 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10330 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10331 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10332 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10342 #ifdef CONFIG_SND_HDA_POWER_SAVE
10343 #define alc262_loopbacks alc880_loopbacks
10346 /* pcm configuration: identiacal with ALC880 */
10347 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10348 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10349 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10350 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10353 * BIOS auto configuration
10355 static int alc262_parse_auto_config(struct hda_codec *codec)
10357 struct alc_spec *spec = codec->spec;
10359 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10365 if (!spec->autocfg.line_outs)
10366 return 0; /* can't find valid BIOS pin config */
10367 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10370 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10374 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10376 if (spec->autocfg.dig_out_pin)
10377 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10378 if (spec->autocfg.dig_in_pin)
10379 spec->dig_in_nid = ALC262_DIGIN_NID;
10381 if (spec->kctls.list)
10382 add_mixer(spec, spec->kctls.list);
10384 add_verb(spec, alc262_volume_init_verbs);
10385 spec->num_mux_defs = 1;
10386 spec->input_mux = &spec->private_imux;
10388 err = alc_auto_add_mic_boost(codec);
10392 store_pin_configs(codec);
10396 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10397 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10398 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10399 #define alc262_auto_init_input_src alc882_auto_init_input_src
10402 /* init callback for auto-configuration model -- overriding the default init */
10403 static void alc262_auto_init(struct hda_codec *codec)
10405 struct alc_spec *spec = codec->spec;
10406 alc262_auto_init_multi_out(codec);
10407 alc262_auto_init_hp_out(codec);
10408 alc262_auto_init_analog_input(codec);
10409 alc262_auto_init_input_src(codec);
10410 if (spec->unsol_event)
10411 alc_inithook(codec);
10415 * configuration and preset
10417 static const char *alc262_models[ALC262_MODEL_LAST] = {
10418 [ALC262_BASIC] = "basic",
10419 [ALC262_HIPPO] = "hippo",
10420 [ALC262_HIPPO_1] = "hippo_1",
10421 [ALC262_FUJITSU] = "fujitsu",
10422 [ALC262_HP_BPC] = "hp-bpc",
10423 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10424 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10425 [ALC262_HP_RP5700] = "hp-rp5700",
10426 [ALC262_BENQ_ED8] = "benq",
10427 [ALC262_BENQ_T31] = "benq-t31",
10428 [ALC262_SONY_ASSAMD] = "sony-assamd",
10429 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10430 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10431 [ALC262_ULTRA] = "ultra",
10432 [ALC262_LENOVO_3000] = "lenovo-3000",
10433 [ALC262_NEC] = "nec",
10434 [ALC262_AUTO] = "auto",
10437 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10438 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10439 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10440 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10441 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10442 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10443 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10444 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10445 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10446 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10447 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10448 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10449 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10450 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10451 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10452 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10453 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10454 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10455 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10456 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10457 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10458 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10459 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10460 ALC262_HP_TC_T5735),
10461 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10462 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10463 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10464 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10465 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10466 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10467 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10468 ALC262_TOSHIBA_RX1),
10469 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10470 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10471 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10472 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10473 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10474 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10475 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10476 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10477 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10481 static struct alc_config_preset alc262_presets[] = {
10483 .mixers = { alc262_base_mixer },
10484 .init_verbs = { alc262_init_verbs },
10485 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10486 .dac_nids = alc262_dac_nids,
10488 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10489 .channel_mode = alc262_modes,
10490 .input_mux = &alc262_capture_source,
10493 .mixers = { alc262_base_mixer },
10494 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10495 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10496 .dac_nids = alc262_dac_nids,
10498 .dig_out_nid = ALC262_DIGOUT_NID,
10499 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10500 .channel_mode = alc262_modes,
10501 .input_mux = &alc262_capture_source,
10502 .unsol_event = alc262_hippo_unsol_event,
10503 .init_hook = alc262_hippo_automute,
10505 [ALC262_HIPPO_1] = {
10506 .mixers = { alc262_hippo1_mixer },
10507 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10508 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10509 .dac_nids = alc262_dac_nids,
10511 .dig_out_nid = ALC262_DIGOUT_NID,
10512 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10513 .channel_mode = alc262_modes,
10514 .input_mux = &alc262_capture_source,
10515 .unsol_event = alc262_hippo1_unsol_event,
10516 .init_hook = alc262_hippo1_automute,
10518 [ALC262_FUJITSU] = {
10519 .mixers = { alc262_fujitsu_mixer },
10520 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10521 alc262_fujitsu_unsol_verbs },
10522 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10523 .dac_nids = alc262_dac_nids,
10525 .dig_out_nid = ALC262_DIGOUT_NID,
10526 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10527 .channel_mode = alc262_modes,
10528 .input_mux = &alc262_fujitsu_capture_source,
10529 .unsol_event = alc262_fujitsu_unsol_event,
10530 .init_hook = alc262_fujitsu_init_hook,
10532 [ALC262_HP_BPC] = {
10533 .mixers = { alc262_HP_BPC_mixer },
10534 .init_verbs = { alc262_HP_BPC_init_verbs },
10535 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10536 .dac_nids = alc262_dac_nids,
10538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10539 .channel_mode = alc262_modes,
10540 .input_mux = &alc262_HP_capture_source,
10541 .unsol_event = alc262_hp_bpc_unsol_event,
10542 .init_hook = alc262_hp_bpc_automute,
10544 [ALC262_HP_BPC_D7000_WF] = {
10545 .mixers = { alc262_HP_BPC_WildWest_mixer },
10546 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10547 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10548 .dac_nids = alc262_dac_nids,
10550 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10551 .channel_mode = alc262_modes,
10552 .input_mux = &alc262_HP_D7000_capture_source,
10553 .unsol_event = alc262_hp_wildwest_unsol_event,
10554 .init_hook = alc262_hp_wildwest_automute,
10556 [ALC262_HP_BPC_D7000_WL] = {
10557 .mixers = { alc262_HP_BPC_WildWest_mixer,
10558 alc262_HP_BPC_WildWest_option_mixer },
10559 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10560 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10561 .dac_nids = alc262_dac_nids,
10563 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10564 .channel_mode = alc262_modes,
10565 .input_mux = &alc262_HP_D7000_capture_source,
10566 .unsol_event = alc262_hp_wildwest_unsol_event,
10567 .init_hook = alc262_hp_wildwest_automute,
10569 [ALC262_HP_TC_T5735] = {
10570 .mixers = { alc262_hp_t5735_mixer },
10571 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10572 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10573 .dac_nids = alc262_dac_nids,
10575 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10576 .channel_mode = alc262_modes,
10577 .input_mux = &alc262_capture_source,
10578 .unsol_event = alc262_hp_t5735_unsol_event,
10579 .init_hook = alc262_hp_t5735_init_hook,
10581 [ALC262_HP_RP5700] = {
10582 .mixers = { alc262_hp_rp5700_mixer },
10583 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10584 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10585 .dac_nids = alc262_dac_nids,
10586 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10587 .channel_mode = alc262_modes,
10588 .input_mux = &alc262_hp_rp5700_capture_source,
10590 [ALC262_BENQ_ED8] = {
10591 .mixers = { alc262_base_mixer },
10592 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10593 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10594 .dac_nids = alc262_dac_nids,
10596 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10597 .channel_mode = alc262_modes,
10598 .input_mux = &alc262_capture_source,
10600 [ALC262_SONY_ASSAMD] = {
10601 .mixers = { alc262_sony_mixer },
10602 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10603 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10604 .dac_nids = alc262_dac_nids,
10606 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10607 .channel_mode = alc262_modes,
10608 .input_mux = &alc262_capture_source,
10609 .unsol_event = alc262_hippo_unsol_event,
10610 .init_hook = alc262_hippo_automute,
10612 [ALC262_BENQ_T31] = {
10613 .mixers = { alc262_benq_t31_mixer },
10614 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10615 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10616 .dac_nids = alc262_dac_nids,
10618 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10619 .channel_mode = alc262_modes,
10620 .input_mux = &alc262_capture_source,
10621 .unsol_event = alc262_hippo_unsol_event,
10622 .init_hook = alc262_hippo_automute,
10625 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10626 .init_verbs = { alc262_ultra_verbs },
10627 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10628 .dac_nids = alc262_dac_nids,
10629 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10630 .channel_mode = alc262_modes,
10631 .input_mux = &alc262_ultra_capture_source,
10632 .adc_nids = alc262_adc_nids, /* ADC0 */
10633 .capsrc_nids = alc262_capsrc_nids,
10634 .num_adc_nids = 1, /* single ADC */
10635 .unsol_event = alc262_ultra_unsol_event,
10636 .init_hook = alc262_ultra_automute,
10638 [ALC262_LENOVO_3000] = {
10639 .mixers = { alc262_lenovo_3000_mixer },
10640 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10641 alc262_lenovo_3000_unsol_verbs },
10642 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10643 .dac_nids = alc262_dac_nids,
10645 .dig_out_nid = ALC262_DIGOUT_NID,
10646 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10647 .channel_mode = alc262_modes,
10648 .input_mux = &alc262_fujitsu_capture_source,
10649 .unsol_event = alc262_lenovo_3000_unsol_event,
10652 .mixers = { alc262_nec_mixer },
10653 .init_verbs = { alc262_nec_verbs },
10654 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10655 .dac_nids = alc262_dac_nids,
10657 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10658 .channel_mode = alc262_modes,
10659 .input_mux = &alc262_capture_source,
10661 [ALC262_TOSHIBA_S06] = {
10662 .mixers = { alc262_toshiba_s06_mixer },
10663 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10664 alc262_eapd_verbs },
10665 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10666 .capsrc_nids = alc262_dmic_capsrc_nids,
10667 .dac_nids = alc262_dac_nids,
10668 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10669 .dig_out_nid = ALC262_DIGOUT_NID,
10670 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10671 .channel_mode = alc262_modes,
10672 .input_mux = &alc262_dmic_capture_source,
10673 .unsol_event = alc262_toshiba_s06_unsol_event,
10674 .init_hook = alc262_toshiba_s06_init_hook,
10676 [ALC262_TOSHIBA_RX1] = {
10677 .mixers = { alc262_toshiba_rx1_mixer },
10678 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10679 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10680 .dac_nids = alc262_dac_nids,
10682 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10683 .channel_mode = alc262_modes,
10684 .input_mux = &alc262_capture_source,
10685 .unsol_event = alc262_hippo_unsol_event,
10686 .init_hook = alc262_hippo_automute,
10690 static int patch_alc262(struct hda_codec *codec)
10692 struct alc_spec *spec;
10696 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10700 codec->spec = spec;
10702 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10707 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10708 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10709 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10710 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10714 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10716 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10720 if (board_config < 0) {
10721 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10722 "trying auto-probe from BIOS...\n");
10723 board_config = ALC262_AUTO;
10726 if (board_config == ALC262_AUTO) {
10727 /* automatic parse from the BIOS config */
10728 err = alc262_parse_auto_config(codec);
10734 "hda_codec: Cannot set up configuration "
10735 "from BIOS. Using base mode...\n");
10736 board_config = ALC262_BASIC;
10740 if (board_config != ALC262_AUTO)
10741 setup_preset(spec, &alc262_presets[board_config]);
10743 spec->stream_name_analog = "ALC262 Analog";
10744 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10745 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10747 spec->stream_name_digital = "ALC262 Digital";
10748 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10749 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10751 if (!spec->adc_nids && spec->input_mux) {
10752 /* check whether NID 0x07 is valid */
10753 unsigned int wcap = get_wcaps(codec, 0x07);
10756 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10757 if (wcap != AC_WID_AUD_IN) {
10758 spec->adc_nids = alc262_adc_nids_alt;
10759 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10760 spec->capsrc_nids = alc262_capsrc_nids_alt;
10761 add_mixer(spec, alc262_capture_alt_mixer);
10763 spec->adc_nids = alc262_adc_nids;
10764 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10765 spec->capsrc_nids = alc262_capsrc_nids;
10766 add_mixer(spec, alc262_capture_mixer);
10770 spec->vmaster_nid = 0x0c;
10772 codec->patch_ops = alc_patch_ops;
10773 if (board_config == ALC262_AUTO)
10774 spec->init_hook = alc262_auto_init;
10775 #ifdef CONFIG_SND_HDA_POWER_SAVE
10776 if (!spec->loopback.amplist)
10777 spec->loopback.amplist = alc262_loopbacks;
10784 * ALC268 channel source setting (2 channel)
10786 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10787 #define alc268_modes alc260_modes
10789 static hda_nid_t alc268_dac_nids[2] = {
10794 static hda_nid_t alc268_adc_nids[2] = {
10799 static hda_nid_t alc268_adc_nids_alt[1] = {
10804 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10806 static struct snd_kcontrol_new alc268_base_mixer[] = {
10807 /* output mixer control */
10808 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10809 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10812 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10813 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10814 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10818 /* bind Beep switches of both NID 0x0f and 0x10 */
10819 static struct hda_bind_ctls alc268_bind_beep_sw = {
10820 .ops = &snd_hda_bind_sw,
10822 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10823 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10828 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10829 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10830 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10834 static struct hda_verb alc268_eapd_verbs[] = {
10835 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10836 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10840 /* Toshiba specific */
10841 #define alc268_toshiba_automute alc262_hippo_automute
10843 static struct hda_verb alc268_toshiba_verbs[] = {
10844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10848 static struct hda_input_mux alc268_acer_lc_capture_source = {
10856 /* Acer specific */
10857 /* bind volumes of both NID 0x02 and 0x03 */
10858 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10859 .ops = &snd_hda_bind_vol,
10861 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10862 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10867 /* mute/unmute internal speaker according to the hp jack and mute state */
10868 static void alc268_acer_automute(struct hda_codec *codec, int force)
10870 struct alc_spec *spec = codec->spec;
10873 if (force || !spec->sense_updated) {
10874 unsigned int present;
10875 present = snd_hda_codec_read(codec, 0x14, 0,
10876 AC_VERB_GET_PIN_SENSE, 0);
10877 spec->jack_present = (present & 0x80000000) != 0;
10878 spec->sense_updated = 1;
10880 if (spec->jack_present)
10881 mute = HDA_AMP_MUTE; /* mute internal speaker */
10882 else /* unmute internal speaker if necessary */
10883 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10884 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10885 HDA_AMP_MUTE, mute);
10889 /* bind hp and internal speaker mute (with plug check) */
10890 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10891 struct snd_ctl_elem_value *ucontrol)
10893 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10894 long *valp = ucontrol->value.integer.value;
10897 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10899 valp[0] ? 0 : HDA_AMP_MUTE);
10900 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10902 valp[1] ? 0 : HDA_AMP_MUTE);
10904 alc268_acer_automute(codec, 0);
10908 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10909 /* output mixer control */
10910 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10913 .name = "Master Playback Switch",
10914 .info = snd_hda_mixer_amp_switch_info,
10915 .get = snd_hda_mixer_amp_switch_get,
10916 .put = alc268_acer_master_sw_put,
10917 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10919 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10923 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10924 /* output mixer control */
10925 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10928 .name = "Master Playback Switch",
10929 .info = snd_hda_mixer_amp_switch_info,
10930 .get = snd_hda_mixer_amp_switch_get,
10931 .put = alc268_acer_master_sw_put,
10932 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10935 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10936 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10940 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10944 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10945 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10950 static struct hda_verb alc268_acer_verbs[] = {
10951 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10952 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10955 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10961 /* unsolicited event for HP jack sensing */
10962 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10965 if ((res >> 26) != ALC880_HP_EVENT)
10967 alc268_toshiba_automute(codec);
10970 static void alc268_acer_unsol_event(struct hda_codec *codec,
10973 if ((res >> 26) != ALC880_HP_EVENT)
10975 alc268_acer_automute(codec, 1);
10978 static void alc268_acer_init_hook(struct hda_codec *codec)
10980 alc268_acer_automute(codec, 1);
10983 /* toggle speaker-output according to the hp-jack state */
10984 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10986 unsigned int present;
10987 unsigned char bits;
10989 present = snd_hda_codec_read(codec, 0x15, 0,
10990 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10991 bits = present ? AMP_IN_MUTE(0) : 0;
10992 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10993 AMP_IN_MUTE(0), bits);
10994 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10995 AMP_IN_MUTE(0), bits);
10999 static void alc268_acer_mic_automute(struct hda_codec *codec)
11001 unsigned int present;
11003 present = snd_hda_codec_read(codec, 0x18, 0,
11004 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11005 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11006 present ? 0x0 : 0x6);
11009 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11012 if ((res >> 26) == ALC880_HP_EVENT)
11013 alc268_aspire_one_speaker_automute(codec);
11014 if ((res >> 26) == ALC880_MIC_EVENT)
11015 alc268_acer_mic_automute(codec);
11018 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11020 alc268_aspire_one_speaker_automute(codec);
11021 alc268_acer_mic_automute(codec);
11024 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11025 /* output mixer control */
11026 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11027 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11028 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11030 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11031 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11035 static struct hda_verb alc268_dell_verbs[] = {
11036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11038 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11042 /* mute/unmute internal speaker according to the hp jack and mute state */
11043 static void alc268_dell_automute(struct hda_codec *codec)
11045 unsigned int present;
11048 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11049 if (present & 0x80000000)
11050 mute = HDA_AMP_MUTE;
11052 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11053 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11054 HDA_AMP_MUTE, mute);
11057 static void alc268_dell_unsol_event(struct hda_codec *codec,
11060 if ((res >> 26) != ALC880_HP_EVENT)
11062 alc268_dell_automute(codec);
11065 #define alc268_dell_init_hook alc268_dell_automute
11067 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11068 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11069 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11072 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11073 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11074 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11075 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11079 static struct hda_verb alc267_quanta_il1_verbs[] = {
11080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11081 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11085 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11087 unsigned int present;
11089 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11090 & AC_PINSENSE_PRESENCE;
11091 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11092 present ? 0 : PIN_OUT);
11095 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11097 unsigned int present;
11099 present = snd_hda_codec_read(codec, 0x18, 0,
11100 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11101 snd_hda_codec_write(codec, 0x23, 0,
11102 AC_VERB_SET_CONNECT_SEL,
11103 present ? 0x00 : 0x01);
11106 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11108 alc267_quanta_il1_hp_automute(codec);
11109 alc267_quanta_il1_mic_automute(codec);
11112 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11115 switch (res >> 26) {
11116 case ALC880_HP_EVENT:
11117 alc267_quanta_il1_hp_automute(codec);
11119 case ALC880_MIC_EVENT:
11120 alc267_quanta_il1_mic_automute(codec);
11126 * generic initialization of ADC, input mixers and output mixers
11128 static struct hda_verb alc268_base_init_verbs[] = {
11129 /* Unmute DAC0-1 and set vol = 0 */
11130 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11131 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11132 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11133 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11134 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11138 * Set up output mixers (0x0c - 0x0e)
11140 /* set vol=0 to output mixers */
11141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11142 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11144 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11146 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11147 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11149 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11150 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11151 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11152 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11153 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11154 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11156 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11160 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11162 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11163 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11164 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11166 /* set PCBEEP vol = 0, mute connections */
11167 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11168 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11169 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11171 /* Unmute Selector 23h,24h and set the default input to mic-in */
11173 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11174 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11175 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11176 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11182 * generic initialization of ADC, input mixers and output mixers
11184 static struct hda_verb alc268_volume_init_verbs[] = {
11185 /* set output DAC */
11186 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11187 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11188 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11189 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11192 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11194 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11195 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11197 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11201 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11203 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11204 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11206 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11208 /* set PCBEEP vol = 0, mute connections */
11209 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11211 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11216 #define alc268_mux_enum_info alc_mux_enum_info
11217 #define alc268_mux_enum_get alc_mux_enum_get
11218 #define alc268_mux_enum_put alc_mux_enum_put
11220 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11221 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11222 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11225 /* The multiple "Capture Source" controls confuse alsamixer
11226 * So call somewhat different..
11228 /* .name = "Capture Source", */
11229 .name = "Input Source",
11231 .info = alc268_mux_enum_info,
11232 .get = alc268_mux_enum_get,
11233 .put = alc268_mux_enum_put,
11238 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11239 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11240 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11241 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11242 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11245 /* The multiple "Capture Source" controls confuse alsamixer
11246 * So call somewhat different..
11248 /* .name = "Capture Source", */
11249 .name = "Input Source",
11251 .info = alc268_mux_enum_info,
11252 .get = alc268_mux_enum_get,
11253 .put = alc268_mux_enum_put,
11258 static struct hda_input_mux alc268_capture_source = {
11262 { "Front Mic", 0x1 },
11268 static struct hda_input_mux alc268_acer_capture_source = {
11272 { "Internal Mic", 0x6 },
11277 #ifdef CONFIG_SND_DEBUG
11278 static struct snd_kcontrol_new alc268_test_mixer[] = {
11279 /* Volume widgets */
11280 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11281 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11282 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11283 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11284 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11285 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11286 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11287 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11288 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11289 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11291 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11292 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11293 /* The below appears problematic on some hardwares */
11294 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11295 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11296 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11297 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11298 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11300 /* Modes for retasking pin widgets */
11301 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11302 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11303 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11304 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11306 /* Controls for GPIO pins, assuming they are configured as outputs */
11307 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11308 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11309 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11310 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11312 /* Switches to allow the digital SPDIF output pin to be enabled.
11313 * The ALC268 does not have an SPDIF input.
11315 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11317 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11318 * this output to turn on an external amplifier.
11320 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11321 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11327 /* create input playback/capture controls for the given pin */
11328 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11329 const char *ctlname, int idx)
11334 sprintf(name, "%s Playback Volume", ctlname);
11336 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11337 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11341 } else if (nid == 0x15) {
11342 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11343 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11349 sprintf(name, "%s Playback Switch", ctlname);
11350 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11351 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11357 /* add playback controls from the parsed DAC table */
11358 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11359 const struct auto_pin_cfg *cfg)
11364 spec->multiout.num_dacs = 2; /* only use one dac */
11365 spec->multiout.dac_nids = spec->private_dac_nids;
11366 spec->multiout.dac_nids[0] = 2;
11367 spec->multiout.dac_nids[1] = 3;
11369 nid = cfg->line_out_pins[0];
11371 alc268_new_analog_output(spec, nid, "Front", 0);
11373 nid = cfg->speaker_pins[0];
11375 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11376 "Speaker Playback Volume",
11377 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11381 nid = cfg->hp_pins[0];
11383 alc268_new_analog_output(spec, nid, "Headphone", 0);
11385 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11387 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11388 "Mono Playback Switch",
11389 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11396 /* create playback/capture controls for input pins */
11397 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11398 const struct auto_pin_cfg *cfg)
11400 struct hda_input_mux *imux = &spec->private_imux;
11403 for (i = 0; i < AUTO_PIN_LAST; i++) {
11404 switch(cfg->input_pins[i]) {
11406 idx1 = 0; /* Mic 1 */
11409 idx1 = 1; /* Mic 2 */
11412 idx1 = 2; /* Line In */
11419 idx1 = 6; /* digital mics */
11424 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11425 imux->items[imux->num_items].index = idx1;
11431 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11433 struct alc_spec *spec = codec->spec;
11434 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11435 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11436 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11437 unsigned int dac_vol1, dac_vol2;
11440 snd_hda_codec_write(codec, speaker_nid, 0,
11441 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11442 snd_hda_codec_write(codec, 0x0f, 0,
11443 AC_VERB_SET_AMP_GAIN_MUTE,
11445 snd_hda_codec_write(codec, 0x10, 0,
11446 AC_VERB_SET_AMP_GAIN_MUTE,
11449 snd_hda_codec_write(codec, 0x0f, 0,
11450 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11451 snd_hda_codec_write(codec, 0x10, 0,
11452 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11455 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11456 if (line_nid == 0x14)
11457 dac_vol2 = AMP_OUT_ZERO;
11458 else if (line_nid == 0x15)
11459 dac_vol1 = AMP_OUT_ZERO;
11460 if (hp_nid == 0x14)
11461 dac_vol2 = AMP_OUT_ZERO;
11462 else if (hp_nid == 0x15)
11463 dac_vol1 = AMP_OUT_ZERO;
11464 if (line_nid != 0x16 || hp_nid != 0x16 ||
11465 spec->autocfg.line_out_pins[1] != 0x16 ||
11466 spec->autocfg.line_out_pins[2] != 0x16)
11467 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11469 snd_hda_codec_write(codec, 0x02, 0,
11470 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11471 snd_hda_codec_write(codec, 0x03, 0,
11472 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11475 /* pcm configuration: identiacal with ALC880 */
11476 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11477 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11478 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11479 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11482 * BIOS auto configuration
11484 static int alc268_parse_auto_config(struct hda_codec *codec)
11486 struct alc_spec *spec = codec->spec;
11488 static hda_nid_t alc268_ignore[] = { 0 };
11490 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11494 if (!spec->autocfg.line_outs)
11495 return 0; /* can't find valid BIOS pin config */
11497 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11500 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11504 spec->multiout.max_channels = 2;
11506 /* digital only support output */
11507 if (spec->autocfg.dig_out_pin)
11508 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11510 if (spec->kctls.list)
11511 add_mixer(spec, spec->kctls.list);
11513 if (spec->autocfg.speaker_pins[0] != 0x1d)
11514 add_mixer(spec, alc268_beep_mixer);
11516 add_verb(spec, alc268_volume_init_verbs);
11517 spec->num_mux_defs = 1;
11518 spec->input_mux = &spec->private_imux;
11520 err = alc_auto_add_mic_boost(codec);
11524 store_pin_configs(codec);
11528 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11529 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11530 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11532 /* init callback for auto-configuration model -- overriding the default init */
11533 static void alc268_auto_init(struct hda_codec *codec)
11535 struct alc_spec *spec = codec->spec;
11536 alc268_auto_init_multi_out(codec);
11537 alc268_auto_init_hp_out(codec);
11538 alc268_auto_init_mono_speaker_out(codec);
11539 alc268_auto_init_analog_input(codec);
11540 if (spec->unsol_event)
11541 alc_inithook(codec);
11545 * configuration and preset
11547 static const char *alc268_models[ALC268_MODEL_LAST] = {
11548 [ALC267_QUANTA_IL1] = "quanta-il1",
11549 [ALC268_3ST] = "3stack",
11550 [ALC268_TOSHIBA] = "toshiba",
11551 [ALC268_ACER] = "acer",
11552 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11553 [ALC268_DELL] = "dell",
11554 [ALC268_ZEPTO] = "zepto",
11555 #ifdef CONFIG_SND_DEBUG
11556 [ALC268_TEST] = "test",
11558 [ALC268_AUTO] = "auto",
11561 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11562 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11563 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11564 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11565 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11566 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11567 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11568 ALC268_ACER_ASPIRE_ONE),
11569 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11570 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11571 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11572 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11573 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11574 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11575 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11576 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11577 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11578 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11582 static struct alc_config_preset alc268_presets[] = {
11583 [ALC267_QUANTA_IL1] = {
11584 .mixers = { alc267_quanta_il1_mixer },
11585 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11586 alc267_quanta_il1_verbs },
11587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11588 .dac_nids = alc268_dac_nids,
11589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11590 .adc_nids = alc268_adc_nids_alt,
11592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11593 .channel_mode = alc268_modes,
11594 .input_mux = &alc268_capture_source,
11595 .unsol_event = alc267_quanta_il1_unsol_event,
11596 .init_hook = alc267_quanta_il1_automute,
11599 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11600 alc268_beep_mixer },
11601 .init_verbs = { alc268_base_init_verbs },
11602 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11603 .dac_nids = alc268_dac_nids,
11604 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11605 .adc_nids = alc268_adc_nids_alt,
11606 .capsrc_nids = alc268_capsrc_nids,
11608 .dig_out_nid = ALC268_DIGOUT_NID,
11609 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11610 .channel_mode = alc268_modes,
11611 .input_mux = &alc268_capture_source,
11613 [ALC268_TOSHIBA] = {
11614 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11615 alc268_beep_mixer },
11616 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11617 alc268_toshiba_verbs },
11618 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11619 .dac_nids = alc268_dac_nids,
11620 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11621 .adc_nids = alc268_adc_nids_alt,
11622 .capsrc_nids = alc268_capsrc_nids,
11624 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11625 .channel_mode = alc268_modes,
11626 .input_mux = &alc268_capture_source,
11627 .unsol_event = alc268_toshiba_unsol_event,
11628 .init_hook = alc268_toshiba_automute,
11631 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11632 alc268_beep_mixer },
11633 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11634 alc268_acer_verbs },
11635 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11636 .dac_nids = alc268_dac_nids,
11637 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11638 .adc_nids = alc268_adc_nids_alt,
11639 .capsrc_nids = alc268_capsrc_nids,
11641 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11642 .channel_mode = alc268_modes,
11643 .input_mux = &alc268_acer_capture_source,
11644 .unsol_event = alc268_acer_unsol_event,
11645 .init_hook = alc268_acer_init_hook,
11647 [ALC268_ACER_ASPIRE_ONE] = {
11648 .mixers = { alc268_acer_aspire_one_mixer,
11649 alc268_capture_alt_mixer },
11650 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11651 alc268_acer_aspire_one_verbs },
11652 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11653 .dac_nids = alc268_dac_nids,
11654 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11655 .adc_nids = alc268_adc_nids_alt,
11656 .capsrc_nids = alc268_capsrc_nids,
11658 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11659 .channel_mode = alc268_modes,
11660 .input_mux = &alc268_acer_lc_capture_source,
11661 .unsol_event = alc268_acer_lc_unsol_event,
11662 .init_hook = alc268_acer_lc_init_hook,
11665 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11666 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11667 alc268_dell_verbs },
11668 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11669 .dac_nids = alc268_dac_nids,
11671 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11672 .channel_mode = alc268_modes,
11673 .unsol_event = alc268_dell_unsol_event,
11674 .init_hook = alc268_dell_init_hook,
11675 .input_mux = &alc268_capture_source,
11678 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11679 alc268_beep_mixer },
11680 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11681 alc268_toshiba_verbs },
11682 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11683 .dac_nids = alc268_dac_nids,
11684 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11685 .adc_nids = alc268_adc_nids_alt,
11686 .capsrc_nids = alc268_capsrc_nids,
11688 .dig_out_nid = ALC268_DIGOUT_NID,
11689 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11690 .channel_mode = alc268_modes,
11691 .input_mux = &alc268_capture_source,
11692 .unsol_event = alc268_toshiba_unsol_event,
11693 .init_hook = alc268_toshiba_automute
11695 #ifdef CONFIG_SND_DEBUG
11697 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11698 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11699 alc268_volume_init_verbs },
11700 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11701 .dac_nids = alc268_dac_nids,
11702 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11703 .adc_nids = alc268_adc_nids_alt,
11704 .capsrc_nids = alc268_capsrc_nids,
11706 .dig_out_nid = ALC268_DIGOUT_NID,
11707 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11708 .channel_mode = alc268_modes,
11709 .input_mux = &alc268_capture_source,
11714 static int patch_alc268(struct hda_codec *codec)
11716 struct alc_spec *spec;
11720 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11724 codec->spec = spec;
11726 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11730 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11731 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11732 "trying auto-probe from BIOS...\n");
11733 board_config = ALC268_AUTO;
11736 if (board_config == ALC268_AUTO) {
11737 /* automatic parse from the BIOS config */
11738 err = alc268_parse_auto_config(codec);
11744 "hda_codec: Cannot set up configuration "
11745 "from BIOS. Using base mode...\n");
11746 board_config = ALC268_3ST;
11750 if (board_config != ALC268_AUTO)
11751 setup_preset(spec, &alc268_presets[board_config]);
11753 if (codec->vendor_id == 0x10ec0267) {
11754 spec->stream_name_analog = "ALC267 Analog";
11755 spec->stream_name_digital = "ALC267 Digital";
11757 spec->stream_name_analog = "ALC268 Analog";
11758 spec->stream_name_digital = "ALC268 Digital";
11761 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11762 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11763 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11765 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11767 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11768 /* override the amp caps for beep generator */
11769 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11770 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11771 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11772 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11773 (0 << AC_AMPCAP_MUTE_SHIFT));
11775 if (!spec->adc_nids && spec->input_mux) {
11776 /* check whether NID 0x07 is valid */
11777 unsigned int wcap = get_wcaps(codec, 0x07);
11781 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11782 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11783 spec->adc_nids = alc268_adc_nids_alt;
11784 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11785 add_mixer(spec, alc268_capture_alt_mixer);
11787 spec->adc_nids = alc268_adc_nids;
11788 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11789 add_mixer(spec, alc268_capture_mixer);
11791 spec->capsrc_nids = alc268_capsrc_nids;
11792 /* set default input source */
11793 for (i = 0; i < spec->num_adc_nids; i++)
11794 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11795 0, AC_VERB_SET_CONNECT_SEL,
11796 spec->input_mux->items[0].index);
11799 spec->vmaster_nid = 0x02;
11801 codec->patch_ops = alc_patch_ops;
11802 if (board_config == ALC268_AUTO)
11803 spec->init_hook = alc268_auto_init;
11809 * ALC269 channel source setting (2 channel)
11811 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11813 #define alc269_dac_nids alc260_dac_nids
11815 static hda_nid_t alc269_adc_nids[1] = {
11820 static hda_nid_t alc269_capsrc_nids[1] = {
11824 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11828 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11836 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11844 #define alc269_modes alc260_modes
11845 #define alc269_capture_source alc880_lg_lw_capture_source
11847 static struct snd_kcontrol_new alc269_base_mixer[] = {
11848 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11849 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11854 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11855 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11857 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11858 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11859 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11861 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11865 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11866 /* output mixer control */
11867 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11870 .name = "Master Playback Switch",
11871 .info = snd_hda_mixer_amp_switch_info,
11872 .get = snd_hda_mixer_amp_switch_get,
11873 .put = alc268_acer_master_sw_put,
11874 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11878 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11879 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11880 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11881 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11882 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11883 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11887 /* bind volumes of both NID 0x0c and 0x0d */
11888 static struct hda_bind_ctls alc269_epc_bind_vol = {
11889 .ops = &snd_hda_bind_vol,
11891 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11892 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11897 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11898 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11899 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11900 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11904 /* capture mixer elements */
11905 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11906 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11907 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11910 /* The multiple "Capture Source" controls confuse alsamixer
11911 * So call somewhat different..
11913 /* .name = "Capture Source", */
11914 .name = "Input Source",
11916 .info = alc_mux_enum_info,
11917 .get = alc_mux_enum_get,
11918 .put = alc_mux_enum_put,
11923 /* capture mixer elements */
11924 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11925 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11926 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11931 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11932 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11933 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11937 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11938 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11939 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11941 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11942 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11943 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11947 /* toggle speaker-output according to the hp-jack state */
11948 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11950 unsigned int present;
11951 unsigned char bits;
11953 present = snd_hda_codec_read(codec, 0x15, 0,
11954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11955 bits = present ? AMP_IN_MUTE(0) : 0;
11956 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11957 AMP_IN_MUTE(0), bits);
11958 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11959 AMP_IN_MUTE(0), bits);
11961 snd_hda_codec_write(codec, 0x20, 0,
11962 AC_VERB_SET_COEF_INDEX, 0x0c);
11963 snd_hda_codec_write(codec, 0x20, 0,
11964 AC_VERB_SET_PROC_COEF, 0x680);
11966 snd_hda_codec_write(codec, 0x20, 0,
11967 AC_VERB_SET_COEF_INDEX, 0x0c);
11968 snd_hda_codec_write(codec, 0x20, 0,
11969 AC_VERB_SET_PROC_COEF, 0x480);
11972 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11974 unsigned int present;
11976 present = snd_hda_codec_read(codec, 0x18, 0,
11977 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11978 snd_hda_codec_write(codec, 0x23, 0,
11979 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11982 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11985 if ((res >> 26) == ALC880_HP_EVENT)
11986 alc269_quanta_fl1_speaker_automute(codec);
11987 if ((res >> 26) == ALC880_MIC_EVENT)
11988 alc269_quanta_fl1_mic_automute(codec);
11991 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11993 alc269_quanta_fl1_speaker_automute(codec);
11994 alc269_quanta_fl1_mic_automute(codec);
11997 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11999 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12000 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12002 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12003 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12004 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12008 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12009 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12010 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12011 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12012 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12018 /* toggle speaker-output according to the hp-jack state */
12019 static void alc269_speaker_automute(struct hda_codec *codec)
12021 unsigned int present;
12022 unsigned char bits;
12024 present = snd_hda_codec_read(codec, 0x15, 0,
12025 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12026 bits = present ? AMP_IN_MUTE(0) : 0;
12027 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12028 AMP_IN_MUTE(0), bits);
12029 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12030 AMP_IN_MUTE(0), bits);
12033 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12035 unsigned int present;
12037 present = snd_hda_codec_read(codec, 0x18, 0,
12038 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12039 snd_hda_codec_write(codec, 0x23, 0,
12040 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12043 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12045 unsigned int present;
12047 present = snd_hda_codec_read(codec, 0x18, 0,
12048 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12049 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12050 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12051 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12052 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12055 /* unsolicited event for HP jack sensing */
12056 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12059 if ((res >> 26) == ALC880_HP_EVENT)
12060 alc269_speaker_automute(codec);
12062 if ((res >> 26) == ALC880_MIC_EVENT)
12063 alc269_eeepc_dmic_automute(codec);
12066 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12068 alc269_speaker_automute(codec);
12069 alc269_eeepc_dmic_automute(codec);
12072 /* unsolicited event for HP jack sensing */
12073 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12076 if ((res >> 26) == ALC880_HP_EVENT)
12077 alc269_speaker_automute(codec);
12079 if ((res >> 26) == ALC880_MIC_EVENT)
12080 alc269_eeepc_amic_automute(codec);
12083 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12085 alc269_speaker_automute(codec);
12086 alc269_eeepc_amic_automute(codec);
12090 * generic initialization of ADC, input mixers and output mixers
12092 static struct hda_verb alc269_init_verbs[] = {
12094 * Unmute ADC0 and set the default input to mic-in
12096 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12098 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12099 * analog-loopback mixer widget
12100 * Note: PASD motherboards uses the Line In 2 as the input for
12101 * front panel mic (mic 2)
12103 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12111 * Set up output mixers (0x0c - 0x0e)
12113 /* set vol=0 to output mixers */
12114 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12115 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12117 /* set up input amps for analog loopback */
12118 /* Amp Indices: DAC = 0, mixer = 1 */
12119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12123 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12124 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12128 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12136 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12137 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12138 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12142 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12145 /* FIXME: use matrix-type input source selection */
12146 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12147 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12154 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12155 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12159 /* add playback controls from the parsed DAC table */
12160 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12161 const struct auto_pin_cfg *cfg)
12166 spec->multiout.num_dacs = 1; /* only use one dac */
12167 spec->multiout.dac_nids = spec->private_dac_nids;
12168 spec->multiout.dac_nids[0] = 2;
12170 nid = cfg->line_out_pins[0];
12172 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12173 "Front Playback Volume",
12174 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12177 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12178 "Front Playback Switch",
12179 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12184 nid = cfg->speaker_pins[0];
12186 if (!cfg->line_out_pins[0]) {
12187 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12188 "Speaker Playback Volume",
12189 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12195 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12196 "Speaker Playback Switch",
12197 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12202 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12203 "Speaker Playback Switch",
12204 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12210 nid = cfg->hp_pins[0];
12212 /* spec->multiout.hp_nid = 2; */
12213 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12214 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12215 "Headphone Playback Volume",
12216 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12222 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12223 "Headphone Playback Switch",
12224 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12229 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12230 "Headphone Playback Switch",
12231 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12240 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12241 const struct auto_pin_cfg *cfg)
12245 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12248 /* digital-mic input pin is excluded in alc880_auto_create..()
12249 * because it's under 0x18
12251 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12252 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12253 struct hda_input_mux *imux = &spec->private_imux;
12254 imux->items[imux->num_items].label = "Int Mic";
12255 imux->items[imux->num_items].index = 0x05;
12261 #ifdef CONFIG_SND_HDA_POWER_SAVE
12262 #define alc269_loopbacks alc880_loopbacks
12265 /* pcm configuration: identiacal with ALC880 */
12266 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12267 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12268 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12269 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12272 * BIOS auto configuration
12274 static int alc269_parse_auto_config(struct hda_codec *codec)
12276 struct alc_spec *spec = codec->spec;
12278 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12280 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12285 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12288 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12292 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12294 if (spec->autocfg.dig_out_pin)
12295 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12297 if (spec->kctls.list)
12298 add_mixer(spec, spec->kctls.list);
12300 /* create a beep mixer control if the pin 0x1d isn't assigned */
12301 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12302 if (spec->autocfg.input_pins[i] == 0x1d)
12304 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12305 add_mixer(spec, alc269_beep_mixer);
12307 add_verb(spec, alc269_init_verbs);
12308 spec->num_mux_defs = 1;
12309 spec->input_mux = &spec->private_imux;
12310 /* set default input source */
12311 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12312 0, AC_VERB_SET_CONNECT_SEL,
12313 spec->input_mux->items[0].index);
12315 err = alc_auto_add_mic_boost(codec);
12319 add_mixer(spec, alc269_capture_mixer);
12321 store_pin_configs(codec);
12325 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12326 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12327 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12330 /* init callback for auto-configuration model -- overriding the default init */
12331 static void alc269_auto_init(struct hda_codec *codec)
12333 struct alc_spec *spec = codec->spec;
12334 alc269_auto_init_multi_out(codec);
12335 alc269_auto_init_hp_out(codec);
12336 alc269_auto_init_analog_input(codec);
12337 if (spec->unsol_event)
12338 alc_inithook(codec);
12342 * configuration and preset
12344 static const char *alc269_models[ALC269_MODEL_LAST] = {
12345 [ALC269_BASIC] = "basic",
12346 [ALC269_QUANTA_FL1] = "quanta",
12347 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12348 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
12351 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12352 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12353 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12354 ALC269_ASUS_EEEPC_P703),
12355 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12356 ALC269_ASUS_EEEPC_P901),
12357 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12358 ALC269_ASUS_EEEPC_P901),
12362 static struct alc_config_preset alc269_presets[] = {
12364 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12365 .init_verbs = { alc269_init_verbs },
12366 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12367 .dac_nids = alc269_dac_nids,
12369 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12370 .channel_mode = alc269_modes,
12371 .input_mux = &alc269_capture_source,
12373 [ALC269_QUANTA_FL1] = {
12374 .mixers = { alc269_quanta_fl1_mixer },
12375 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12376 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12377 .dac_nids = alc269_dac_nids,
12379 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12380 .channel_mode = alc269_modes,
12381 .input_mux = &alc269_capture_source,
12382 .unsol_event = alc269_quanta_fl1_unsol_event,
12383 .init_hook = alc269_quanta_fl1_init_hook,
12385 [ALC269_ASUS_EEEPC_P703] = {
12386 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12387 .init_verbs = { alc269_init_verbs,
12388 alc269_eeepc_amic_init_verbs },
12389 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12390 .dac_nids = alc269_dac_nids,
12392 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12393 .channel_mode = alc269_modes,
12394 .input_mux = &alc269_eeepc_amic_capture_source,
12395 .unsol_event = alc269_eeepc_amic_unsol_event,
12396 .init_hook = alc269_eeepc_amic_inithook,
12398 [ALC269_ASUS_EEEPC_P901] = {
12399 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12400 .init_verbs = { alc269_init_verbs,
12401 alc269_eeepc_dmic_init_verbs },
12402 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12403 .dac_nids = alc269_dac_nids,
12405 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12406 .channel_mode = alc269_modes,
12407 .input_mux = &alc269_eeepc_dmic_capture_source,
12408 .unsol_event = alc269_eeepc_dmic_unsol_event,
12409 .init_hook = alc269_eeepc_dmic_inithook,
12413 static int patch_alc269(struct hda_codec *codec)
12415 struct alc_spec *spec;
12419 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12423 codec->spec = spec;
12425 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12427 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12431 if (board_config < 0) {
12432 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12433 "trying auto-probe from BIOS...\n");
12434 board_config = ALC269_AUTO;
12437 if (board_config == ALC269_AUTO) {
12438 /* automatic parse from the BIOS config */
12439 err = alc269_parse_auto_config(codec);
12445 "hda_codec: Cannot set up configuration "
12446 "from BIOS. Using base mode...\n");
12447 board_config = ALC269_BASIC;
12451 if (board_config != ALC269_AUTO)
12452 setup_preset(spec, &alc269_presets[board_config]);
12454 spec->stream_name_analog = "ALC269 Analog";
12455 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12456 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12458 spec->stream_name_digital = "ALC269 Digital";
12459 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12460 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12462 spec->adc_nids = alc269_adc_nids;
12463 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12464 spec->capsrc_nids = alc269_capsrc_nids;
12466 codec->patch_ops = alc_patch_ops;
12467 if (board_config == ALC269_AUTO)
12468 spec->init_hook = alc269_auto_init;
12469 #ifdef CONFIG_SND_HDA_POWER_SAVE
12470 if (!spec->loopback.amplist)
12471 spec->loopback.amplist = alc269_loopbacks;
12478 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12482 * set the path ways for 2 channel output
12483 * need to set the codec line out and mic 1 pin widgets to inputs
12485 static struct hda_verb alc861_threestack_ch2_init[] = {
12486 /* set pin widget 1Ah (line in) for input */
12487 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12488 /* set pin widget 18h (mic1/2) for input, for mic also enable
12491 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12493 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12495 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12496 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12502 * need to set the codec line out and mic 1 pin widgets to outputs
12504 static struct hda_verb alc861_threestack_ch6_init[] = {
12505 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12506 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12507 /* set pin widget 18h (mic1) for output (CLFE)*/
12508 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12510 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12511 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12513 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12515 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12516 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12521 static struct hda_channel_mode alc861_threestack_modes[2] = {
12522 { 2, alc861_threestack_ch2_init },
12523 { 6, alc861_threestack_ch6_init },
12525 /* Set mic1 as input and unmute the mixer */
12526 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12527 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12528 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12531 /* Set mic1 as output and mute mixer */
12532 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12533 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12534 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12538 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12539 { 2, alc861_uniwill_m31_ch2_init },
12540 { 4, alc861_uniwill_m31_ch4_init },
12543 /* Set mic1 and line-in as input and unmute the mixer */
12544 static struct hda_verb alc861_asus_ch2_init[] = {
12545 /* set pin widget 1Ah (line in) for input */
12546 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12547 /* set pin widget 18h (mic1/2) for input, for mic also enable
12550 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12552 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12554 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12555 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12559 /* Set mic1 nad line-in as output and mute mixer */
12560 static struct hda_verb alc861_asus_ch6_init[] = {
12561 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12562 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12563 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12564 /* set pin widget 18h (mic1) for output (CLFE)*/
12565 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12566 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12567 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12568 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12570 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12572 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12573 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12578 static struct hda_channel_mode alc861_asus_modes[2] = {
12579 { 2, alc861_asus_ch2_init },
12580 { 6, alc861_asus_ch6_init },
12585 static struct snd_kcontrol_new alc861_base_mixer[] = {
12586 /* output mixer control */
12587 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12588 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12589 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12590 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12591 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12593 /*Input mixer control */
12594 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12595 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12596 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12597 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12598 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12599 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12601 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12602 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12605 /* Capture mixer control */
12606 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12607 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12610 .name = "Capture Source",
12612 .info = alc_mux_enum_info,
12613 .get = alc_mux_enum_get,
12614 .put = alc_mux_enum_put,
12619 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12620 /* output mixer control */
12621 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12622 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12623 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12624 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12625 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12627 /* Input mixer control */
12628 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12629 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12630 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12631 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12632 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12633 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12635 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12639 /* Capture mixer control */
12640 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12641 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12643 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12644 .name = "Capture Source",
12646 .info = alc_mux_enum_info,
12647 .get = alc_mux_enum_get,
12648 .put = alc_mux_enum_put,
12651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12652 .name = "Channel Mode",
12653 .info = alc_ch_mode_info,
12654 .get = alc_ch_mode_get,
12655 .put = alc_ch_mode_put,
12656 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12661 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12662 /* output mixer control */
12663 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12665 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12667 /*Capture mixer control */
12668 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12669 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12672 .name = "Capture Source",
12674 .info = alc_mux_enum_info,
12675 .get = alc_mux_enum_get,
12676 .put = alc_mux_enum_put,
12682 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12683 /* output mixer control */
12684 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12686 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12687 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12688 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12690 /* Input mixer control */
12691 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12692 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12693 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12694 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12695 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12696 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12697 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12698 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12699 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12702 /* Capture mixer control */
12703 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12704 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12707 .name = "Capture Source",
12709 .info = alc_mux_enum_info,
12710 .get = alc_mux_enum_get,
12711 .put = alc_mux_enum_put,
12714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12715 .name = "Channel Mode",
12716 .info = alc_ch_mode_info,
12717 .get = alc_ch_mode_get,
12718 .put = alc_ch_mode_put,
12719 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12724 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12725 /* output mixer control */
12726 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12728 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12729 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12730 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12732 /* Input mixer control */
12733 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12734 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12735 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12736 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12737 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12738 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12740 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12741 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12744 /* Capture mixer control */
12745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12749 .name = "Capture Source",
12751 .info = alc_mux_enum_info,
12752 .get = alc_mux_enum_get,
12753 .put = alc_mux_enum_put,
12756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12757 .name = "Channel Mode",
12758 .info = alc_ch_mode_info,
12759 .get = alc_ch_mode_get,
12760 .put = alc_ch_mode_put,
12761 .private_value = ARRAY_SIZE(alc861_asus_modes),
12766 /* additional mixer */
12767 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12768 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12769 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12770 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12771 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12776 * generic initialization of ADC, input mixers and output mixers
12778 static struct hda_verb alc861_base_init_verbs[] = {
12780 * Unmute ADC0 and set the default input to mic-in
12782 /* port-A for surround (rear panel) */
12783 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12784 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12785 /* port-B for mic-in (rear panel) with vref */
12786 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12787 /* port-C for line-in (rear panel) */
12788 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12789 /* port-D for Front */
12790 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12791 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12792 /* port-E for HP out (front panel) */
12793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12794 /* route front PCM to HP */
12795 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12796 /* port-F for mic-in (front panel) with vref */
12797 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12798 /* port-G for CLFE (rear panel) */
12799 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12800 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12801 /* port-H for side (rear panel) */
12802 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12803 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12805 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12806 /* route front mic to ADC1*/
12807 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12808 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12810 /* Unmute DAC0~3 & spdif out*/
12811 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12813 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12814 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12817 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12818 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12819 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12820 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12821 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12823 /* Unmute Stereo Mixer 15 */
12824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12837 /* hp used DAC 3 (Front) */
12838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12844 static struct hda_verb alc861_threestack_init_verbs[] = {
12846 * Unmute ADC0 and set the default input to mic-in
12848 /* port-A for surround (rear panel) */
12849 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12850 /* port-B for mic-in (rear panel) with vref */
12851 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12852 /* port-C for line-in (rear panel) */
12853 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12854 /* port-D for Front */
12855 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12856 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12857 /* port-E for HP out (front panel) */
12858 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12859 /* route front PCM to HP */
12860 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12861 /* port-F for mic-in (front panel) with vref */
12862 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12863 /* port-G for CLFE (rear panel) */
12864 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12865 /* port-H for side (rear panel) */
12866 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12868 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12869 /* route front mic to ADC1*/
12870 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12871 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12872 /* Unmute DAC0~3 & spdif out*/
12873 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12874 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12875 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12876 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12879 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12880 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12881 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12882 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12883 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12885 /* Unmute Stereo Mixer 15 */
12886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12888 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12892 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12893 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12894 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12895 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12896 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12897 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12899 /* hp used DAC 3 (Front) */
12900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12905 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12907 * Unmute ADC0 and set the default input to mic-in
12909 /* port-A for surround (rear panel) */
12910 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12911 /* port-B for mic-in (rear panel) with vref */
12912 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12913 /* port-C for line-in (rear panel) */
12914 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12915 /* port-D for Front */
12916 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12917 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12918 /* port-E for HP out (front panel) */
12919 /* this has to be set to VREF80 */
12920 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12921 /* route front PCM to HP */
12922 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12923 /* port-F for mic-in (front panel) with vref */
12924 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12925 /* port-G for CLFE (rear panel) */
12926 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12927 /* port-H for side (rear panel) */
12928 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12930 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12931 /* route front mic to ADC1*/
12932 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12934 /* Unmute DAC0~3 & spdif out*/
12935 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12936 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12937 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12938 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12941 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12942 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12943 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12944 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12945 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12947 /* Unmute Stereo Mixer 15 */
12948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12951 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12953 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12954 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12955 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12957 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12959 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12961 /* hp used DAC 3 (Front) */
12962 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12963 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12967 static struct hda_verb alc861_asus_init_verbs[] = {
12969 * Unmute ADC0 and set the default input to mic-in
12971 /* port-A for surround (rear panel)
12972 * according to codec#0 this is the HP jack
12974 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12975 /* route front PCM to HP */
12976 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12977 /* port-B for mic-in (rear panel) with vref */
12978 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12979 /* port-C for line-in (rear panel) */
12980 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12981 /* port-D for Front */
12982 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12983 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12984 /* port-E for HP out (front panel) */
12985 /* this has to be set to VREF80 */
12986 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12987 /* route front PCM to HP */
12988 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12989 /* port-F for mic-in (front panel) with vref */
12990 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12991 /* port-G for CLFE (rear panel) */
12992 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12993 /* port-H for side (rear panel) */
12994 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12996 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12997 /* route front mic to ADC1*/
12998 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13000 /* Unmute DAC0~3 & spdif out*/
13001 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13002 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13003 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13004 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13006 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13007 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13009 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13012 /* Unmute Stereo Mixer 15 */
13013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13018 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13019 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13020 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13021 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13023 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13024 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13026 /* hp used DAC 3 (Front) */
13027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13028 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13032 /* additional init verbs for ASUS laptops */
13033 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13034 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13035 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13040 * generic initialization of ADC, input mixers and output mixers
13042 static struct hda_verb alc861_auto_init_verbs[] = {
13044 * Unmute ADC0 and set the default input to mic-in
13046 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13049 /* Unmute DAC0~3 & spdif out*/
13050 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13052 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13053 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13056 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13058 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13060 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13062 /* Unmute Stereo Mixer 15 */
13063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13069 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13079 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13080 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13082 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13083 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13091 static struct hda_verb alc861_toshiba_init_verbs[] = {
13092 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13097 /* toggle speaker-output according to the hp-jack state */
13098 static void alc861_toshiba_automute(struct hda_codec *codec)
13100 unsigned int present;
13102 present = snd_hda_codec_read(codec, 0x0f, 0,
13103 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13104 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13105 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13106 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13107 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13110 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13113 if ((res >> 26) == ALC880_HP_EVENT)
13114 alc861_toshiba_automute(codec);
13117 /* pcm configuration: identiacal with ALC880 */
13118 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13119 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13120 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13121 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13124 #define ALC861_DIGOUT_NID 0x07
13126 static struct hda_channel_mode alc861_8ch_modes[1] = {
13130 static hda_nid_t alc861_dac_nids[4] = {
13131 /* front, surround, clfe, side */
13132 0x03, 0x06, 0x05, 0x04
13135 static hda_nid_t alc660_dac_nids[3] = {
13136 /* front, clfe, surround */
13140 static hda_nid_t alc861_adc_nids[1] = {
13145 static struct hda_input_mux alc861_capture_source = {
13149 { "Front Mic", 0x3 },
13156 /* fill in the dac_nids table from the parsed pin configuration */
13157 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13158 const struct auto_pin_cfg *cfg)
13163 spec->multiout.dac_nids = spec->private_dac_nids;
13164 for (i = 0; i < cfg->line_outs; i++) {
13165 nid = cfg->line_out_pins[i];
13167 if (i >= ARRAY_SIZE(alc861_dac_nids))
13169 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13172 spec->multiout.num_dacs = cfg->line_outs;
13176 /* add playback controls from the parsed DAC table */
13177 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13178 const struct auto_pin_cfg *cfg)
13181 static const char *chname[4] = {
13182 "Front", "Surround", NULL /*CLFE*/, "Side"
13187 for (i = 0; i < cfg->line_outs; i++) {
13188 nid = spec->multiout.dac_nids[i];
13193 err = add_control(spec, ALC_CTL_BIND_MUTE,
13194 "Center Playback Switch",
13195 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13199 err = add_control(spec, ALC_CTL_BIND_MUTE,
13200 "LFE Playback Switch",
13201 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13206 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13208 if (nid == alc861_dac_nids[idx])
13210 sprintf(name, "%s Playback Switch", chname[idx]);
13211 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13212 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13221 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13229 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13231 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13232 "Headphone Playback Switch",
13233 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13236 spec->multiout.hp_nid = nid;
13241 /* create playback/capture controls for input pins */
13242 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13243 const struct auto_pin_cfg *cfg)
13245 struct hda_input_mux *imux = &spec->private_imux;
13246 int i, err, idx, idx1;
13248 for (i = 0; i < AUTO_PIN_LAST; i++) {
13249 switch (cfg->input_pins[i]) {
13252 idx = 2; /* Line In */
13256 idx = 2; /* Line In */
13260 idx = 1; /* Mic In */
13264 idx = 1; /* Mic In */
13274 err = new_analog_input(spec, cfg->input_pins[i],
13275 auto_pin_cfg_labels[i], idx, 0x15);
13279 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13280 imux->items[imux->num_items].index = idx1;
13286 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13287 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13288 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13292 /* The multiple "Capture Source" controls confuse alsamixer
13293 * So call somewhat different..
13295 /* .name = "Capture Source", */
13296 .name = "Input Source",
13298 .info = alc_mux_enum_info,
13299 .get = alc_mux_enum_get,
13300 .put = alc_mux_enum_put,
13305 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13307 int pin_type, int dac_idx)
13309 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13311 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13315 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13317 struct alc_spec *spec = codec->spec;
13320 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13321 for (i = 0; i < spec->autocfg.line_outs; i++) {
13322 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13323 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13325 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13326 spec->multiout.dac_nids[i]);
13330 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13332 struct alc_spec *spec = codec->spec;
13335 pin = spec->autocfg.hp_pins[0];
13336 if (pin) /* connect to front */
13337 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13338 spec->multiout.dac_nids[0]);
13339 pin = spec->autocfg.speaker_pins[0];
13341 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13344 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13346 struct alc_spec *spec = codec->spec;
13349 for (i = 0; i < AUTO_PIN_LAST; i++) {
13350 hda_nid_t nid = spec->autocfg.input_pins[i];
13351 if (nid >= 0x0c && nid <= 0x11) {
13352 snd_hda_codec_write(codec, nid, 0,
13353 AC_VERB_SET_PIN_WIDGET_CONTROL,
13354 i <= AUTO_PIN_FRONT_MIC ?
13355 PIN_VREF80 : PIN_IN);
13360 /* parse the BIOS configuration and set up the alc_spec */
13361 /* return 1 if successful, 0 if the proper config is not found,
13362 * or a negative error code
13364 static int alc861_parse_auto_config(struct hda_codec *codec)
13366 struct alc_spec *spec = codec->spec;
13368 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13370 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13374 if (!spec->autocfg.line_outs)
13375 return 0; /* can't find valid BIOS pin config */
13377 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13380 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13383 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13386 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13390 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13392 if (spec->autocfg.dig_out_pin)
13393 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13395 if (spec->kctls.list)
13396 add_mixer(spec, spec->kctls.list);
13398 add_verb(spec, alc861_auto_init_verbs);
13400 spec->num_mux_defs = 1;
13401 spec->input_mux = &spec->private_imux;
13403 spec->adc_nids = alc861_adc_nids;
13404 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13405 add_mixer(spec, alc861_capture_mixer);
13407 store_pin_configs(codec);
13411 /* additional initialization for auto-configuration model */
13412 static void alc861_auto_init(struct hda_codec *codec)
13414 struct alc_spec *spec = codec->spec;
13415 alc861_auto_init_multi_out(codec);
13416 alc861_auto_init_hp_out(codec);
13417 alc861_auto_init_analog_input(codec);
13418 if (spec->unsol_event)
13419 alc_inithook(codec);
13422 #ifdef CONFIG_SND_HDA_POWER_SAVE
13423 static struct hda_amp_list alc861_loopbacks[] = {
13424 { 0x15, HDA_INPUT, 0 },
13425 { 0x15, HDA_INPUT, 1 },
13426 { 0x15, HDA_INPUT, 2 },
13427 { 0x15, HDA_INPUT, 3 },
13434 * configuration and preset
13436 static const char *alc861_models[ALC861_MODEL_LAST] = {
13437 [ALC861_3ST] = "3stack",
13438 [ALC660_3ST] = "3stack-660",
13439 [ALC861_3ST_DIG] = "3stack-dig",
13440 [ALC861_6ST_DIG] = "6stack-dig",
13441 [ALC861_UNIWILL_M31] = "uniwill-m31",
13442 [ALC861_TOSHIBA] = "toshiba",
13443 [ALC861_ASUS] = "asus",
13444 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13445 [ALC861_AUTO] = "auto",
13448 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13449 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13450 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13451 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13452 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13453 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13454 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13455 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13456 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13457 * Any other models that need this preset?
13459 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13460 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13461 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13462 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13463 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13464 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13465 /* FIXME: the below seems conflict */
13466 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13467 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13468 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13472 static struct alc_config_preset alc861_presets[] = {
13474 .mixers = { alc861_3ST_mixer },
13475 .init_verbs = { alc861_threestack_init_verbs },
13476 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13477 .dac_nids = alc861_dac_nids,
13478 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13479 .channel_mode = alc861_threestack_modes,
13481 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13482 .adc_nids = alc861_adc_nids,
13483 .input_mux = &alc861_capture_source,
13485 [ALC861_3ST_DIG] = {
13486 .mixers = { alc861_base_mixer },
13487 .init_verbs = { alc861_threestack_init_verbs },
13488 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13489 .dac_nids = alc861_dac_nids,
13490 .dig_out_nid = ALC861_DIGOUT_NID,
13491 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13492 .channel_mode = alc861_threestack_modes,
13494 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13495 .adc_nids = alc861_adc_nids,
13496 .input_mux = &alc861_capture_source,
13498 [ALC861_6ST_DIG] = {
13499 .mixers = { alc861_base_mixer },
13500 .init_verbs = { alc861_base_init_verbs },
13501 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13502 .dac_nids = alc861_dac_nids,
13503 .dig_out_nid = ALC861_DIGOUT_NID,
13504 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13505 .channel_mode = alc861_8ch_modes,
13506 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13507 .adc_nids = alc861_adc_nids,
13508 .input_mux = &alc861_capture_source,
13511 .mixers = { alc861_3ST_mixer },
13512 .init_verbs = { alc861_threestack_init_verbs },
13513 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13514 .dac_nids = alc660_dac_nids,
13515 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13516 .channel_mode = alc861_threestack_modes,
13518 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13519 .adc_nids = alc861_adc_nids,
13520 .input_mux = &alc861_capture_source,
13522 [ALC861_UNIWILL_M31] = {
13523 .mixers = { alc861_uniwill_m31_mixer },
13524 .init_verbs = { alc861_uniwill_m31_init_verbs },
13525 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13526 .dac_nids = alc861_dac_nids,
13527 .dig_out_nid = ALC861_DIGOUT_NID,
13528 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13529 .channel_mode = alc861_uniwill_m31_modes,
13531 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13532 .adc_nids = alc861_adc_nids,
13533 .input_mux = &alc861_capture_source,
13535 [ALC861_TOSHIBA] = {
13536 .mixers = { alc861_toshiba_mixer },
13537 .init_verbs = { alc861_base_init_verbs,
13538 alc861_toshiba_init_verbs },
13539 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13540 .dac_nids = alc861_dac_nids,
13541 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13542 .channel_mode = alc883_3ST_2ch_modes,
13543 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13544 .adc_nids = alc861_adc_nids,
13545 .input_mux = &alc861_capture_source,
13546 .unsol_event = alc861_toshiba_unsol_event,
13547 .init_hook = alc861_toshiba_automute,
13550 .mixers = { alc861_asus_mixer },
13551 .init_verbs = { alc861_asus_init_verbs },
13552 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13553 .dac_nids = alc861_dac_nids,
13554 .dig_out_nid = ALC861_DIGOUT_NID,
13555 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13556 .channel_mode = alc861_asus_modes,
13559 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13560 .adc_nids = alc861_adc_nids,
13561 .input_mux = &alc861_capture_source,
13563 [ALC861_ASUS_LAPTOP] = {
13564 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13565 .init_verbs = { alc861_asus_init_verbs,
13566 alc861_asus_laptop_init_verbs },
13567 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13568 .dac_nids = alc861_dac_nids,
13569 .dig_out_nid = ALC861_DIGOUT_NID,
13570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13571 .channel_mode = alc883_3ST_2ch_modes,
13573 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13574 .adc_nids = alc861_adc_nids,
13575 .input_mux = &alc861_capture_source,
13580 static int patch_alc861(struct hda_codec *codec)
13582 struct alc_spec *spec;
13586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13590 codec->spec = spec;
13592 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13596 if (board_config < 0) {
13597 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13598 "trying auto-probe from BIOS...\n");
13599 board_config = ALC861_AUTO;
13602 if (board_config == ALC861_AUTO) {
13603 /* automatic parse from the BIOS config */
13604 err = alc861_parse_auto_config(codec);
13610 "hda_codec: Cannot set up configuration "
13611 "from BIOS. Using base mode...\n");
13612 board_config = ALC861_3ST_DIG;
13616 if (board_config != ALC861_AUTO)
13617 setup_preset(spec, &alc861_presets[board_config]);
13619 spec->stream_name_analog = "ALC861 Analog";
13620 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13621 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13623 spec->stream_name_digital = "ALC861 Digital";
13624 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13625 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13627 spec->vmaster_nid = 0x03;
13629 codec->patch_ops = alc_patch_ops;
13630 if (board_config == ALC861_AUTO)
13631 spec->init_hook = alc861_auto_init;
13632 #ifdef CONFIG_SND_HDA_POWER_SAVE
13633 if (!spec->loopback.amplist)
13634 spec->loopback.amplist = alc861_loopbacks;
13641 * ALC861-VD support
13645 * In addition, an independent DAC
13647 #define ALC861VD_DIGOUT_NID 0x06
13649 static hda_nid_t alc861vd_dac_nids[4] = {
13650 /* front, surr, clfe, side surr */
13651 0x02, 0x03, 0x04, 0x05
13654 /* dac_nids for ALC660vd are in a different order - according to
13655 * Realtek's driver.
13656 * This should probably tesult in a different mixer for 6stack models
13657 * of ALC660vd codecs, but for now there is only 3stack mixer
13658 * - and it is the same as in 861vd.
13659 * adc_nids in ALC660vd are (is) the same as in 861vd
13661 static hda_nid_t alc660vd_dac_nids[3] = {
13662 /* front, rear, clfe, rear_surr */
13666 static hda_nid_t alc861vd_adc_nids[1] = {
13671 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13674 /* FIXME: should be a matrix-type input source selection */
13675 static struct hda_input_mux alc861vd_capture_source = {
13679 { "Front Mic", 0x1 },
13685 static struct hda_input_mux alc861vd_dallas_capture_source = {
13688 { "Ext Mic", 0x0 },
13689 { "Int Mic", 0x1 },
13693 static struct hda_input_mux alc861vd_hp_capture_source = {
13696 { "Front Mic", 0x0 },
13697 { "ATAPI Mic", 0x1 },
13701 #define alc861vd_mux_enum_info alc_mux_enum_info
13702 #define alc861vd_mux_enum_get alc_mux_enum_get
13703 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13704 #define alc861vd_mux_enum_put alc882_mux_enum_put
13709 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13716 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13717 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13718 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13719 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13720 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13727 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13728 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13729 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13730 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13731 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13735 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13736 { 6, alc861vd_6stack_ch6_init },
13737 { 8, alc861vd_6stack_ch8_init },
13740 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13743 .name = "Channel Mode",
13744 .info = alc_ch_mode_info,
13745 .get = alc_ch_mode_get,
13746 .put = alc_ch_mode_put,
13751 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13752 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13753 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13757 /* The multiple "Capture Source" controls confuse alsamixer
13758 * So call somewhat different..
13760 /* .name = "Capture Source", */
13761 .name = "Input Source",
13763 .info = alc861vd_mux_enum_info,
13764 .get = alc861vd_mux_enum_get,
13765 .put = alc861vd_mux_enum_put,
13770 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13771 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13773 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13774 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13777 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13778 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13780 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13782 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13784 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13785 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13787 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13788 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13792 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13796 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13797 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13798 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13800 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13801 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13803 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13804 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13806 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13807 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13812 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13813 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13814 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13816 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13822 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13823 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13824 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13832 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13833 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13838 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13839 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13840 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13841 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13845 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13847 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13849 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13850 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13851 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13853 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13854 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13859 /* Pin assignment: Speaker=0x14, HP = 0x15,
13860 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13862 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13863 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13864 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13866 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13867 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13868 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13869 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13870 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13871 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13872 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13873 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13874 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13878 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13879 * Front Mic=0x18, ATAPI Mic = 0x19,
13881 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13882 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13883 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13885 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13886 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13888 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13889 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13895 * generic initialization of ADC, input mixers and output mixers
13897 static struct hda_verb alc861vd_volume_init_verbs[] = {
13899 * Unmute ADC0 and set the default input to mic-in
13901 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13902 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13904 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13905 * the analog-loopback mixer widget
13907 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13908 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13909 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13910 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13911 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13912 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13914 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13918 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13921 * Set up output mixers (0x02 - 0x05)
13923 /* set vol=0 to output mixers */
13924 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13925 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13926 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13927 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13929 /* set up input amps for analog loopback */
13930 /* Amp Indices: DAC = 0, mixer = 1 */
13931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13938 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13944 * 3-stack pin configuration:
13945 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13947 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13949 * Set pin mode and muting
13951 /* set front pin widgets 0x14 for output */
13952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13954 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13956 /* Mic (rear) pin: input vref at 80% */
13957 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13959 /* Front Mic pin: input vref at 80% */
13960 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13961 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13962 /* Line In pin: input */
13963 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13964 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13965 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13966 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13967 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13968 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13969 /* CD pin widget for input */
13970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13976 * 6-stack pin configuration:
13978 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13980 * Set pin mode and muting
13982 /* set front pin widgets 0x14 for output */
13983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13987 /* Rear Pin: output 1 (0x0d) */
13988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13990 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 /* CLFE Pin: output 2 (0x0e) */
13992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13995 /* Side Pin: output 3 (0x0f) */
13996 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13997 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13998 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14000 /* Mic (rear) pin: input vref at 80% */
14001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14003 /* Front Mic pin: input vref at 80% */
14004 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14005 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14006 /* Line In pin: input */
14007 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14008 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14009 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14010 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14011 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14012 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14013 /* CD pin widget for input */
14014 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14019 static struct hda_verb alc861vd_eapd_verbs[] = {
14020 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14024 static struct hda_verb alc660vd_eapd_verbs[] = {
14025 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14026 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14030 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14035 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14039 /* toggle speaker-output according to the hp-jack state */
14040 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14042 unsigned int present;
14043 unsigned char bits;
14045 present = snd_hda_codec_read(codec, 0x1b, 0,
14046 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14047 bits = present ? HDA_AMP_MUTE : 0;
14048 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14049 HDA_AMP_MUTE, bits);
14052 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14054 unsigned int present;
14055 unsigned char bits;
14057 present = snd_hda_codec_read(codec, 0x18, 0,
14058 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14059 bits = present ? HDA_AMP_MUTE : 0;
14060 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14061 HDA_AMP_MUTE, bits);
14064 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14066 alc861vd_lenovo_hp_automute(codec);
14067 alc861vd_lenovo_mic_automute(codec);
14070 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14073 switch (res >> 26) {
14074 case ALC880_HP_EVENT:
14075 alc861vd_lenovo_hp_automute(codec);
14077 case ALC880_MIC_EVENT:
14078 alc861vd_lenovo_mic_automute(codec);
14083 static struct hda_verb alc861vd_dallas_verbs[] = {
14084 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14085 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14086 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14087 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14091 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14092 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14094 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14095 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14096 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14099 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14102 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14103 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14104 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14105 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14107 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14108 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14109 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14110 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14111 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14112 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14113 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14114 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14122 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14128 /* toggle speaker-output according to the hp-jack state */
14129 static void alc861vd_dallas_automute(struct hda_codec *codec)
14131 unsigned int present;
14133 present = snd_hda_codec_read(codec, 0x15, 0,
14134 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14135 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14136 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14139 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14141 if ((res >> 26) == ALC880_HP_EVENT)
14142 alc861vd_dallas_automute(codec);
14145 #ifdef CONFIG_SND_HDA_POWER_SAVE
14146 #define alc861vd_loopbacks alc880_loopbacks
14149 /* pcm configuration: identiacal with ALC880 */
14150 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14151 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14152 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14153 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14156 * configuration and preset
14158 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14159 [ALC660VD_3ST] = "3stack-660",
14160 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14161 [ALC861VD_3ST] = "3stack",
14162 [ALC861VD_3ST_DIG] = "3stack-digout",
14163 [ALC861VD_6ST_DIG] = "6stack-digout",
14164 [ALC861VD_LENOVO] = "lenovo",
14165 [ALC861VD_DALLAS] = "dallas",
14166 [ALC861VD_HP] = "hp",
14167 [ALC861VD_AUTO] = "auto",
14170 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14171 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14172 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14173 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14174 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14175 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14176 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14177 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14178 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14179 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14180 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14181 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14182 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14183 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14184 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14185 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14186 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14187 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14191 static struct alc_config_preset alc861vd_presets[] = {
14193 .mixers = { alc861vd_3st_mixer },
14194 .init_verbs = { alc861vd_volume_init_verbs,
14195 alc861vd_3stack_init_verbs },
14196 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14197 .dac_nids = alc660vd_dac_nids,
14198 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14199 .channel_mode = alc861vd_3stack_2ch_modes,
14200 .input_mux = &alc861vd_capture_source,
14202 [ALC660VD_3ST_DIG] = {
14203 .mixers = { alc861vd_3st_mixer },
14204 .init_verbs = { alc861vd_volume_init_verbs,
14205 alc861vd_3stack_init_verbs },
14206 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14207 .dac_nids = alc660vd_dac_nids,
14208 .dig_out_nid = ALC861VD_DIGOUT_NID,
14209 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14210 .channel_mode = alc861vd_3stack_2ch_modes,
14211 .input_mux = &alc861vd_capture_source,
14214 .mixers = { alc861vd_3st_mixer },
14215 .init_verbs = { alc861vd_volume_init_verbs,
14216 alc861vd_3stack_init_verbs },
14217 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14218 .dac_nids = alc861vd_dac_nids,
14219 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14220 .channel_mode = alc861vd_3stack_2ch_modes,
14221 .input_mux = &alc861vd_capture_source,
14223 [ALC861VD_3ST_DIG] = {
14224 .mixers = { alc861vd_3st_mixer },
14225 .init_verbs = { alc861vd_volume_init_verbs,
14226 alc861vd_3stack_init_verbs },
14227 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14228 .dac_nids = alc861vd_dac_nids,
14229 .dig_out_nid = ALC861VD_DIGOUT_NID,
14230 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14231 .channel_mode = alc861vd_3stack_2ch_modes,
14232 .input_mux = &alc861vd_capture_source,
14234 [ALC861VD_6ST_DIG] = {
14235 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14236 .init_verbs = { alc861vd_volume_init_verbs,
14237 alc861vd_6stack_init_verbs },
14238 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14239 .dac_nids = alc861vd_dac_nids,
14240 .dig_out_nid = ALC861VD_DIGOUT_NID,
14241 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14242 .channel_mode = alc861vd_6stack_modes,
14243 .input_mux = &alc861vd_capture_source,
14245 [ALC861VD_LENOVO] = {
14246 .mixers = { alc861vd_lenovo_mixer },
14247 .init_verbs = { alc861vd_volume_init_verbs,
14248 alc861vd_3stack_init_verbs,
14249 alc861vd_eapd_verbs,
14250 alc861vd_lenovo_unsol_verbs },
14251 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14252 .dac_nids = alc660vd_dac_nids,
14253 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14254 .channel_mode = alc861vd_3stack_2ch_modes,
14255 .input_mux = &alc861vd_capture_source,
14256 .unsol_event = alc861vd_lenovo_unsol_event,
14257 .init_hook = alc861vd_lenovo_automute,
14259 [ALC861VD_DALLAS] = {
14260 .mixers = { alc861vd_dallas_mixer },
14261 .init_verbs = { alc861vd_dallas_verbs },
14262 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14263 .dac_nids = alc861vd_dac_nids,
14264 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14265 .channel_mode = alc861vd_3stack_2ch_modes,
14266 .input_mux = &alc861vd_dallas_capture_source,
14267 .unsol_event = alc861vd_dallas_unsol_event,
14268 .init_hook = alc861vd_dallas_automute,
14271 .mixers = { alc861vd_hp_mixer },
14272 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14273 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14274 .dac_nids = alc861vd_dac_nids,
14275 .dig_out_nid = ALC861VD_DIGOUT_NID,
14276 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14277 .channel_mode = alc861vd_3stack_2ch_modes,
14278 .input_mux = &alc861vd_hp_capture_source,
14279 .unsol_event = alc861vd_dallas_unsol_event,
14280 .init_hook = alc861vd_dallas_automute,
14285 * BIOS auto configuration
14287 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14288 hda_nid_t nid, int pin_type, int dac_idx)
14290 alc_set_pin_output(codec, nid, pin_type);
14293 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14295 struct alc_spec *spec = codec->spec;
14298 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14299 for (i = 0; i <= HDA_SIDE; i++) {
14300 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14301 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14303 alc861vd_auto_set_output_and_unmute(codec, nid,
14309 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14311 struct alc_spec *spec = codec->spec;
14314 pin = spec->autocfg.hp_pins[0];
14315 if (pin) /* connect to front and use dac 0 */
14316 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14317 pin = spec->autocfg.speaker_pins[0];
14319 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14322 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14323 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14325 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14327 struct alc_spec *spec = codec->spec;
14330 for (i = 0; i < AUTO_PIN_LAST; i++) {
14331 hda_nid_t nid = spec->autocfg.input_pins[i];
14332 if (alc861vd_is_input_pin(nid)) {
14333 snd_hda_codec_write(codec, nid, 0,
14334 AC_VERB_SET_PIN_WIDGET_CONTROL,
14335 i <= AUTO_PIN_FRONT_MIC ?
14336 PIN_VREF80 : PIN_IN);
14337 if (nid != ALC861VD_PIN_CD_NID)
14338 snd_hda_codec_write(codec, nid, 0,
14339 AC_VERB_SET_AMP_GAIN_MUTE,
14345 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14347 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14348 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14350 /* add playback controls from the parsed DAC table */
14351 /* Based on ALC880 version. But ALC861VD has separate,
14352 * different NIDs for mute/unmute switch and volume control */
14353 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14354 const struct auto_pin_cfg *cfg)
14357 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14358 hda_nid_t nid_v, nid_s;
14361 for (i = 0; i < cfg->line_outs; i++) {
14362 if (!spec->multiout.dac_nids[i])
14364 nid_v = alc861vd_idx_to_mixer_vol(
14366 spec->multiout.dac_nids[i]));
14367 nid_s = alc861vd_idx_to_mixer_switch(
14369 spec->multiout.dac_nids[i]));
14373 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14374 "Center Playback Volume",
14375 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14379 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14380 "LFE Playback Volume",
14381 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14385 err = add_control(spec, ALC_CTL_BIND_MUTE,
14386 "Center Playback Switch",
14387 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14391 err = add_control(spec, ALC_CTL_BIND_MUTE,
14392 "LFE Playback Switch",
14393 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14398 sprintf(name, "%s Playback Volume", chname[i]);
14399 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14400 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14404 sprintf(name, "%s Playback Switch", chname[i]);
14405 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14406 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14415 /* add playback controls for speaker and HP outputs */
14416 /* Based on ALC880 version. But ALC861VD has separate,
14417 * different NIDs for mute/unmute switch and volume control */
14418 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14419 hda_nid_t pin, const char *pfx)
14421 hda_nid_t nid_v, nid_s;
14428 if (alc880_is_fixed_pin(pin)) {
14429 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14430 /* specify the DAC as the extra output */
14431 if (!spec->multiout.hp_nid)
14432 spec->multiout.hp_nid = nid_v;
14434 spec->multiout.extra_out_nid[0] = nid_v;
14435 /* control HP volume/switch on the output mixer amp */
14436 nid_v = alc861vd_idx_to_mixer_vol(
14437 alc880_fixed_pin_idx(pin));
14438 nid_s = alc861vd_idx_to_mixer_switch(
14439 alc880_fixed_pin_idx(pin));
14441 sprintf(name, "%s Playback Volume", pfx);
14442 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14443 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14446 sprintf(name, "%s Playback Switch", pfx);
14447 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14448 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14451 } else if (alc880_is_multi_pin(pin)) {
14452 /* set manual connection */
14453 /* we have only a switch on HP-out PIN */
14454 sprintf(name, "%s Playback Switch", pfx);
14455 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14456 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14463 /* parse the BIOS configuration and set up the alc_spec
14464 * return 1 if successful, 0 if the proper config is not found,
14465 * or a negative error code
14466 * Based on ALC880 version - had to change it to override
14467 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14468 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14470 struct alc_spec *spec = codec->spec;
14472 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14474 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14478 if (!spec->autocfg.line_outs)
14479 return 0; /* can't find valid BIOS pin config */
14481 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14484 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14487 err = alc861vd_auto_create_extra_out(spec,
14488 spec->autocfg.speaker_pins[0],
14492 err = alc861vd_auto_create_extra_out(spec,
14493 spec->autocfg.hp_pins[0],
14497 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14501 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14503 if (spec->autocfg.dig_out_pin)
14504 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14506 if (spec->kctls.list)
14507 add_mixer(spec, spec->kctls.list);
14509 add_verb(spec, alc861vd_volume_init_verbs);
14511 spec->num_mux_defs = 1;
14512 spec->input_mux = &spec->private_imux;
14514 err = alc_auto_add_mic_boost(codec);
14518 store_pin_configs(codec);
14522 /* additional initialization for auto-configuration model */
14523 static void alc861vd_auto_init(struct hda_codec *codec)
14525 struct alc_spec *spec = codec->spec;
14526 alc861vd_auto_init_multi_out(codec);
14527 alc861vd_auto_init_hp_out(codec);
14528 alc861vd_auto_init_analog_input(codec);
14529 alc861vd_auto_init_input_src(codec);
14530 if (spec->unsol_event)
14531 alc_inithook(codec);
14534 static int patch_alc861vd(struct hda_codec *codec)
14536 struct alc_spec *spec;
14537 int err, board_config;
14539 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14543 codec->spec = spec;
14545 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14549 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14550 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14551 "ALC861VD, trying auto-probe from BIOS...\n");
14552 board_config = ALC861VD_AUTO;
14555 if (board_config == ALC861VD_AUTO) {
14556 /* automatic parse from the BIOS config */
14557 err = alc861vd_parse_auto_config(codec);
14563 "hda_codec: Cannot set up configuration "
14564 "from BIOS. Using base mode...\n");
14565 board_config = ALC861VD_3ST;
14569 if (board_config != ALC861VD_AUTO)
14570 setup_preset(spec, &alc861vd_presets[board_config]);
14572 if (codec->vendor_id == 0x10ec0660) {
14573 spec->stream_name_analog = "ALC660-VD Analog";
14574 spec->stream_name_digital = "ALC660-VD Digital";
14575 /* always turn on EAPD */
14576 add_verb(spec, alc660vd_eapd_verbs);
14578 spec->stream_name_analog = "ALC861VD Analog";
14579 spec->stream_name_digital = "ALC861VD Digital";
14582 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14583 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14585 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14586 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14588 spec->adc_nids = alc861vd_adc_nids;
14589 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14590 spec->capsrc_nids = alc861vd_capsrc_nids;
14592 add_mixer(spec, alc861vd_capture_mixer);
14594 spec->vmaster_nid = 0x02;
14596 codec->patch_ops = alc_patch_ops;
14598 if (board_config == ALC861VD_AUTO)
14599 spec->init_hook = alc861vd_auto_init;
14600 #ifdef CONFIG_SND_HDA_POWER_SAVE
14601 if (!spec->loopback.amplist)
14602 spec->loopback.amplist = alc861vd_loopbacks;
14611 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14612 * configuration. Each pin widget can choose any input DACs and a mixer.
14613 * Each ADC is connected from a mixer of all inputs. This makes possible
14614 * 6-channel independent captures.
14616 * In addition, an independent DAC for the multi-playback (not used in this
14619 #define ALC662_DIGOUT_NID 0x06
14620 #define ALC662_DIGIN_NID 0x0a
14622 static hda_nid_t alc662_dac_nids[4] = {
14623 /* front, rear, clfe, rear_surr */
14627 static hda_nid_t alc662_adc_nids[1] = {
14632 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14635 /* FIXME: should be a matrix-type input source selection */
14636 static struct hda_input_mux alc662_capture_source = {
14640 { "Front Mic", 0x1 },
14646 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14654 static struct hda_input_mux alc662_eeepc_capture_source = {
14662 static struct hda_input_mux alc663_capture_source = {
14666 { "Front Mic", 0x1 },
14671 static struct hda_input_mux alc663_m51va_capture_source = {
14674 { "Ext-Mic", 0x0 },
14679 #define alc662_mux_enum_info alc_mux_enum_info
14680 #define alc662_mux_enum_get alc_mux_enum_get
14681 #define alc662_mux_enum_put alc882_mux_enum_put
14686 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14693 static struct hda_verb alc662_3ST_ch2_init[] = {
14694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14696 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14697 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14704 static struct hda_verb alc662_3ST_ch6_init[] = {
14705 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14706 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14707 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14710 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14714 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14715 { 2, alc662_3ST_ch2_init },
14716 { 6, alc662_3ST_ch6_init },
14722 static struct hda_verb alc662_sixstack_ch6_init[] = {
14723 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14724 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14725 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14732 static struct hda_verb alc662_sixstack_ch8_init[] = {
14733 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14734 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14735 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14739 static struct hda_channel_mode alc662_5stack_modes[2] = {
14740 { 2, alc662_sixstack_ch6_init },
14741 { 6, alc662_sixstack_ch8_init },
14744 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14745 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14748 static struct snd_kcontrol_new alc662_base_mixer[] = {
14749 /* output mixer control */
14750 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14751 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14752 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14753 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14754 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14755 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14756 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14757 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14760 /*Input mixer control */
14761 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14762 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14763 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14764 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14765 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14766 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14767 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14768 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14772 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14773 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14774 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14782 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14783 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14784 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14785 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14789 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14790 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14791 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14792 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14793 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14794 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14795 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14796 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14797 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14798 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14799 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14800 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14801 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14802 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14805 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14806 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14807 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14808 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14812 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14813 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14814 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14815 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14816 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14817 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14825 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14828 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14831 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14832 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14833 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14835 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14836 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14837 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14841 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14842 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14844 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14845 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14846 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14847 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14848 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14849 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14850 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14851 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14852 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14853 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14859 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14860 .ops = &snd_hda_bind_vol,
14862 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14863 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14868 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14869 .ops = &snd_hda_bind_sw,
14871 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14872 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14877 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14878 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14879 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14885 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14886 .ops = &snd_hda_bind_sw,
14888 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14889 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14890 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14895 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14896 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14897 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14900 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14901 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14906 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14907 .ops = &snd_hda_bind_sw,
14909 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14910 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14911 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14916 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14917 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14918 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14921 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14922 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14926 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14927 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14928 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14933 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14937 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14938 .ops = &snd_hda_bind_vol,
14940 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14941 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14946 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14947 .ops = &snd_hda_bind_sw,
14949 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14950 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14955 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14956 HDA_BIND_VOL("Master Playback Volume",
14957 &alc663_asus_two_bind_master_vol),
14958 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14959 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14962 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14966 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14967 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14968 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14969 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14970 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14976 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14977 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14978 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14979 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14980 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14981 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14985 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14986 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14990 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14991 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14997 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14998 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15004 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15007 .name = "Channel Mode",
15008 .info = alc_ch_mode_info,
15009 .get = alc_ch_mode_get,
15010 .put = alc_ch_mode_put,
15015 static struct hda_verb alc662_init_verbs[] = {
15016 /* ADC: mute amp left and right */
15017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15018 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15019 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15034 /* Front Pin: output 0 (0x0c) */
15035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15036 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15038 /* Rear Pin: output 1 (0x0d) */
15039 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15042 /* CLFE Pin: output 2 (0x0e) */
15043 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15044 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15046 /* Mic (rear) pin: input vref at 80% */
15047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15048 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15049 /* Front Mic pin: input vref at 80% */
15050 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15051 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15052 /* Line In pin: input */
15053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15055 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15058 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15059 /* CD pin widget for input */
15060 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15062 /* FIXME: use matrix-type input source selection */
15063 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15072 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15073 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15075 /* always trun on EAPD */
15076 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15077 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15082 static struct hda_verb alc662_sue_init_verbs[] = {
15083 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15084 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15088 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15090 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15094 /* Set Unsolicited Event*/
15095 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15097 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15102 * generic initialization of ADC, input mixers and output mixers
15104 static struct hda_verb alc662_auto_init_verbs[] = {
15106 * Unmute ADC and set the default input to mic-in
15108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15111 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15113 * Note: PASD motherboards uses the Line In 2 as the input for front
15114 * panel mic (mic 2)
15116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15124 * Set up output mixers (0x0c - 0x0f)
15126 /* set vol=0 to output mixers */
15127 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15128 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15131 /* set up input amps for analog loopback */
15132 /* Amp Indices: DAC = 0, mixer = 1 */
15133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15136 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15137 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15138 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15141 /* FIXME: use matrix-type input source selection */
15142 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15149 /* additional verbs for ALC663 */
15150 static struct hda_verb alc663_auto_init_verbs[] = {
15151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15152 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15156 static struct hda_verb alc663_m51va_init_verbs[] = {
15157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15158 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15159 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15160 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15161 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15164 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15165 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15169 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15170 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15171 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15172 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15173 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15175 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15176 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15180 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15181 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15184 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15187 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15188 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15192 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15194 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15195 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15197 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15198 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15199 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15203 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15205 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15206 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15207 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15210 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15212 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15214 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15219 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15223 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15229 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15230 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15231 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15235 static struct hda_verb alc663_g71v_init_verbs[] = {
15236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15237 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15238 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15240 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15241 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15242 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15244 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15245 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15246 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15250 static struct hda_verb alc663_g50v_init_verbs[] = {
15251 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15252 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15253 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15255 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15256 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15260 static struct hda_verb alc662_ecs_init_verbs[] = {
15261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15264 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15268 /* capture mixer elements */
15269 static struct snd_kcontrol_new alc662_capture_mixer[] = {
15270 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15271 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15273 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15274 /* The multiple "Capture Source" controls confuse alsamixer
15275 * So call somewhat different..
15277 /* .name = "Capture Source", */
15278 .name = "Input Source",
15280 .info = alc662_mux_enum_info,
15281 .get = alc662_mux_enum_get,
15282 .put = alc662_mux_enum_put,
15287 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15288 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15289 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15293 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15295 unsigned int present;
15296 unsigned char bits;
15298 present = snd_hda_codec_read(codec, 0x14, 0,
15299 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15300 bits = present ? HDA_AMP_MUTE : 0;
15301 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15302 HDA_AMP_MUTE, bits);
15305 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15307 unsigned int present;
15308 unsigned char bits;
15310 present = snd_hda_codec_read(codec, 0x1b, 0,
15311 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15312 bits = present ? HDA_AMP_MUTE : 0;
15313 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15314 HDA_AMP_MUTE, bits);
15315 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15316 HDA_AMP_MUTE, bits);
15319 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15322 if ((res >> 26) == ALC880_HP_EVENT)
15323 alc662_lenovo_101e_all_automute(codec);
15324 if ((res >> 26) == ALC880_FRONT_EVENT)
15325 alc662_lenovo_101e_ispeaker_automute(codec);
15328 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15330 unsigned int present;
15332 present = snd_hda_codec_read(codec, 0x18, 0,
15333 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15334 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15335 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15336 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15337 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15338 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15339 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15340 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15341 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15344 /* unsolicited event for HP jack sensing */
15345 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15348 if ((res >> 26) == ALC880_HP_EVENT)
15349 alc262_hippo1_automute( codec );
15351 if ((res >> 26) == ALC880_MIC_EVENT)
15352 alc662_eeepc_mic_automute(codec);
15355 static void alc662_eeepc_inithook(struct hda_codec *codec)
15357 alc262_hippo1_automute( codec );
15358 alc662_eeepc_mic_automute(codec);
15361 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15364 unsigned int present;
15366 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15367 present = snd_hda_codec_read(codec, 0x14, 0,
15368 AC_VERB_GET_PIN_SENSE, 0);
15369 present = (present & 0x80000000) != 0;
15371 /* mute internal speaker */
15372 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15373 HDA_AMP_MUTE, HDA_AMP_MUTE);
15375 /* unmute internal speaker if necessary */
15376 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15377 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15378 HDA_AMP_MUTE, mute);
15382 /* unsolicited event for HP jack sensing */
15383 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15386 if ((res >> 26) == ALC880_HP_EVENT)
15387 alc662_eeepc_ep20_automute(codec);
15390 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15392 alc662_eeepc_ep20_automute(codec);
15395 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15397 unsigned int present;
15398 unsigned char bits;
15400 present = snd_hda_codec_read(codec, 0x21, 0,
15401 AC_VERB_GET_PIN_SENSE, 0)
15402 & AC_PINSENSE_PRESENCE;
15403 bits = present ? HDA_AMP_MUTE : 0;
15404 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15405 AMP_IN_MUTE(0), bits);
15406 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15407 AMP_IN_MUTE(0), bits);
15410 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15412 unsigned int present;
15413 unsigned char bits;
15415 present = snd_hda_codec_read(codec, 0x21, 0,
15416 AC_VERB_GET_PIN_SENSE, 0)
15417 & AC_PINSENSE_PRESENCE;
15418 bits = present ? HDA_AMP_MUTE : 0;
15419 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15420 AMP_IN_MUTE(0), bits);
15421 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15422 AMP_IN_MUTE(0), bits);
15423 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15424 AMP_IN_MUTE(0), bits);
15425 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15426 AMP_IN_MUTE(0), bits);
15429 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15431 unsigned int present;
15432 unsigned char bits;
15434 present = snd_hda_codec_read(codec, 0x15, 0,
15435 AC_VERB_GET_PIN_SENSE, 0)
15436 & AC_PINSENSE_PRESENCE;
15437 bits = present ? HDA_AMP_MUTE : 0;
15438 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15439 AMP_IN_MUTE(0), bits);
15440 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15441 AMP_IN_MUTE(0), bits);
15442 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15443 AMP_IN_MUTE(0), bits);
15444 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15445 AMP_IN_MUTE(0), bits);
15448 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15450 unsigned int present;
15451 unsigned char bits;
15453 present = snd_hda_codec_read(codec, 0x1b, 0,
15454 AC_VERB_GET_PIN_SENSE, 0)
15455 & AC_PINSENSE_PRESENCE;
15456 bits = present ? 0 : PIN_OUT;
15457 snd_hda_codec_write(codec, 0x14, 0,
15458 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15461 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15463 unsigned int present1, present2;
15465 present1 = snd_hda_codec_read(codec, 0x21, 0,
15466 AC_VERB_GET_PIN_SENSE, 0)
15467 & AC_PINSENSE_PRESENCE;
15468 present2 = snd_hda_codec_read(codec, 0x15, 0,
15469 AC_VERB_GET_PIN_SENSE, 0)
15470 & AC_PINSENSE_PRESENCE;
15472 if (present1 || present2) {
15473 snd_hda_codec_write_cache(codec, 0x14, 0,
15474 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15476 snd_hda_codec_write_cache(codec, 0x14, 0,
15477 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15481 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15483 unsigned int present1, present2;
15485 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15486 AC_VERB_GET_PIN_SENSE, 0)
15487 & AC_PINSENSE_PRESENCE;
15488 present2 = snd_hda_codec_read(codec, 0x15, 0,
15489 AC_VERB_GET_PIN_SENSE, 0)
15490 & AC_PINSENSE_PRESENCE;
15492 if (present1 || present2) {
15493 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15494 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15495 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15496 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15498 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15499 AMP_IN_MUTE(0), 0);
15500 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15501 AMP_IN_MUTE(0), 0);
15505 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15507 unsigned int present;
15509 present = snd_hda_codec_read(codec, 0x18, 0,
15510 AC_VERB_GET_PIN_SENSE, 0)
15511 & AC_PINSENSE_PRESENCE;
15512 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15513 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15514 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15515 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15516 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15517 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15518 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15519 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15522 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15525 switch (res >> 26) {
15526 case ALC880_HP_EVENT:
15527 alc663_m51va_speaker_automute(codec);
15529 case ALC880_MIC_EVENT:
15530 alc663_m51va_mic_automute(codec);
15535 static void alc663_m51va_inithook(struct hda_codec *codec)
15537 alc663_m51va_speaker_automute(codec);
15538 alc663_m51va_mic_automute(codec);
15541 /* ***************** Mode1 ******************************/
15542 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15545 switch (res >> 26) {
15546 case ALC880_HP_EVENT:
15547 alc663_m51va_speaker_automute(codec);
15549 case ALC880_MIC_EVENT:
15550 alc662_eeepc_mic_automute(codec);
15555 static void alc663_mode1_inithook(struct hda_codec *codec)
15557 alc663_m51va_speaker_automute(codec);
15558 alc662_eeepc_mic_automute(codec);
15560 /* ***************** Mode2 ******************************/
15561 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15564 switch (res >> 26) {
15565 case ALC880_HP_EVENT:
15566 alc662_f5z_speaker_automute(codec);
15568 case ALC880_MIC_EVENT:
15569 alc662_eeepc_mic_automute(codec);
15574 static void alc662_mode2_inithook(struct hda_codec *codec)
15576 alc662_f5z_speaker_automute(codec);
15577 alc662_eeepc_mic_automute(codec);
15579 /* ***************** Mode3 ******************************/
15580 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15583 switch (res >> 26) {
15584 case ALC880_HP_EVENT:
15585 alc663_two_hp_m1_speaker_automute(codec);
15587 case ALC880_MIC_EVENT:
15588 alc662_eeepc_mic_automute(codec);
15593 static void alc663_mode3_inithook(struct hda_codec *codec)
15595 alc663_two_hp_m1_speaker_automute(codec);
15596 alc662_eeepc_mic_automute(codec);
15598 /* ***************** Mode4 ******************************/
15599 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15602 switch (res >> 26) {
15603 case ALC880_HP_EVENT:
15604 alc663_21jd_two_speaker_automute(codec);
15606 case ALC880_MIC_EVENT:
15607 alc662_eeepc_mic_automute(codec);
15612 static void alc663_mode4_inithook(struct hda_codec *codec)
15614 alc663_21jd_two_speaker_automute(codec);
15615 alc662_eeepc_mic_automute(codec);
15617 /* ***************** Mode5 ******************************/
15618 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15621 switch (res >> 26) {
15622 case ALC880_HP_EVENT:
15623 alc663_15jd_two_speaker_automute(codec);
15625 case ALC880_MIC_EVENT:
15626 alc662_eeepc_mic_automute(codec);
15631 static void alc663_mode5_inithook(struct hda_codec *codec)
15633 alc663_15jd_two_speaker_automute(codec);
15634 alc662_eeepc_mic_automute(codec);
15636 /* ***************** Mode6 ******************************/
15637 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15640 switch (res >> 26) {
15641 case ALC880_HP_EVENT:
15642 alc663_two_hp_m2_speaker_automute(codec);
15644 case ALC880_MIC_EVENT:
15645 alc662_eeepc_mic_automute(codec);
15650 static void alc663_mode6_inithook(struct hda_codec *codec)
15652 alc663_two_hp_m2_speaker_automute(codec);
15653 alc662_eeepc_mic_automute(codec);
15656 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15658 unsigned int present;
15659 unsigned char bits;
15661 present = snd_hda_codec_read(codec, 0x21, 0,
15662 AC_VERB_GET_PIN_SENSE, 0)
15663 & AC_PINSENSE_PRESENCE;
15664 bits = present ? HDA_AMP_MUTE : 0;
15665 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15666 HDA_AMP_MUTE, bits);
15667 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15668 HDA_AMP_MUTE, bits);
15671 static void alc663_g71v_front_automute(struct hda_codec *codec)
15673 unsigned int present;
15674 unsigned char bits;
15676 present = snd_hda_codec_read(codec, 0x15, 0,
15677 AC_VERB_GET_PIN_SENSE, 0)
15678 & AC_PINSENSE_PRESENCE;
15679 bits = present ? HDA_AMP_MUTE : 0;
15680 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15681 HDA_AMP_MUTE, bits);
15684 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15687 switch (res >> 26) {
15688 case ALC880_HP_EVENT:
15689 alc663_g71v_hp_automute(codec);
15691 case ALC880_FRONT_EVENT:
15692 alc663_g71v_front_automute(codec);
15694 case ALC880_MIC_EVENT:
15695 alc662_eeepc_mic_automute(codec);
15700 static void alc663_g71v_inithook(struct hda_codec *codec)
15702 alc663_g71v_front_automute(codec);
15703 alc663_g71v_hp_automute(codec);
15704 alc662_eeepc_mic_automute(codec);
15707 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15710 switch (res >> 26) {
15711 case ALC880_HP_EVENT:
15712 alc663_m51va_speaker_automute(codec);
15714 case ALC880_MIC_EVENT:
15715 alc662_eeepc_mic_automute(codec);
15720 static void alc663_g50v_inithook(struct hda_codec *codec)
15722 alc663_m51va_speaker_automute(codec);
15723 alc662_eeepc_mic_automute(codec);
15726 /* bind hp and internal speaker mute (with plug check) */
15727 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15728 struct snd_ctl_elem_value *ucontrol)
15730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15731 long *valp = ucontrol->value.integer.value;
15734 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15736 valp[0] ? 0 : HDA_AMP_MUTE);
15737 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15739 valp[1] ? 0 : HDA_AMP_MUTE);
15741 alc262_hippo1_automute(codec);
15745 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15746 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15749 .name = "Master Playback Switch",
15750 .info = snd_hda_mixer_amp_switch_info,
15751 .get = snd_hda_mixer_amp_switch_get,
15752 .put = alc662_ecs_master_sw_put,
15753 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15756 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15757 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15758 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15760 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15761 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15762 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15766 #ifdef CONFIG_SND_HDA_POWER_SAVE
15767 #define alc662_loopbacks alc880_loopbacks
15771 /* pcm configuration: identiacal with ALC880 */
15772 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15773 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15774 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15775 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15778 * configuration and preset
15780 static const char *alc662_models[ALC662_MODEL_LAST] = {
15781 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15782 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15783 [ALC662_3ST_6ch] = "3stack-6ch",
15784 [ALC662_5ST_DIG] = "6stack-dig",
15785 [ALC662_LENOVO_101E] = "lenovo-101e",
15786 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15787 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15788 [ALC662_ECS] = "ecs",
15789 [ALC663_ASUS_M51VA] = "m51va",
15790 [ALC663_ASUS_G71V] = "g71v",
15791 [ALC663_ASUS_H13] = "h13",
15792 [ALC663_ASUS_G50V] = "g50v",
15793 [ALC663_ASUS_MODE1] = "asus-mode1",
15794 [ALC662_ASUS_MODE2] = "asus-mode2",
15795 [ALC663_ASUS_MODE3] = "asus-mode3",
15796 [ALC663_ASUS_MODE4] = "asus-mode4",
15797 [ALC663_ASUS_MODE5] = "asus-mode5",
15798 [ALC663_ASUS_MODE6] = "asus-mode6",
15799 [ALC662_AUTO] = "auto",
15802 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15803 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15804 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15805 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15806 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15807 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15808 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15809 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15810 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15811 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15812 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15813 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15814 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15815 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15816 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15817 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15818 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15819 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15820 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15821 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15822 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15823 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15824 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15825 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15826 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15827 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15828 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15829 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15830 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15831 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15832 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15833 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15834 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15835 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15836 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15837 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15838 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15839 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15840 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15841 ALC662_3ST_6ch_DIG),
15842 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15843 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15844 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15845 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15846 ALC662_3ST_6ch_DIG),
15847 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15848 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15849 ALC662_3ST_6ch_DIG),
15850 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15851 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15852 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15856 static struct alc_config_preset alc662_presets[] = {
15857 [ALC662_3ST_2ch_DIG] = {
15858 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15859 .init_verbs = { alc662_init_verbs },
15860 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15861 .dac_nids = alc662_dac_nids,
15862 .dig_out_nid = ALC662_DIGOUT_NID,
15863 .dig_in_nid = ALC662_DIGIN_NID,
15864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15865 .channel_mode = alc662_3ST_2ch_modes,
15866 .input_mux = &alc662_capture_source,
15868 [ALC662_3ST_6ch_DIG] = {
15869 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15870 alc662_capture_mixer },
15871 .init_verbs = { alc662_init_verbs },
15872 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15873 .dac_nids = alc662_dac_nids,
15874 .dig_out_nid = ALC662_DIGOUT_NID,
15875 .dig_in_nid = ALC662_DIGIN_NID,
15876 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15877 .channel_mode = alc662_3ST_6ch_modes,
15879 .input_mux = &alc662_capture_source,
15881 [ALC662_3ST_6ch] = {
15882 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15883 alc662_capture_mixer },
15884 .init_verbs = { alc662_init_verbs },
15885 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886 .dac_nids = alc662_dac_nids,
15887 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15888 .channel_mode = alc662_3ST_6ch_modes,
15890 .input_mux = &alc662_capture_source,
15892 [ALC662_5ST_DIG] = {
15893 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15894 alc662_capture_mixer },
15895 .init_verbs = { alc662_init_verbs },
15896 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15897 .dac_nids = alc662_dac_nids,
15898 .dig_out_nid = ALC662_DIGOUT_NID,
15899 .dig_in_nid = ALC662_DIGIN_NID,
15900 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15901 .channel_mode = alc662_5stack_modes,
15902 .input_mux = &alc662_capture_source,
15904 [ALC662_LENOVO_101E] = {
15905 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15906 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15907 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15908 .dac_nids = alc662_dac_nids,
15909 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15910 .channel_mode = alc662_3ST_2ch_modes,
15911 .input_mux = &alc662_lenovo_101e_capture_source,
15912 .unsol_event = alc662_lenovo_101e_unsol_event,
15913 .init_hook = alc662_lenovo_101e_all_automute,
15915 [ALC662_ASUS_EEEPC_P701] = {
15916 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15917 .init_verbs = { alc662_init_verbs,
15918 alc662_eeepc_sue_init_verbs },
15919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15920 .dac_nids = alc662_dac_nids,
15921 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15922 .channel_mode = alc662_3ST_2ch_modes,
15923 .input_mux = &alc662_eeepc_capture_source,
15924 .unsol_event = alc662_eeepc_unsol_event,
15925 .init_hook = alc662_eeepc_inithook,
15927 [ALC662_ASUS_EEEPC_EP20] = {
15928 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15929 alc662_chmode_mixer },
15930 .init_verbs = { alc662_init_verbs,
15931 alc662_eeepc_ep20_sue_init_verbs },
15932 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15933 .dac_nids = alc662_dac_nids,
15934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15935 .channel_mode = alc662_3ST_6ch_modes,
15936 .input_mux = &alc662_lenovo_101e_capture_source,
15937 .unsol_event = alc662_eeepc_ep20_unsol_event,
15938 .init_hook = alc662_eeepc_ep20_inithook,
15941 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15942 .init_verbs = { alc662_init_verbs,
15943 alc662_ecs_init_verbs },
15944 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15945 .dac_nids = alc662_dac_nids,
15946 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15947 .channel_mode = alc662_3ST_2ch_modes,
15948 .input_mux = &alc662_eeepc_capture_source,
15949 .unsol_event = alc662_eeepc_unsol_event,
15950 .init_hook = alc662_eeepc_inithook,
15952 [ALC663_ASUS_M51VA] = {
15953 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15954 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15955 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15956 .dac_nids = alc662_dac_nids,
15957 .dig_out_nid = ALC662_DIGOUT_NID,
15958 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15959 .channel_mode = alc662_3ST_2ch_modes,
15960 .input_mux = &alc663_m51va_capture_source,
15961 .unsol_event = alc663_m51va_unsol_event,
15962 .init_hook = alc663_m51va_inithook,
15964 [ALC663_ASUS_G71V] = {
15965 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15966 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15967 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15968 .dac_nids = alc662_dac_nids,
15969 .dig_out_nid = ALC662_DIGOUT_NID,
15970 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15971 .channel_mode = alc662_3ST_2ch_modes,
15972 .input_mux = &alc662_eeepc_capture_source,
15973 .unsol_event = alc663_g71v_unsol_event,
15974 .init_hook = alc663_g71v_inithook,
15976 [ALC663_ASUS_H13] = {
15977 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15978 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15979 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15980 .dac_nids = alc662_dac_nids,
15981 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15982 .channel_mode = alc662_3ST_2ch_modes,
15983 .input_mux = &alc663_m51va_capture_source,
15984 .unsol_event = alc663_m51va_unsol_event,
15985 .init_hook = alc663_m51va_inithook,
15987 [ALC663_ASUS_G50V] = {
15988 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15989 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15991 .dac_nids = alc662_dac_nids,
15992 .dig_out_nid = ALC662_DIGOUT_NID,
15993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15994 .channel_mode = alc662_3ST_6ch_modes,
15995 .input_mux = &alc663_capture_source,
15996 .unsol_event = alc663_g50v_unsol_event,
15997 .init_hook = alc663_g50v_inithook,
15999 [ALC663_ASUS_MODE1] = {
16000 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
16001 .init_verbs = { alc662_init_verbs,
16002 alc663_21jd_amic_init_verbs },
16003 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16005 .dac_nids = alc662_dac_nids,
16006 .dig_out_nid = ALC662_DIGOUT_NID,
16007 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16008 .channel_mode = alc662_3ST_2ch_modes,
16009 .input_mux = &alc662_eeepc_capture_source,
16010 .unsol_event = alc663_mode1_unsol_event,
16011 .init_hook = alc663_mode1_inithook,
16013 [ALC662_ASUS_MODE2] = {
16014 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
16015 .init_verbs = { alc662_init_verbs,
16016 alc662_1bjd_amic_init_verbs },
16017 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16018 .dac_nids = alc662_dac_nids,
16019 .dig_out_nid = ALC662_DIGOUT_NID,
16020 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16021 .channel_mode = alc662_3ST_2ch_modes,
16022 .input_mux = &alc662_eeepc_capture_source,
16023 .unsol_event = alc662_mode2_unsol_event,
16024 .init_hook = alc662_mode2_inithook,
16026 [ALC663_ASUS_MODE3] = {
16027 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
16028 .init_verbs = { alc662_init_verbs,
16029 alc663_two_hp_amic_m1_init_verbs },
16030 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16032 .dac_nids = alc662_dac_nids,
16033 .dig_out_nid = ALC662_DIGOUT_NID,
16034 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16035 .channel_mode = alc662_3ST_2ch_modes,
16036 .input_mux = &alc662_eeepc_capture_source,
16037 .unsol_event = alc663_mode3_unsol_event,
16038 .init_hook = alc663_mode3_inithook,
16040 [ALC663_ASUS_MODE4] = {
16041 .mixers = { alc663_asus_21jd_clfe_mixer,
16042 alc662_auto_capture_mixer},
16043 .init_verbs = { alc662_init_verbs,
16044 alc663_21jd_amic_init_verbs},
16045 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16047 .dac_nids = alc662_dac_nids,
16048 .dig_out_nid = ALC662_DIGOUT_NID,
16049 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16050 .channel_mode = alc662_3ST_2ch_modes,
16051 .input_mux = &alc662_eeepc_capture_source,
16052 .unsol_event = alc663_mode4_unsol_event,
16053 .init_hook = alc663_mode4_inithook,
16055 [ALC663_ASUS_MODE5] = {
16056 .mixers = { alc663_asus_15jd_clfe_mixer,
16057 alc662_auto_capture_mixer },
16058 .init_verbs = { alc662_init_verbs,
16059 alc663_15jd_amic_init_verbs },
16060 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16062 .dac_nids = alc662_dac_nids,
16063 .dig_out_nid = ALC662_DIGOUT_NID,
16064 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16065 .channel_mode = alc662_3ST_2ch_modes,
16066 .input_mux = &alc662_eeepc_capture_source,
16067 .unsol_event = alc663_mode5_unsol_event,
16068 .init_hook = alc663_mode5_inithook,
16070 [ALC663_ASUS_MODE6] = {
16071 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
16072 .init_verbs = { alc662_init_verbs,
16073 alc663_two_hp_amic_m2_init_verbs },
16074 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16076 .dac_nids = alc662_dac_nids,
16077 .dig_out_nid = ALC662_DIGOUT_NID,
16078 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16079 .channel_mode = alc662_3ST_2ch_modes,
16080 .input_mux = &alc662_eeepc_capture_source,
16081 .unsol_event = alc663_mode6_unsol_event,
16082 .init_hook = alc663_mode6_inithook,
16088 * BIOS auto configuration
16091 /* add playback controls from the parsed DAC table */
16092 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16093 const struct auto_pin_cfg *cfg)
16096 static const char *chname[4] = {
16097 "Front", "Surround", NULL /*CLFE*/, "Side"
16102 for (i = 0; i < cfg->line_outs; i++) {
16103 if (!spec->multiout.dac_nids[i])
16105 nid = alc880_idx_to_dac(i);
16108 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16109 "Center Playback Volume",
16110 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16114 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16115 "LFE Playback Volume",
16116 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16120 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16121 "Center Playback Switch",
16122 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16126 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16127 "LFE Playback Switch",
16128 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16133 sprintf(name, "%s Playback Volume", chname[i]);
16134 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16135 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16139 sprintf(name, "%s Playback Switch", chname[i]);
16140 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16141 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16150 /* add playback controls for speaker and HP outputs */
16151 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16162 /* ALC663 has a mono output pin on 0x17 */
16163 sprintf(name, "%s Playback Switch", pfx);
16164 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16165 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16169 if (alc880_is_fixed_pin(pin)) {
16170 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16171 /* printk("DAC nid=%x\n",nid); */
16172 /* specify the DAC as the extra output */
16173 if (!spec->multiout.hp_nid)
16174 spec->multiout.hp_nid = nid;
16176 spec->multiout.extra_out_nid[0] = nid;
16177 /* control HP volume/switch on the output mixer amp */
16178 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16179 sprintf(name, "%s Playback Volume", pfx);
16180 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16181 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16184 sprintf(name, "%s Playback Switch", pfx);
16185 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16186 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16189 } else if (alc880_is_multi_pin(pin)) {
16190 /* set manual connection */
16191 /* we have only a switch on HP-out PIN */
16192 sprintf(name, "%s Playback Switch", pfx);
16193 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16194 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16201 /* create playback/capture controls for input pins */
16202 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16203 const struct auto_pin_cfg *cfg)
16205 struct hda_input_mux *imux = &spec->private_imux;
16208 for (i = 0; i < AUTO_PIN_LAST; i++) {
16209 if (alc880_is_input_pin(cfg->input_pins[i])) {
16210 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16211 err = new_analog_input(spec, cfg->input_pins[i],
16212 auto_pin_cfg_labels[i],
16216 imux->items[imux->num_items].label =
16217 auto_pin_cfg_labels[i];
16218 imux->items[imux->num_items].index =
16219 alc880_input_pin_idx(cfg->input_pins[i]);
16226 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16227 hda_nid_t nid, int pin_type,
16230 alc_set_pin_output(codec, nid, pin_type);
16231 /* need the manual connection? */
16232 if (alc880_is_multi_pin(nid)) {
16233 struct alc_spec *spec = codec->spec;
16234 int idx = alc880_multi_pin_idx(nid);
16235 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16236 AC_VERB_SET_CONNECT_SEL,
16237 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16241 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16243 struct alc_spec *spec = codec->spec;
16246 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16247 for (i = 0; i <= HDA_SIDE; i++) {
16248 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16249 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16251 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16256 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16258 struct alc_spec *spec = codec->spec;
16261 pin = spec->autocfg.hp_pins[0];
16262 if (pin) /* connect to front */
16264 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16265 pin = spec->autocfg.speaker_pins[0];
16267 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16270 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16271 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16273 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16275 struct alc_spec *spec = codec->spec;
16278 for (i = 0; i < AUTO_PIN_LAST; i++) {
16279 hda_nid_t nid = spec->autocfg.input_pins[i];
16280 if (alc662_is_input_pin(nid)) {
16281 snd_hda_codec_write(codec, nid, 0,
16282 AC_VERB_SET_PIN_WIDGET_CONTROL,
16283 (i <= AUTO_PIN_FRONT_MIC ?
16284 PIN_VREF80 : PIN_IN));
16285 if (nid != ALC662_PIN_CD_NID)
16286 snd_hda_codec_write(codec, nid, 0,
16287 AC_VERB_SET_AMP_GAIN_MUTE,
16293 #define alc662_auto_init_input_src alc882_auto_init_input_src
16295 static int alc662_parse_auto_config(struct hda_codec *codec)
16297 struct alc_spec *spec = codec->spec;
16299 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16301 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16305 if (!spec->autocfg.line_outs)
16306 return 0; /* can't find valid BIOS pin config */
16308 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16311 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16314 err = alc662_auto_create_extra_out(spec,
16315 spec->autocfg.speaker_pins[0],
16319 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16323 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16327 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16329 if (spec->autocfg.dig_out_pin)
16330 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16332 if (spec->kctls.list)
16333 add_mixer(spec, spec->kctls.list);
16335 spec->num_mux_defs = 1;
16336 spec->input_mux = &spec->private_imux;
16338 add_verb(spec, alc662_auto_init_verbs);
16339 if (codec->vendor_id == 0x10ec0663)
16340 add_verb(spec, alc663_auto_init_verbs);
16342 err = alc_auto_add_mic_boost(codec);
16346 add_mixer(spec, alc662_capture_mixer);
16348 store_pin_configs(codec);
16352 /* additional initialization for auto-configuration model */
16353 static void alc662_auto_init(struct hda_codec *codec)
16355 struct alc_spec *spec = codec->spec;
16356 alc662_auto_init_multi_out(codec);
16357 alc662_auto_init_hp_out(codec);
16358 alc662_auto_init_analog_input(codec);
16359 alc662_auto_init_input_src(codec);
16360 if (spec->unsol_event)
16361 alc_inithook(codec);
16364 static int patch_alc662(struct hda_codec *codec)
16366 struct alc_spec *spec;
16367 int err, board_config;
16369 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16373 codec->spec = spec;
16375 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16377 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16380 if (board_config < 0) {
16381 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16382 "trying auto-probe from BIOS...\n");
16383 board_config = ALC662_AUTO;
16386 if (board_config == ALC662_AUTO) {
16387 /* automatic parse from the BIOS config */
16388 err = alc662_parse_auto_config(codec);
16394 "hda_codec: Cannot set up configuration "
16395 "from BIOS. Using base mode...\n");
16396 board_config = ALC662_3ST_2ch_DIG;
16400 if (board_config != ALC662_AUTO)
16401 setup_preset(spec, &alc662_presets[board_config]);
16403 if (codec->vendor_id == 0x10ec0663) {
16404 spec->stream_name_analog = "ALC663 Analog";
16405 spec->stream_name_digital = "ALC663 Digital";
16406 } else if (codec->vendor_id == 0x10ec0272) {
16407 spec->stream_name_analog = "ALC272 Analog";
16408 spec->stream_name_digital = "ALC272 Digital";
16410 spec->stream_name_analog = "ALC662 Analog";
16411 spec->stream_name_digital = "ALC662 Digital";
16414 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16415 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16417 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16418 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16420 spec->adc_nids = alc662_adc_nids;
16421 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16422 spec->capsrc_nids = alc662_capsrc_nids;
16424 spec->vmaster_nid = 0x02;
16426 codec->patch_ops = alc_patch_ops;
16427 if (board_config == ALC662_AUTO)
16428 spec->init_hook = alc662_auto_init;
16429 #ifdef CONFIG_SND_HDA_POWER_SAVE
16430 if (!spec->loopback.amplist)
16431 spec->loopback.amplist = alc662_loopbacks;
16440 struct hda_codec_preset snd_hda_preset_realtek[] = {
16441 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16442 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16443 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16444 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16445 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16446 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16447 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16448 .patch = patch_alc861 },
16449 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16450 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16451 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16452 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16453 .patch = patch_alc883 },
16454 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16455 .patch = patch_alc662 },
16456 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16457 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16458 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16459 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16460 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16461 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16462 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16463 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16464 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16465 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16466 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16467 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16468 .patch = patch_alc883 },
16469 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16470 {} /* terminator */