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 */
118 ALC268_ACER_ASPIRE_ONE,
121 #ifdef CONFIG_SND_DEBUG
125 ALC268_MODEL_LAST /* last tag */
132 ALC269_ASUS_EEEPC_P703,
133 ALC269_ASUS_EEEPC_P901,
137 ALC269_MODEL_LAST /* last tag */
154 /* ALC861-VD models */
176 ALC662_ASUS_EEEPC_P701,
177 ALC662_ASUS_EEEPC_EP20,
216 ALC883_TARGA_2ch_DIG,
219 ALC888_ACER_ASPIRE_4930G,
223 ALC883_LENOVO_101E_2ch,
224 ALC883_LENOVO_NB0763,
225 ALC888_LENOVO_MS7195_DIG,
232 ALC883_FUJITSU_PI2515,
233 ALC883_3ST_6ch_INTEL,
242 #define GPIO_MASK 0x03
245 /* codec parameterization */
246 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
247 unsigned int num_mixers;
248 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
250 const struct hda_verb *init_verbs[5]; /* initialization verbs
254 unsigned int num_init_verbs;
256 char *stream_name_analog; /* analog PCM stream */
257 struct hda_pcm_stream *stream_analog_playback;
258 struct hda_pcm_stream *stream_analog_capture;
259 struct hda_pcm_stream *stream_analog_alt_playback;
260 struct hda_pcm_stream *stream_analog_alt_capture;
262 char *stream_name_digital; /* digital PCM stream */
263 struct hda_pcm_stream *stream_digital_playback;
264 struct hda_pcm_stream *stream_digital_capture;
267 struct hda_multi_out multiout; /* playback set-up
268 * max_channels, dacs must be set
269 * dig_out_nid and hp_nid are optional
271 hda_nid_t alt_dac_nid;
274 unsigned int num_adc_nids;
276 hda_nid_t *capsrc_nids;
277 hda_nid_t dig_in_nid; /* digital-in NID; optional */
278 unsigned char is_mix_capture; /* matrix-style capture (non-mux) */
281 unsigned int num_mux_defs;
282 const struct hda_input_mux *input_mux;
283 unsigned int cur_mux[3];
286 const struct hda_channel_mode *channel_mode;
287 int num_channel_mode;
290 /* PCM information */
291 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
293 /* dynamic controls, init_verbs and input_mux */
294 struct auto_pin_cfg autocfg;
295 struct snd_array kctls;
296 struct hda_input_mux private_imux;
297 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
300 void (*init_hook)(struct hda_codec *codec);
301 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
303 /* for pin sensing */
304 unsigned int sense_updated: 1;
305 unsigned int jack_present: 1;
306 unsigned int master_sw: 1;
308 /* for virtual master */
309 hda_nid_t vmaster_nid;
310 #ifdef CONFIG_SND_HDA_POWER_SAVE
311 struct hda_loopback_check loopback;
316 unsigned int pll_coef_idx, pll_coef_bit;
318 #ifdef SND_HDA_NEEDS_RESUME
319 #define ALC_MAX_PINS 16
320 unsigned int num_pins;
321 hda_nid_t pin_nids[ALC_MAX_PINS];
322 unsigned int pin_cfgs[ALC_MAX_PINS];
327 * configuration template - to be copied to the spec instance
329 struct alc_config_preset {
330 struct snd_kcontrol_new *mixers[5]; /* should be identical size
333 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
334 const struct hda_verb *init_verbs[5];
335 unsigned int num_dacs;
337 hda_nid_t dig_out_nid; /* optional */
338 hda_nid_t hp_nid; /* optional */
339 unsigned int num_adc_nids;
341 hda_nid_t *capsrc_nids;
342 hda_nid_t dig_in_nid;
343 unsigned int num_channel_mode;
344 const struct hda_channel_mode *channel_mode;
346 unsigned int num_mux_defs;
347 const struct hda_input_mux *input_mux;
348 void (*unsol_event)(struct hda_codec *, unsigned int);
349 void (*init_hook)(struct hda_codec *);
350 #ifdef CONFIG_SND_HDA_POWER_SAVE
351 struct hda_amp_list *loopbacks;
359 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
360 struct snd_ctl_elem_info *uinfo)
362 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
363 struct alc_spec *spec = codec->spec;
364 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
365 if (mux_idx >= spec->num_mux_defs)
367 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
370 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
371 struct snd_ctl_elem_value *ucontrol)
373 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
374 struct alc_spec *spec = codec->spec;
375 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
377 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
381 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
384 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct alc_spec *spec = codec->spec;
386 const struct hda_input_mux *imux;
387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
388 unsigned int mux_idx;
389 hda_nid_t nid = spec->capsrc_nids ?
390 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
392 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
393 imux = &spec->input_mux[mux_idx];
395 if (spec->is_mix_capture) {
396 /* Matrix-mixer style (e.g. ALC882) */
397 unsigned int *cur_val = &spec->cur_mux[adc_idx];
400 idx = ucontrol->value.enumerated.item[0];
401 if (idx >= imux->num_items)
402 idx = imux->num_items - 1;
405 for (i = 0; i < imux->num_items; i++) {
406 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
407 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
408 imux->items[i].index,
414 /* MUX style (e.g. ALC880) */
415 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
416 &spec->cur_mux[adc_idx]);
421 * channel mode setting
423 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
424 struct snd_ctl_elem_info *uinfo)
426 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
427 struct alc_spec *spec = codec->spec;
428 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
429 spec->num_channel_mode);
432 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_value *ucontrol)
435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436 struct alc_spec *spec = codec->spec;
437 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
438 spec->num_channel_mode,
439 spec->multiout.max_channels);
442 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
443 struct snd_ctl_elem_value *ucontrol)
445 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
446 struct alc_spec *spec = codec->spec;
447 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
448 spec->num_channel_mode,
449 &spec->multiout.max_channels);
450 if (err >= 0 && spec->need_dac_fix)
451 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
456 * Control the mode of pin widget settings via the mixer. "pc" is used
457 * instead of "%" to avoid consequences of accidently treating the % as
458 * being part of a format specifier. Maximum allowed length of a value is
459 * 63 characters plus NULL terminator.
461 * Note: some retasking pin complexes seem to ignore requests for input
462 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
463 * are requested. Therefore order this list so that this behaviour will not
464 * cause problems when mixer clients move through the enum sequentially.
465 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
468 static char *alc_pin_mode_names[] = {
469 "Mic 50pc bias", "Mic 80pc bias",
470 "Line in", "Line out", "Headphone out",
472 static unsigned char alc_pin_mode_values[] = {
473 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
475 /* The control can present all 5 options, or it can limit the options based
476 * in the pin being assumed to be exclusively an input or an output pin. In
477 * addition, "input" pins may or may not process the mic bias option
478 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
479 * accept requests for bias as of chip versions up to March 2006) and/or
480 * wiring in the computer.
482 #define ALC_PIN_DIR_IN 0x00
483 #define ALC_PIN_DIR_OUT 0x01
484 #define ALC_PIN_DIR_INOUT 0x02
485 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
486 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
488 /* Info about the pin modes supported by the different pin direction modes.
489 * For each direction the minimum and maximum values are given.
491 static signed char alc_pin_mode_dir_info[5][2] = {
492 { 0, 2 }, /* ALC_PIN_DIR_IN */
493 { 3, 4 }, /* ALC_PIN_DIR_OUT */
494 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
495 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
496 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
498 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
499 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
500 #define alc_pin_mode_n_items(_dir) \
501 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
503 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
504 struct snd_ctl_elem_info *uinfo)
506 unsigned int item_num = uinfo->value.enumerated.item;
507 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
509 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
511 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
513 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
514 item_num = alc_pin_mode_min(dir);
515 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
519 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_value *ucontrol)
523 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
524 hda_nid_t nid = kcontrol->private_value & 0xffff;
525 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
526 long *valp = ucontrol->value.integer.value;
527 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
528 AC_VERB_GET_PIN_WIDGET_CONTROL,
531 /* Find enumerated value for current pinctl setting */
532 i = alc_pin_mode_min(dir);
533 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
535 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
539 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
540 struct snd_ctl_elem_value *ucontrol)
543 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
544 hda_nid_t nid = kcontrol->private_value & 0xffff;
545 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
546 long val = *ucontrol->value.integer.value;
547 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
548 AC_VERB_GET_PIN_WIDGET_CONTROL,
551 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
552 val = alc_pin_mode_min(dir);
554 change = pinctl != alc_pin_mode_values[val];
556 /* Set pin mode to that requested */
557 snd_hda_codec_write_cache(codec, nid, 0,
558 AC_VERB_SET_PIN_WIDGET_CONTROL,
559 alc_pin_mode_values[val]);
561 /* Also enable the retasking pin's input/output as required
562 * for the requested pin mode. Enum values of 2 or less are
565 * Dynamically switching the input/output buffers probably
566 * reduces noise slightly (particularly on input) so we'll
567 * do it. However, having both input and output buffers
568 * enabled simultaneously doesn't seem to be problematic if
569 * this turns out to be necessary in the future.
572 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
573 HDA_AMP_MUTE, HDA_AMP_MUTE);
574 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
577 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
578 HDA_AMP_MUTE, HDA_AMP_MUTE);
579 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
586 #define ALC_PIN_MODE(xname, nid, dir) \
587 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
588 .info = alc_pin_mode_info, \
589 .get = alc_pin_mode_get, \
590 .put = alc_pin_mode_put, \
591 .private_value = nid | (dir<<16) }
593 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
594 * together using a mask with more than one bit set. This control is
595 * currently used only by the ALC260 test model. At this stage they are not
596 * needed for any "production" models.
598 #ifdef CONFIG_SND_DEBUG
599 #define alc_gpio_data_info snd_ctl_boolean_mono_info
601 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
602 struct snd_ctl_elem_value *ucontrol)
604 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
605 hda_nid_t nid = kcontrol->private_value & 0xffff;
606 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
607 long *valp = ucontrol->value.integer.value;
608 unsigned int val = snd_hda_codec_read(codec, nid, 0,
609 AC_VERB_GET_GPIO_DATA, 0x00);
611 *valp = (val & mask) != 0;
614 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
618 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
619 hda_nid_t nid = kcontrol->private_value & 0xffff;
620 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
621 long val = *ucontrol->value.integer.value;
622 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
623 AC_VERB_GET_GPIO_DATA,
626 /* Set/unset the masked GPIO bit(s) as needed */
627 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
632 snd_hda_codec_write_cache(codec, nid, 0,
633 AC_VERB_SET_GPIO_DATA, gpio_data);
637 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
638 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
639 .info = alc_gpio_data_info, \
640 .get = alc_gpio_data_get, \
641 .put = alc_gpio_data_put, \
642 .private_value = nid | (mask<<16) }
643 #endif /* CONFIG_SND_DEBUG */
645 /* A switch control to allow the enabling of the digital IO pins on the
646 * ALC260. This is incredibly simplistic; the intention of this control is
647 * to provide something in the test model allowing digital outputs to be
648 * identified if present. If models are found which can utilise these
649 * outputs a more complete mixer control can be devised for those models if
652 #ifdef CONFIG_SND_DEBUG
653 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
655 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
656 struct snd_ctl_elem_value *ucontrol)
658 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
659 hda_nid_t nid = kcontrol->private_value & 0xffff;
660 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
661 long *valp = ucontrol->value.integer.value;
662 unsigned int val = snd_hda_codec_read(codec, nid, 0,
663 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
665 *valp = (val & mask) != 0;
668 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
673 hda_nid_t nid = kcontrol->private_value & 0xffff;
674 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
675 long val = *ucontrol->value.integer.value;
676 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
677 AC_VERB_GET_DIGI_CONVERT_1,
680 /* Set/unset the masked control bit(s) as needed */
681 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
686 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
691 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
692 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
693 .info = alc_spdif_ctrl_info, \
694 .get = alc_spdif_ctrl_get, \
695 .put = alc_spdif_ctrl_put, \
696 .private_value = nid | (mask<<16) }
697 #endif /* CONFIG_SND_DEBUG */
699 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
700 * Again, this is only used in the ALC26x test models to help identify when
701 * the EAPD line must be asserted for features to work.
703 #ifdef CONFIG_SND_DEBUG
704 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
706 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol)
709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
710 hda_nid_t nid = kcontrol->private_value & 0xffff;
711 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
712 long *valp = ucontrol->value.integer.value;
713 unsigned int val = snd_hda_codec_read(codec, nid, 0,
714 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
716 *valp = (val & mask) != 0;
720 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *ucontrol)
724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
725 hda_nid_t nid = kcontrol->private_value & 0xffff;
726 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
727 long val = *ucontrol->value.integer.value;
728 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
729 AC_VERB_GET_EAPD_BTLENABLE,
732 /* Set/unset the masked control bit(s) as needed */
733 change = (!val ? 0 : mask) != (ctrl_data & mask);
738 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
744 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
745 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
746 .info = alc_eapd_ctrl_info, \
747 .get = alc_eapd_ctrl_get, \
748 .put = alc_eapd_ctrl_put, \
749 .private_value = nid | (mask<<16) }
750 #endif /* CONFIG_SND_DEBUG */
754 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
756 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
758 spec->mixers[spec->num_mixers++] = mix;
761 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
763 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
765 spec->init_verbs[spec->num_init_verbs++] = verb;
769 * set up from the preset table
771 static void setup_preset(struct alc_spec *spec,
772 const struct alc_config_preset *preset)
776 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
777 add_mixer(spec, preset->mixers[i]);
778 spec->cap_mixer = preset->cap_mixer;
779 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
781 add_verb(spec, preset->init_verbs[i]);
783 spec->channel_mode = preset->channel_mode;
784 spec->num_channel_mode = preset->num_channel_mode;
785 spec->need_dac_fix = preset->need_dac_fix;
787 spec->multiout.max_channels = spec->channel_mode[0].channels;
789 spec->multiout.num_dacs = preset->num_dacs;
790 spec->multiout.dac_nids = preset->dac_nids;
791 spec->multiout.dig_out_nid = preset->dig_out_nid;
792 spec->multiout.hp_nid = preset->hp_nid;
794 spec->num_mux_defs = preset->num_mux_defs;
795 if (!spec->num_mux_defs)
796 spec->num_mux_defs = 1;
797 spec->input_mux = preset->input_mux;
799 spec->num_adc_nids = preset->num_adc_nids;
800 spec->adc_nids = preset->adc_nids;
801 spec->capsrc_nids = preset->capsrc_nids;
802 spec->dig_in_nid = preset->dig_in_nid;
804 spec->unsol_event = preset->unsol_event;
805 spec->init_hook = preset->init_hook;
806 #ifdef CONFIG_SND_HDA_POWER_SAVE
807 spec->loopback.amplist = preset->loopbacks;
811 /* Enable GPIO mask and set output */
812 static struct hda_verb alc_gpio1_init_verbs[] = {
813 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
814 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
815 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
819 static struct hda_verb alc_gpio2_init_verbs[] = {
820 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
821 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
822 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
826 static struct hda_verb alc_gpio3_init_verbs[] = {
827 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
828 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
829 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
834 * Fix hardware PLL issue
835 * On some codecs, the analog PLL gating control must be off while
836 * the default value is 1.
838 static void alc_fix_pll(struct hda_codec *codec)
840 struct alc_spec *spec = codec->spec;
845 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
847 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
848 AC_VERB_GET_PROC_COEF, 0);
849 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
851 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
852 val & ~(1 << spec->pll_coef_bit));
855 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
856 unsigned int coef_idx, unsigned int coef_bit)
858 struct alc_spec *spec = codec->spec;
860 spec->pll_coef_idx = coef_idx;
861 spec->pll_coef_bit = coef_bit;
865 static void alc_sku_automute(struct hda_codec *codec)
867 struct alc_spec *spec = codec->spec;
868 unsigned int present;
869 unsigned int hp_nid = spec->autocfg.hp_pins[0];
870 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
872 /* need to execute and sync at first */
873 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
874 present = snd_hda_codec_read(codec, hp_nid, 0,
875 AC_VERB_GET_PIN_SENSE, 0);
876 spec->jack_present = (present & 0x80000000) != 0;
877 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
878 spec->jack_present ? 0 : PIN_OUT);
881 #if 0 /* it's broken in some acses -- temporarily disabled */
882 static void alc_mic_automute(struct hda_codec *codec)
884 struct alc_spec *spec = codec->spec;
885 unsigned int present;
886 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
887 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
888 unsigned int mix_nid = spec->capsrc_nids[0];
889 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
891 capsrc_idx_mic = mic_nid - 0x18;
892 capsrc_idx_fmic = fmic_nid - 0x18;
893 present = snd_hda_codec_read(codec, mic_nid, 0,
894 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
895 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
896 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
897 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
898 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
899 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
900 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
903 #define alc_mic_automute(codec) /* NOP */
904 #endif /* disabled */
906 /* unsolicited event for HP jack sensing */
907 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
909 if (codec->vendor_id == 0x10ec0880)
913 if (res == ALC880_HP_EVENT)
914 alc_sku_automute(codec);
916 if (res == ALC880_MIC_EVENT)
917 alc_mic_automute(codec);
920 static void alc_inithook(struct hda_codec *codec)
922 alc_sku_automute(codec);
923 alc_mic_automute(codec);
926 /* additional initialization for ALC888 variants */
927 static void alc888_coef_init(struct hda_codec *codec)
931 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
932 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
933 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
934 if ((tmp & 0xf0) == 2)
936 snd_hda_codec_read(codec, 0x20, 0,
937 AC_VERB_SET_PROC_COEF, 0x830);
940 snd_hda_codec_read(codec, 0x20, 0,
941 AC_VERB_SET_PROC_COEF, 0x3030);
944 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
945 * 31 ~ 16 : Manufacture ID
947 * 7 ~ 0 : Assembly ID
948 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
950 static void alc_subsystem_id(struct hda_codec *codec,
951 unsigned int porta, unsigned int porte,
954 unsigned int ass, tmp, i;
956 struct alc_spec *spec = codec->spec;
958 ass = codec->subsystem_id & 0xffff;
959 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
963 * 31~30 : port conetcivity
966 * 19~16 : Check sum (15:1)
971 if (codec->vendor_id == 0x10ec0260)
973 ass = snd_hda_codec_read(codec, nid, 0,
974 AC_VERB_GET_CONFIG_DEFAULT, 0);
975 if (!(ass & 1) && !(ass & 0x100000))
977 if ((ass >> 30) != 1) /* no physical connection */
982 for (i = 1; i < 16; i++) {
986 if (((ass >> 16) & 0xf) != tmp)
992 * 2 : 0 --> Desktop, 1 --> Laptop
993 * 3~5 : External Amplifier control
996 tmp = (ass & 0x38) >> 3; /* external Amp control */
999 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1002 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1005 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1007 case 5: /* set EAPD output high */
1008 switch (codec->vendor_id) {
1010 snd_hda_codec_write(codec, 0x0f, 0,
1011 AC_VERB_SET_EAPD_BTLENABLE, 2);
1012 snd_hda_codec_write(codec, 0x10, 0,
1013 AC_VERB_SET_EAPD_BTLENABLE, 2);
1024 snd_hda_codec_write(codec, 0x14, 0,
1025 AC_VERB_SET_EAPD_BTLENABLE, 2);
1026 snd_hda_codec_write(codec, 0x15, 0,
1027 AC_VERB_SET_EAPD_BTLENABLE, 2);
1030 switch (codec->vendor_id) {
1032 snd_hda_codec_write(codec, 0x1a, 0,
1033 AC_VERB_SET_COEF_INDEX, 7);
1034 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1035 AC_VERB_GET_PROC_COEF, 0);
1036 snd_hda_codec_write(codec, 0x1a, 0,
1037 AC_VERB_SET_COEF_INDEX, 7);
1038 snd_hda_codec_write(codec, 0x1a, 0,
1039 AC_VERB_SET_PROC_COEF,
1048 snd_hda_codec_write(codec, 0x20, 0,
1049 AC_VERB_SET_COEF_INDEX, 7);
1050 tmp = snd_hda_codec_read(codec, 0x20, 0,
1051 AC_VERB_GET_PROC_COEF, 0);
1052 snd_hda_codec_write(codec, 0x20, 0,
1053 AC_VERB_SET_COEF_INDEX, 7);
1054 snd_hda_codec_write(codec, 0x20, 0,
1055 AC_VERB_SET_PROC_COEF,
1059 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1063 snd_hda_codec_write(codec, 0x20, 0,
1064 AC_VERB_SET_COEF_INDEX, 7);
1065 tmp = snd_hda_codec_read(codec, 0x20, 0,
1066 AC_VERB_GET_PROC_COEF, 0);
1067 snd_hda_codec_write(codec, 0x20, 0,
1068 AC_VERB_SET_COEF_INDEX, 7);
1069 snd_hda_codec_write(codec, 0x20, 0,
1070 AC_VERB_SET_PROC_COEF,
1078 /* is laptop or Desktop and enable the function "Mute internal speaker
1079 * when the external headphone out jack is plugged"
1081 if (!(ass & 0x8000))
1084 * 10~8 : Jack location
1085 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1087 * 15 : 1 --> enable the function "Mute internal speaker
1088 * when the external headphone out jack is plugged"
1090 if (!spec->autocfg.speaker_pins[0]) {
1091 if (spec->autocfg.line_out_pins[0])
1092 spec->autocfg.speaker_pins[0] =
1093 spec->autocfg.line_out_pins[0];
1098 if (!spec->autocfg.hp_pins[0]) {
1099 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1101 spec->autocfg.hp_pins[0] = porta;
1103 spec->autocfg.hp_pins[0] = porte;
1105 spec->autocfg.hp_pins[0] = portd;
1109 if (spec->autocfg.hp_pins[0])
1110 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1111 AC_VERB_SET_UNSOLICITED_ENABLE,
1112 AC_USRSP_EN | ALC880_HP_EVENT);
1114 #if 0 /* it's broken in some acses -- temporarily disabled */
1115 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1116 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1117 snd_hda_codec_write(codec,
1118 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1119 AC_VERB_SET_UNSOLICITED_ENABLE,
1120 AC_USRSP_EN | ALC880_MIC_EVENT);
1121 #endif /* disabled */
1123 spec->unsol_event = alc_sku_unsol_event;
1127 * Fix-up pin default configurations
1135 static void alc_fix_pincfg(struct hda_codec *codec,
1136 const struct snd_pci_quirk *quirk,
1137 const struct alc_pincfg **pinfix)
1139 const struct alc_pincfg *cfg;
1141 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1145 cfg = pinfix[quirk->value];
1146 for (; cfg->nid; cfg++) {
1149 for (i = 0; i < 4; i++) {
1150 snd_hda_codec_write(codec, cfg->nid, 0,
1151 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1159 * ALC888 Acer Aspire 4930G model
1162 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1163 /* Front Mic: set to PIN_IN (empty by default) */
1164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1165 /* Unselect Front Mic by default in input mixer 3 */
1166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1167 /* enable unsolicited event fpr HP jack */
1168 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1169 /* Connect Internal HP to front */
1170 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1171 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1172 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1173 /* Connect HP out to front */
1174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1176 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1180 static struct hda_input_mux alc888_acer_aspire_4930g_capture_source[2] = {
1181 /* Front mic only available on one ADC */
1188 { "Front Mic", 0xb },
1201 static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
1202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1205 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1206 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1211 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1212 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1218 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1220 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1221 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1225 static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1227 unsigned int present;
1228 present = snd_hda_codec_read(codec, 0x15, 0,
1229 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1230 /* Toggle the internal HP PIN (regular muting doesn't work) */
1231 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1232 (present ? 0x0 : PIN_OUT));
1235 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1238 if (res >> 26 == ALC880_HP_EVENT)
1239 alc888_acer_aspire_4930g_automute(codec);
1243 * ALC880 3-stack model
1245 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1246 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1247 * F-Mic = 0x1b, HP = 0x19
1250 static hda_nid_t alc880_dac_nids[4] = {
1251 /* front, rear, clfe, rear_surr */
1252 0x02, 0x05, 0x04, 0x03
1255 static hda_nid_t alc880_adc_nids[3] = {
1260 /* The datasheet says the node 0x07 is connected from inputs,
1261 * but it shows zero connection in the real implementation on some devices.
1262 * Note: this is a 915GAV bug, fixed on 915GLV
1264 static hda_nid_t alc880_adc_nids_alt[2] = {
1269 #define ALC880_DIGOUT_NID 0x06
1270 #define ALC880_DIGIN_NID 0x0a
1272 static struct hda_input_mux alc880_capture_source = {
1276 { "Front Mic", 0x3 },
1282 /* channel source setting (2/6 channel selection for 3-stack) */
1284 static struct hda_verb alc880_threestack_ch2_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 },
1288 /* set mic-in to input vref 80%, mute it */
1289 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1290 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1295 static struct hda_verb alc880_threestack_ch6_init[] = {
1296 /* set line-in to output, unmute it */
1297 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1298 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1299 /* set mic-in to output, unmute it */
1300 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1301 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1305 static struct hda_channel_mode alc880_threestack_modes[2] = {
1306 { 2, alc880_threestack_ch2_init },
1307 { 6, alc880_threestack_ch6_init },
1310 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1311 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1312 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1313 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1314 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1315 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1316 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1317 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1318 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1319 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1320 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1321 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1322 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1325 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1326 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1327 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1328 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1331 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1332 .name = "Channel Mode",
1333 .info = alc_ch_mode_info,
1334 .get = alc_ch_mode_get,
1335 .put = alc_ch_mode_put,
1340 /* capture mixer elements */
1341 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1342 struct snd_ctl_elem_info *uinfo)
1344 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1345 struct alc_spec *spec = codec->spec;
1348 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1349 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1351 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1352 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1356 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1357 unsigned int size, unsigned int __user *tlv)
1359 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1360 struct alc_spec *spec = codec->spec;
1363 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1364 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1366 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1367 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1371 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1372 struct snd_ctl_elem_value *ucontrol);
1374 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1375 struct snd_ctl_elem_value *ucontrol,
1378 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1379 struct alc_spec *spec = codec->spec;
1380 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1383 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1384 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1386 err = func(kcontrol, ucontrol);
1387 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1391 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1392 struct snd_ctl_elem_value *ucontrol)
1394 return alc_cap_getput_caller(kcontrol, ucontrol,
1395 snd_hda_mixer_amp_volume_get);
1398 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1399 struct snd_ctl_elem_value *ucontrol)
1401 return alc_cap_getput_caller(kcontrol, ucontrol,
1402 snd_hda_mixer_amp_volume_put);
1405 /* capture mixer elements */
1406 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1408 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1409 struct snd_ctl_elem_value *ucontrol)
1411 return alc_cap_getput_caller(kcontrol, ucontrol,
1412 snd_hda_mixer_amp_switch_get);
1415 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1416 struct snd_ctl_elem_value *ucontrol)
1418 return alc_cap_getput_caller(kcontrol, ucontrol,
1419 snd_hda_mixer_amp_switch_put);
1422 #define DEFINE_CAPMIX(num) \
1423 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1426 .name = "Capture Switch", \
1427 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1429 .info = alc_cap_sw_info, \
1430 .get = alc_cap_sw_get, \
1431 .put = alc_cap_sw_put, \
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1435 .name = "Capture Volume", \
1436 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1437 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1438 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1440 .info = alc_cap_vol_info, \
1441 .get = alc_cap_vol_get, \
1442 .put = alc_cap_vol_put, \
1443 .tlv = { .c = alc_cap_vol_tlv }, \
1446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1447 /* .name = "Capture Source", */ \
1448 .name = "Input Source", \
1450 .info = alc_mux_enum_info, \
1451 .get = alc_mux_enum_get, \
1452 .put = alc_mux_enum_put, \
1457 /* up to three ADCs */
1464 * ALC880 5-stack model
1466 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1468 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1469 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1472 /* additional mixers to alc880_three_stack_mixer */
1473 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1474 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1475 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1479 /* channel source setting (6/8 channel selection for 5-stack) */
1481 static struct hda_verb alc880_fivestack_ch6_init[] = {
1482 /* set line-in to input, mute it */
1483 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1484 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1489 static struct hda_verb alc880_fivestack_ch8_init[] = {
1490 /* set line-in to output, unmute it */
1491 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1492 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1496 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1497 { 6, alc880_fivestack_ch6_init },
1498 { 8, alc880_fivestack_ch8_init },
1503 * ALC880 6-stack model
1505 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1506 * Side = 0x05 (0x0f)
1507 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1508 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1511 static hda_nid_t alc880_6st_dac_nids[4] = {
1512 /* front, rear, clfe, rear_surr */
1513 0x02, 0x03, 0x04, 0x05
1516 static struct hda_input_mux alc880_6stack_capture_source = {
1520 { "Front Mic", 0x1 },
1526 /* fixed 8-channels */
1527 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1531 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1532 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1533 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1534 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1535 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1536 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1537 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1538 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1539 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1540 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1541 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1542 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1543 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1544 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1545 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1548 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1549 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1550 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1551 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1554 .name = "Channel Mode",
1555 .info = alc_ch_mode_info,
1556 .get = alc_ch_mode_get,
1557 .put = alc_ch_mode_put,
1566 * W810 has rear IO for:
1569 * Center/LFE (DAC 04)
1572 * The system also has a pair of internal speakers, and a headphone jack.
1573 * These are both connected to Line2 on the codec, hence to DAC 02.
1575 * There is a variable resistor to control the speaker or headphone
1576 * volume. This is a hardware-only device without a software API.
1578 * Plugging headphones in will disable the internal speakers. This is
1579 * implemented in hardware, not via the driver using jack sense. In
1580 * a similar fashion, plugging into the rear socket marked "front" will
1581 * disable both the speakers and headphones.
1583 * For input, there's a microphone jack, and an "audio in" jack.
1584 * These may not do anything useful with this driver yet, because I
1585 * haven't setup any initialization verbs for these yet...
1588 static hda_nid_t alc880_w810_dac_nids[3] = {
1589 /* front, rear/surround, clfe */
1593 /* fixed 6 channels */
1594 static struct hda_channel_mode alc880_w810_modes[1] = {
1598 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1599 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1600 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1601 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1602 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1603 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1604 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1605 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1606 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1607 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1608 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1616 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1617 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1621 static hda_nid_t alc880_z71v_dac_nids[1] = {
1624 #define ALC880_Z71V_HP_DAC 0x03
1626 /* fixed 2 channels */
1627 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1631 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1632 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1633 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1634 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1635 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1636 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1637 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1645 * ALC880 F1734 model
1647 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1648 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1651 static hda_nid_t alc880_f1734_dac_nids[1] = {
1654 #define ALC880_F1734_HP_DAC 0x02
1656 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1657 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1658 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1659 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1660 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1661 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1662 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1668 static struct hda_input_mux alc880_f1734_capture_source = {
1680 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1681 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1682 * Mic = 0x18, Line = 0x1a
1685 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1686 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1688 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1690 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1691 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1692 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1693 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1694 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1695 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1696 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1697 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1698 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1699 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1700 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1705 .name = "Channel Mode",
1706 .info = alc_ch_mode_info,
1707 .get = alc_ch_mode_get,
1708 .put = alc_ch_mode_put,
1714 * ALC880 ASUS W1V model
1716 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1717 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1718 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1721 /* additional mixers to alc880_asus_mixer */
1722 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1723 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1724 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1728 /* additional mixers to alc880_asus_mixer */
1729 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1730 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1731 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1736 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1737 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1738 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1740 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1741 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1742 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1743 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1744 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1745 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1750 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1751 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1752 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1753 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1754 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1755 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1756 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1757 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1758 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1759 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1760 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1761 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1762 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1765 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1766 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1767 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1768 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1771 .name = "Channel Mode",
1772 .info = alc_ch_mode_info,
1773 .get = alc_ch_mode_get,
1774 .put = alc_ch_mode_put,
1779 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1780 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1781 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1782 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1783 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1784 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1785 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1786 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1787 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1788 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1789 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1793 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1794 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1795 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1796 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1797 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1799 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1804 * virtual master controls
1808 * slave controls for virtual master
1810 static const char *alc_slave_vols[] = {
1811 "Front Playback Volume",
1812 "Surround Playback Volume",
1813 "Center Playback Volume",
1814 "LFE Playback Volume",
1815 "Side Playback Volume",
1816 "Headphone Playback Volume",
1817 "Speaker Playback Volume",
1818 "Mono Playback Volume",
1819 "Line-Out Playback Volume",
1820 "PCM Playback Volume",
1824 static const char *alc_slave_sws[] = {
1825 "Front Playback Switch",
1826 "Surround Playback Switch",
1827 "Center Playback Switch",
1828 "LFE Playback Switch",
1829 "Side Playback Switch",
1830 "Headphone Playback Switch",
1831 "Speaker Playback Switch",
1832 "Mono Playback Switch",
1833 "IEC958 Playback Switch",
1838 * build control elements
1841 static void alc_free_kctls(struct hda_codec *codec);
1843 static int alc_build_controls(struct hda_codec *codec)
1845 struct alc_spec *spec = codec->spec;
1849 for (i = 0; i < spec->num_mixers; i++) {
1850 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1854 if (spec->cap_mixer) {
1855 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
1859 if (spec->multiout.dig_out_nid) {
1860 err = snd_hda_create_spdif_out_ctls(codec,
1861 spec->multiout.dig_out_nid);
1864 err = snd_hda_create_spdif_share_sw(codec,
1868 spec->multiout.share_spdif = 1;
1870 if (spec->dig_in_nid) {
1871 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1876 /* if we have no master control, let's create it */
1877 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1878 unsigned int vmaster_tlv[4];
1879 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1880 HDA_OUTPUT, vmaster_tlv);
1881 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1882 vmaster_tlv, alc_slave_vols);
1886 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1887 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1888 NULL, alc_slave_sws);
1893 alc_free_kctls(codec); /* no longer needed */
1899 * initialize the codec volumes, etc
1903 * generic initialization of ADC, input mixers and output mixers
1905 static struct hda_verb alc880_volume_init_verbs[] = {
1907 * Unmute ADC0-2 and set the default input to mic-in
1909 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1911 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1913 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1914 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1916 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1918 * Note: PASD motherboards uses the Line In 2 as the input for front
1921 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1931 * Set up output mixers (0x0c - 0x0f)
1933 /* set vol=0 to output mixers */
1934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1935 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1938 /* set up input amps for analog loopback */
1939 /* Amp Indices: DAC = 0, mixer = 1 */
1940 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1942 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1944 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1946 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1947 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1953 * 3-stack pin configuration:
1954 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1956 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1958 * preset connection lists of input pins
1959 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1961 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1962 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1963 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1966 * Set pin mode and muting
1968 /* set front pin widgets 0x14 for output */
1969 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1971 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1974 /* Mic2 (as headphone out) for HP output */
1975 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1976 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1977 /* Line In pin widget for input */
1978 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1979 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1980 /* Line2 (as front mic) pin widget for input and vref at 80% */
1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1983 /* CD pin widget for input */
1984 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1990 * 5-stack pin configuration:
1991 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1992 * line-in/side = 0x1a, f-mic = 0x1b
1994 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1996 * preset connection lists of input pins
1997 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1999 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2000 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2003 * Set pin mode and muting
2005 /* set pin widgets 0x14-0x17 for output */
2006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2008 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2009 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2010 /* unmute pins for output (no gain on this amp) */
2011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2012 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2013 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2014 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2016 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2017 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2018 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2019 /* Mic2 (as headphone out) for HP output */
2020 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2021 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022 /* Line In pin widget for input */
2023 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2024 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2025 /* Line2 (as front mic) pin widget for input and vref at 80% */
2026 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2027 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2028 /* CD pin widget for input */
2029 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2035 * W810 pin configuration:
2036 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2038 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2039 /* hphone/speaker input selector: front DAC */
2040 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2042 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2043 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2046 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2047 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2049 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2050 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2056 * Z71V pin configuration:
2057 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2059 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2060 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2061 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2065 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2067 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2068 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2074 * 6-stack pin configuration:
2075 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2076 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2078 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2079 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2081 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2082 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2085 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2086 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2087 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2088 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2092 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2093 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2097 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2098 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2104 * Uniwill pin configuration:
2105 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2108 static struct hda_verb alc880_uniwill_init_verbs[] = {
2109 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2111 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2112 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2113 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2114 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2115 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2116 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2117 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2118 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2123 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2124 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2127 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2129 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2131 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2132 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2133 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2134 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2136 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2137 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2144 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2146 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2147 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2149 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2150 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2151 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2152 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2153 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2154 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2157 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2159 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2162 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2164 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2165 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2166 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2167 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2169 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2170 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2175 static struct hda_verb alc880_beep_init_verbs[] = {
2176 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2180 /* toggle speaker-output according to the hp-jack state */
2181 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2183 unsigned int present;
2186 present = snd_hda_codec_read(codec, 0x14, 0,
2187 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2188 bits = present ? HDA_AMP_MUTE : 0;
2189 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2190 HDA_AMP_MUTE, bits);
2191 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2192 HDA_AMP_MUTE, bits);
2195 /* auto-toggle front mic */
2196 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2198 unsigned int present;
2201 present = snd_hda_codec_read(codec, 0x18, 0,
2202 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2203 bits = present ? HDA_AMP_MUTE : 0;
2204 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2207 static void alc880_uniwill_automute(struct hda_codec *codec)
2209 alc880_uniwill_hp_automute(codec);
2210 alc880_uniwill_mic_automute(codec);
2213 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2216 /* Looks like the unsol event is incompatible with the standard
2217 * definition. 4bit tag is placed at 28 bit!
2219 switch (res >> 28) {
2220 case ALC880_HP_EVENT:
2221 alc880_uniwill_hp_automute(codec);
2223 case ALC880_MIC_EVENT:
2224 alc880_uniwill_mic_automute(codec);
2229 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2231 unsigned int present;
2234 present = snd_hda_codec_read(codec, 0x14, 0,
2235 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2236 bits = present ? HDA_AMP_MUTE : 0;
2237 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2240 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2242 unsigned int present;
2244 present = snd_hda_codec_read(codec, 0x21, 0,
2245 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2246 present &= HDA_AMP_VOLMASK;
2247 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2248 HDA_AMP_VOLMASK, present);
2249 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2250 HDA_AMP_VOLMASK, present);
2253 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2256 /* Looks like the unsol event is incompatible with the standard
2257 * definition. 4bit tag is placed at 28 bit!
2259 if ((res >> 28) == ALC880_HP_EVENT)
2260 alc880_uniwill_p53_hp_automute(codec);
2261 if ((res >> 28) == ALC880_DCVOL_EVENT)
2262 alc880_uniwill_p53_dcvol_automute(codec);
2266 * F1734 pin configuration:
2267 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2269 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2270 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2271 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2272 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2273 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2274 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2276 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2277 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2279 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2281 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2283 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2284 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2287 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2288 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2291 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2292 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2298 * ASUS pin configuration:
2299 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2301 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2302 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2303 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2304 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2305 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2307 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2308 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2309 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2310 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2311 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2312 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2313 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2314 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2316 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2317 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2319 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2321 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2322 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2323 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2324 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2329 /* Enable GPIO mask and set output */
2330 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2331 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2333 /* Clevo m520g init */
2334 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2335 /* headphone output */
2336 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2345 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2346 /* Mic1 (rear panel) */
2347 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2348 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2349 /* Mic2 (front panel) */
2350 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2351 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2353 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2354 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2355 /* change to EAPD mode */
2356 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2357 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2362 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2363 /* change to EAPD mode */
2364 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2365 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2367 /* Headphone output */
2368 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2370 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2371 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2373 /* Line In pin widget for input */
2374 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2375 /* CD pin widget for input */
2376 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2377 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2378 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2380 /* change to EAPD mode */
2381 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2382 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2388 * LG m1 express dual
2391 * Rear Line-In/Out (blue): 0x14
2392 * Build-in Mic-In: 0x15
2394 * HP-Out (green): 0x1b
2395 * Mic-In/Out (red): 0x19
2399 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2400 static hda_nid_t alc880_lg_dac_nids[3] = {
2404 /* seems analog CD is not working */
2405 static struct hda_input_mux alc880_lg_capture_source = {
2410 { "Internal Mic", 0x6 },
2414 /* 2,4,6 channel modes */
2415 static struct hda_verb alc880_lg_ch2_init[] = {
2416 /* set line-in and mic-in to input */
2417 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2418 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2422 static struct hda_verb alc880_lg_ch4_init[] = {
2423 /* set line-in to out and mic-in to input */
2424 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2425 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2429 static struct hda_verb alc880_lg_ch6_init[] = {
2430 /* set line-in and mic-in to output */
2431 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2432 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2436 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2437 { 2, alc880_lg_ch2_init },
2438 { 4, alc880_lg_ch4_init },
2439 { 6, alc880_lg_ch6_init },
2442 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2443 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2444 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2445 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2446 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2447 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2448 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2449 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2450 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2453 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2454 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2455 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2456 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2459 .name = "Channel Mode",
2460 .info = alc_ch_mode_info,
2461 .get = alc_ch_mode_get,
2462 .put = alc_ch_mode_put,
2467 static struct hda_verb alc880_lg_init_verbs[] = {
2468 /* set capture source to mic-in */
2469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2470 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2471 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2472 /* mute all amp mixer inputs */
2473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2476 /* line-in to input */
2477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2483 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2484 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2485 /* mic-in to input */
2486 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2487 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2488 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2491 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2492 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2498 /* toggle speaker-output according to the hp-jack state */
2499 static void alc880_lg_automute(struct hda_codec *codec)
2501 unsigned int present;
2504 present = snd_hda_codec_read(codec, 0x1b, 0,
2505 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2506 bits = present ? HDA_AMP_MUTE : 0;
2507 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2508 HDA_AMP_MUTE, bits);
2511 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2513 /* Looks like the unsol event is incompatible with the standard
2514 * definition. 4bit tag is placed at 28 bit!
2516 if ((res >> 28) == 0x01)
2517 alc880_lg_automute(codec);
2526 * Built-in Mic-In: 0x19
2532 static struct hda_input_mux alc880_lg_lw_capture_source = {
2536 { "Internal Mic", 0x1 },
2541 #define alc880_lg_lw_modes alc880_threestack_modes
2543 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2544 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2545 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2546 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2547 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2548 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2549 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2550 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2551 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2557 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2560 .name = "Channel Mode",
2561 .info = alc_ch_mode_info,
2562 .get = alc_ch_mode_get,
2563 .put = alc_ch_mode_put,
2568 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2569 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2570 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2571 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2573 /* set capture source to mic-in */
2574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2575 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2576 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2579 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2580 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2584 /* mic-in to input */
2585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2586 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2588 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2589 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2591 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2595 /* toggle speaker-output according to the hp-jack state */
2596 static void alc880_lg_lw_automute(struct hda_codec *codec)
2598 unsigned int present;
2601 present = snd_hda_codec_read(codec, 0x1b, 0,
2602 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2603 bits = present ? HDA_AMP_MUTE : 0;
2604 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2605 HDA_AMP_MUTE, bits);
2608 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2610 /* Looks like the unsol event is incompatible with the standard
2611 * definition. 4bit tag is placed at 28 bit!
2613 if ((res >> 28) == 0x01)
2614 alc880_lg_lw_automute(codec);
2617 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2618 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2619 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2621 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2622 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2623 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2627 static struct hda_input_mux alc880_medion_rim_capture_source = {
2631 { "Internal Mic", 0x1 },
2635 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2636 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2641 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2642 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2644 /* Mic2 (as headphone out) for HP output */
2645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2646 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2647 /* Internal Speaker */
2648 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2649 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2651 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2652 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2654 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2658 /* toggle speaker-output according to the hp-jack state */
2659 static void alc880_medion_rim_automute(struct hda_codec *codec)
2661 unsigned int present;
2664 present = snd_hda_codec_read(codec, 0x14, 0,
2665 AC_VERB_GET_PIN_SENSE, 0)
2666 & AC_PINSENSE_PRESENCE;
2667 bits = present ? HDA_AMP_MUTE : 0;
2668 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2669 HDA_AMP_MUTE, bits);
2671 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2673 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2676 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2679 /* Looks like the unsol event is incompatible with the standard
2680 * definition. 4bit tag is placed at 28 bit!
2682 if ((res >> 28) == ALC880_HP_EVENT)
2683 alc880_medion_rim_automute(codec);
2686 #ifdef CONFIG_SND_HDA_POWER_SAVE
2687 static struct hda_amp_list alc880_loopbacks[] = {
2688 { 0x0b, HDA_INPUT, 0 },
2689 { 0x0b, HDA_INPUT, 1 },
2690 { 0x0b, HDA_INPUT, 2 },
2691 { 0x0b, HDA_INPUT, 3 },
2692 { 0x0b, HDA_INPUT, 4 },
2696 static struct hda_amp_list alc880_lg_loopbacks[] = {
2697 { 0x0b, HDA_INPUT, 1 },
2698 { 0x0b, HDA_INPUT, 6 },
2699 { 0x0b, HDA_INPUT, 7 },
2708 static int alc_init(struct hda_codec *codec)
2710 struct alc_spec *spec = codec->spec;
2714 if (codec->vendor_id == 0x10ec0888)
2715 alc888_coef_init(codec);
2717 for (i = 0; i < spec->num_init_verbs; i++)
2718 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2720 if (spec->init_hook)
2721 spec->init_hook(codec);
2726 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2728 struct alc_spec *spec = codec->spec;
2730 if (spec->unsol_event)
2731 spec->unsol_event(codec, res);
2734 #ifdef CONFIG_SND_HDA_POWER_SAVE
2735 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2737 struct alc_spec *spec = codec->spec;
2738 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2743 * Analog playback callbacks
2745 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2746 struct hda_codec *codec,
2747 struct snd_pcm_substream *substream)
2749 struct alc_spec *spec = codec->spec;
2750 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2754 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2755 struct hda_codec *codec,
2756 unsigned int stream_tag,
2757 unsigned int format,
2758 struct snd_pcm_substream *substream)
2760 struct alc_spec *spec = codec->spec;
2761 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2762 stream_tag, format, substream);
2765 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2766 struct hda_codec *codec,
2767 struct snd_pcm_substream *substream)
2769 struct alc_spec *spec = codec->spec;
2770 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2776 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2777 struct hda_codec *codec,
2778 struct snd_pcm_substream *substream)
2780 struct alc_spec *spec = codec->spec;
2781 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2784 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2785 struct hda_codec *codec,
2786 unsigned int stream_tag,
2787 unsigned int format,
2788 struct snd_pcm_substream *substream)
2790 struct alc_spec *spec = codec->spec;
2791 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2792 stream_tag, format, substream);
2795 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2796 struct hda_codec *codec,
2797 struct snd_pcm_substream *substream)
2799 struct alc_spec *spec = codec->spec;
2800 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2806 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2807 struct hda_codec *codec,
2808 unsigned int stream_tag,
2809 unsigned int format,
2810 struct snd_pcm_substream *substream)
2812 struct alc_spec *spec = codec->spec;
2814 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2815 stream_tag, 0, format);
2819 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2820 struct hda_codec *codec,
2821 struct snd_pcm_substream *substream)
2823 struct alc_spec *spec = codec->spec;
2825 snd_hda_codec_cleanup_stream(codec,
2826 spec->adc_nids[substream->number + 1]);
2833 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2837 /* NID is set in alc_build_pcms */
2839 .open = alc880_playback_pcm_open,
2840 .prepare = alc880_playback_pcm_prepare,
2841 .cleanup = alc880_playback_pcm_cleanup
2845 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2849 /* NID is set in alc_build_pcms */
2852 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2856 /* NID is set in alc_build_pcms */
2859 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2860 .substreams = 2, /* can be overridden */
2863 /* NID is set in alc_build_pcms */
2865 .prepare = alc880_alt_capture_pcm_prepare,
2866 .cleanup = alc880_alt_capture_pcm_cleanup
2870 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2874 /* NID is set in alc_build_pcms */
2876 .open = alc880_dig_playback_pcm_open,
2877 .close = alc880_dig_playback_pcm_close,
2878 .prepare = alc880_dig_playback_pcm_prepare
2882 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2886 /* NID is set in alc_build_pcms */
2889 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2890 static struct hda_pcm_stream alc_pcm_null_stream = {
2896 static int alc_build_pcms(struct hda_codec *codec)
2898 struct alc_spec *spec = codec->spec;
2899 struct hda_pcm *info = spec->pcm_rec;
2902 codec->num_pcms = 1;
2903 codec->pcm_info = info;
2905 info->name = spec->stream_name_analog;
2906 if (spec->stream_analog_playback) {
2907 if (snd_BUG_ON(!spec->multiout.dac_nids))
2909 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2910 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2912 if (spec->stream_analog_capture) {
2913 if (snd_BUG_ON(!spec->adc_nids))
2915 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2916 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2919 if (spec->channel_mode) {
2920 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2921 for (i = 0; i < spec->num_channel_mode; i++) {
2922 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2923 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2928 /* SPDIF for stream index #1 */
2929 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2930 codec->num_pcms = 2;
2931 info = spec->pcm_rec + 1;
2932 info->name = spec->stream_name_digital;
2933 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2934 if (spec->multiout.dig_out_nid &&
2935 spec->stream_digital_playback) {
2936 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2937 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2939 if (spec->dig_in_nid &&
2940 spec->stream_digital_capture) {
2941 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2942 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2944 /* FIXME: do we need this for all Realtek codec models? */
2945 codec->spdif_status_reset = 1;
2948 /* If the use of more than one ADC is requested for the current
2949 * model, configure a second analog capture-only PCM.
2951 /* Additional Analaog capture for index #2 */
2952 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2953 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2954 codec->num_pcms = 3;
2955 info = spec->pcm_rec + 2;
2956 info->name = spec->stream_name_analog;
2957 if (spec->alt_dac_nid) {
2958 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2959 *spec->stream_analog_alt_playback;
2960 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2963 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2964 alc_pcm_null_stream;
2965 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2967 if (spec->num_adc_nids > 1) {
2968 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2969 *spec->stream_analog_alt_capture;
2970 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2972 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2973 spec->num_adc_nids - 1;
2975 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2976 alc_pcm_null_stream;
2977 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2984 static void alc_free_kctls(struct hda_codec *codec)
2986 struct alc_spec *spec = codec->spec;
2988 if (spec->kctls.list) {
2989 struct snd_kcontrol_new *kctl = spec->kctls.list;
2991 for (i = 0; i < spec->kctls.used; i++)
2992 kfree(kctl[i].name);
2994 snd_array_free(&spec->kctls);
2997 static void alc_free(struct hda_codec *codec)
2999 struct alc_spec *spec = codec->spec;
3004 alc_free_kctls(codec);
3006 codec->spec = NULL; /* to be sure */
3009 #ifdef SND_HDA_NEEDS_RESUME
3010 static void store_pin_configs(struct hda_codec *codec)
3012 struct alc_spec *spec = codec->spec;
3013 hda_nid_t nid, end_nid;
3015 end_nid = codec->start_nid + codec->num_nodes;
3016 for (nid = codec->start_nid; nid < end_nid; nid++) {
3017 unsigned int wid_caps = get_wcaps(codec, nid);
3018 unsigned int wid_type =
3019 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3020 if (wid_type != AC_WID_PIN)
3022 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
3024 spec->pin_nids[spec->num_pins] = nid;
3025 spec->pin_cfgs[spec->num_pins] =
3026 snd_hda_codec_read(codec, nid, 0,
3027 AC_VERB_GET_CONFIG_DEFAULT, 0);
3032 static void resume_pin_configs(struct hda_codec *codec)
3034 struct alc_spec *spec = codec->spec;
3037 for (i = 0; i < spec->num_pins; i++) {
3038 hda_nid_t pin_nid = spec->pin_nids[i];
3039 unsigned int pin_config = spec->pin_cfgs[i];
3040 snd_hda_codec_write(codec, pin_nid, 0,
3041 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
3042 pin_config & 0x000000ff);
3043 snd_hda_codec_write(codec, pin_nid, 0,
3044 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
3045 (pin_config & 0x0000ff00) >> 8);
3046 snd_hda_codec_write(codec, pin_nid, 0,
3047 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
3048 (pin_config & 0x00ff0000) >> 16);
3049 snd_hda_codec_write(codec, pin_nid, 0,
3050 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
3055 static int alc_resume(struct hda_codec *codec)
3057 resume_pin_configs(codec);
3058 codec->patch_ops.init(codec);
3059 snd_hda_codec_resume_amp(codec);
3060 snd_hda_codec_resume_cache(codec);
3064 #define store_pin_configs(codec)
3069 static struct hda_codec_ops alc_patch_ops = {
3070 .build_controls = alc_build_controls,
3071 .build_pcms = alc_build_pcms,
3074 .unsol_event = alc_unsol_event,
3075 #ifdef SND_HDA_NEEDS_RESUME
3076 .resume = alc_resume,
3078 #ifdef CONFIG_SND_HDA_POWER_SAVE
3079 .check_power_status = alc_check_power_status,
3085 * Test configuration for debugging
3087 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3090 #ifdef CONFIG_SND_DEBUG
3091 static hda_nid_t alc880_test_dac_nids[4] = {
3092 0x02, 0x03, 0x04, 0x05
3095 static struct hda_input_mux alc880_test_capture_source = {
3104 { "Surround", 0x6 },
3108 static struct hda_channel_mode alc880_test_modes[4] = {
3115 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3116 struct snd_ctl_elem_info *uinfo)
3118 static char *texts[] = {
3119 "N/A", "Line Out", "HP Out",
3120 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3122 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3124 uinfo->value.enumerated.items = 8;
3125 if (uinfo->value.enumerated.item >= 8)
3126 uinfo->value.enumerated.item = 7;
3127 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3131 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3132 struct snd_ctl_elem_value *ucontrol)
3134 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3135 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3136 unsigned int pin_ctl, item = 0;
3138 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3139 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3140 if (pin_ctl & AC_PINCTL_OUT_EN) {
3141 if (pin_ctl & AC_PINCTL_HP_EN)
3145 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3146 switch (pin_ctl & AC_PINCTL_VREFEN) {
3147 case AC_PINCTL_VREF_HIZ: item = 3; break;
3148 case AC_PINCTL_VREF_50: item = 4; break;
3149 case AC_PINCTL_VREF_GRD: item = 5; break;
3150 case AC_PINCTL_VREF_80: item = 6; break;
3151 case AC_PINCTL_VREF_100: item = 7; break;
3154 ucontrol->value.enumerated.item[0] = item;
3158 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3159 struct snd_ctl_elem_value *ucontrol)
3161 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3162 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3163 static unsigned int ctls[] = {
3164 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3165 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3166 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3167 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3168 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3169 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3171 unsigned int old_ctl, new_ctl;
3173 old_ctl = snd_hda_codec_read(codec, nid, 0,
3174 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3175 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3176 if (old_ctl != new_ctl) {
3178 snd_hda_codec_write_cache(codec, nid, 0,
3179 AC_VERB_SET_PIN_WIDGET_CONTROL,
3181 val = ucontrol->value.enumerated.item[0] >= 3 ?
3183 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3190 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3191 struct snd_ctl_elem_info *uinfo)
3193 static char *texts[] = {
3194 "Front", "Surround", "CLFE", "Side"
3196 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3198 uinfo->value.enumerated.items = 4;
3199 if (uinfo->value.enumerated.item >= 4)
3200 uinfo->value.enumerated.item = 3;
3201 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3205 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3206 struct snd_ctl_elem_value *ucontrol)
3208 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3209 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3212 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3213 ucontrol->value.enumerated.item[0] = sel & 3;
3217 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3218 struct snd_ctl_elem_value *ucontrol)
3220 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3221 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3224 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3225 if (ucontrol->value.enumerated.item[0] != sel) {
3226 sel = ucontrol->value.enumerated.item[0] & 3;
3227 snd_hda_codec_write_cache(codec, nid, 0,
3228 AC_VERB_SET_CONNECT_SEL, sel);
3234 #define PIN_CTL_TEST(xname,nid) { \
3235 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3237 .info = alc_test_pin_ctl_info, \
3238 .get = alc_test_pin_ctl_get, \
3239 .put = alc_test_pin_ctl_put, \
3240 .private_value = nid \
3243 #define PIN_SRC_TEST(xname,nid) { \
3244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3246 .info = alc_test_pin_src_info, \
3247 .get = alc_test_pin_src_get, \
3248 .put = alc_test_pin_src_put, \
3249 .private_value = nid \
3252 static struct snd_kcontrol_new alc880_test_mixer[] = {
3253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3254 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3255 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3256 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3257 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3258 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3259 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3260 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3261 PIN_CTL_TEST("Front Pin Mode", 0x14),
3262 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3263 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3264 PIN_CTL_TEST("Side Pin Mode", 0x17),
3265 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3266 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3267 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3268 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3269 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3270 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3271 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3272 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3273 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3274 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3275 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3276 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3277 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3278 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3279 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3280 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3281 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3282 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3285 .name = "Channel Mode",
3286 .info = alc_ch_mode_info,
3287 .get = alc_ch_mode_get,
3288 .put = alc_ch_mode_put,
3293 static struct hda_verb alc880_test_init_verbs[] = {
3294 /* Unmute inputs of 0x0c - 0x0f */
3295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3300 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3301 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3302 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3303 /* Vol output for 0x0c-0x0f */
3304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3305 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3307 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3308 /* Set output pins 0x14-0x17 */
3309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3310 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3311 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3312 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3313 /* Unmute output pins 0x14-0x17 */
3314 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3316 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3318 /* Set input pins 0x18-0x1c */
3319 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3320 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3321 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3322 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3323 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3324 /* Mute input pins 0x18-0x1b */
3325 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3326 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3327 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3328 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3331 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3332 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3333 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3334 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3335 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3336 /* Analog input/passthru */
3337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3341 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3349 static const char *alc880_models[ALC880_MODEL_LAST] = {
3350 [ALC880_3ST] = "3stack",
3351 [ALC880_TCL_S700] = "tcl",
3352 [ALC880_3ST_DIG] = "3stack-digout",
3353 [ALC880_CLEVO] = "clevo",
3354 [ALC880_5ST] = "5stack",
3355 [ALC880_5ST_DIG] = "5stack-digout",
3356 [ALC880_W810] = "w810",
3357 [ALC880_Z71V] = "z71v",
3358 [ALC880_6ST] = "6stack",
3359 [ALC880_6ST_DIG] = "6stack-digout",
3360 [ALC880_ASUS] = "asus",
3361 [ALC880_ASUS_W1V] = "asus-w1v",
3362 [ALC880_ASUS_DIG] = "asus-dig",
3363 [ALC880_ASUS_DIG2] = "asus-dig2",
3364 [ALC880_UNIWILL_DIG] = "uniwill",
3365 [ALC880_UNIWILL_P53] = "uniwill-p53",
3366 [ALC880_FUJITSU] = "fujitsu",
3367 [ALC880_F1734] = "F1734",
3369 [ALC880_LG_LW] = "lg-lw",
3370 [ALC880_MEDION_RIM] = "medion",
3371 #ifdef CONFIG_SND_DEBUG
3372 [ALC880_TEST] = "test",
3374 [ALC880_AUTO] = "auto",
3377 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3378 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3379 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3380 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3381 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3382 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3383 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3384 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3385 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3386 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3387 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3388 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3389 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3390 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3391 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3392 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3393 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3394 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3395 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3396 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3397 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3398 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3399 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3400 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3401 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3402 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3403 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3404 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3405 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3406 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3407 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3408 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3409 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3410 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3411 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3412 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3413 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3414 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3415 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3416 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3417 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3418 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3419 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3420 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3421 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3422 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3423 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3424 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3425 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3426 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3427 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3428 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3429 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3430 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3431 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3432 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3433 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3434 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3435 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3436 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3437 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3438 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3439 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3440 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3441 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3442 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3443 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3444 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3445 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3446 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3447 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3448 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3453 * ALC880 codec presets
3455 static struct alc_config_preset alc880_presets[] = {
3457 .mixers = { alc880_three_stack_mixer },
3458 .init_verbs = { alc880_volume_init_verbs,
3459 alc880_pin_3stack_init_verbs },
3460 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3461 .dac_nids = alc880_dac_nids,
3462 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3463 .channel_mode = alc880_threestack_modes,
3465 .input_mux = &alc880_capture_source,
3467 [ALC880_3ST_DIG] = {
3468 .mixers = { alc880_three_stack_mixer },
3469 .init_verbs = { alc880_volume_init_verbs,
3470 alc880_pin_3stack_init_verbs },
3471 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3472 .dac_nids = alc880_dac_nids,
3473 .dig_out_nid = ALC880_DIGOUT_NID,
3474 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3475 .channel_mode = alc880_threestack_modes,
3477 .input_mux = &alc880_capture_source,
3479 [ALC880_TCL_S700] = {
3480 .mixers = { alc880_tcl_s700_mixer },
3481 .init_verbs = { alc880_volume_init_verbs,
3482 alc880_pin_tcl_S700_init_verbs,
3483 alc880_gpio2_init_verbs },
3484 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3485 .dac_nids = alc880_dac_nids,
3486 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3487 .num_adc_nids = 1, /* single ADC */
3489 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3490 .channel_mode = alc880_2_jack_modes,
3491 .input_mux = &alc880_capture_source,
3494 .mixers = { alc880_three_stack_mixer,
3495 alc880_five_stack_mixer},
3496 .init_verbs = { alc880_volume_init_verbs,
3497 alc880_pin_5stack_init_verbs },
3498 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3499 .dac_nids = alc880_dac_nids,
3500 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3501 .channel_mode = alc880_fivestack_modes,
3502 .input_mux = &alc880_capture_source,
3504 [ALC880_5ST_DIG] = {
3505 .mixers = { alc880_three_stack_mixer,
3506 alc880_five_stack_mixer },
3507 .init_verbs = { alc880_volume_init_verbs,
3508 alc880_pin_5stack_init_verbs },
3509 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3510 .dac_nids = alc880_dac_nids,
3511 .dig_out_nid = ALC880_DIGOUT_NID,
3512 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3513 .channel_mode = alc880_fivestack_modes,
3514 .input_mux = &alc880_capture_source,
3517 .mixers = { alc880_six_stack_mixer },
3518 .init_verbs = { alc880_volume_init_verbs,
3519 alc880_pin_6stack_init_verbs },
3520 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3521 .dac_nids = alc880_6st_dac_nids,
3522 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3523 .channel_mode = alc880_sixstack_modes,
3524 .input_mux = &alc880_6stack_capture_source,
3526 [ALC880_6ST_DIG] = {
3527 .mixers = { alc880_six_stack_mixer },
3528 .init_verbs = { alc880_volume_init_verbs,
3529 alc880_pin_6stack_init_verbs },
3530 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3531 .dac_nids = alc880_6st_dac_nids,
3532 .dig_out_nid = ALC880_DIGOUT_NID,
3533 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3534 .channel_mode = alc880_sixstack_modes,
3535 .input_mux = &alc880_6stack_capture_source,
3538 .mixers = { alc880_w810_base_mixer },
3539 .init_verbs = { alc880_volume_init_verbs,
3540 alc880_pin_w810_init_verbs,
3541 alc880_gpio2_init_verbs },
3542 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3543 .dac_nids = alc880_w810_dac_nids,
3544 .dig_out_nid = ALC880_DIGOUT_NID,
3545 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3546 .channel_mode = alc880_w810_modes,
3547 .input_mux = &alc880_capture_source,
3550 .mixers = { alc880_z71v_mixer },
3551 .init_verbs = { alc880_volume_init_verbs,
3552 alc880_pin_z71v_init_verbs },
3553 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3554 .dac_nids = alc880_z71v_dac_nids,
3555 .dig_out_nid = ALC880_DIGOUT_NID,
3557 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3558 .channel_mode = alc880_2_jack_modes,
3559 .input_mux = &alc880_capture_source,
3562 .mixers = { alc880_f1734_mixer },
3563 .init_verbs = { alc880_volume_init_verbs,
3564 alc880_pin_f1734_init_verbs },
3565 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3566 .dac_nids = alc880_f1734_dac_nids,
3568 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3569 .channel_mode = alc880_2_jack_modes,
3570 .input_mux = &alc880_f1734_capture_source,
3571 .unsol_event = alc880_uniwill_p53_unsol_event,
3572 .init_hook = alc880_uniwill_p53_hp_automute,
3575 .mixers = { alc880_asus_mixer },
3576 .init_verbs = { alc880_volume_init_verbs,
3577 alc880_pin_asus_init_verbs,
3578 alc880_gpio1_init_verbs },
3579 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3580 .dac_nids = alc880_asus_dac_nids,
3581 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3582 .channel_mode = alc880_asus_modes,
3584 .input_mux = &alc880_capture_source,
3586 [ALC880_ASUS_DIG] = {
3587 .mixers = { alc880_asus_mixer },
3588 .init_verbs = { alc880_volume_init_verbs,
3589 alc880_pin_asus_init_verbs,
3590 alc880_gpio1_init_verbs },
3591 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3592 .dac_nids = alc880_asus_dac_nids,
3593 .dig_out_nid = ALC880_DIGOUT_NID,
3594 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3595 .channel_mode = alc880_asus_modes,
3597 .input_mux = &alc880_capture_source,
3599 [ALC880_ASUS_DIG2] = {
3600 .mixers = { alc880_asus_mixer },
3601 .init_verbs = { alc880_volume_init_verbs,
3602 alc880_pin_asus_init_verbs,
3603 alc880_gpio2_init_verbs }, /* use GPIO2 */
3604 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3605 .dac_nids = alc880_asus_dac_nids,
3606 .dig_out_nid = ALC880_DIGOUT_NID,
3607 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3608 .channel_mode = alc880_asus_modes,
3610 .input_mux = &alc880_capture_source,
3612 [ALC880_ASUS_W1V] = {
3613 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3614 .init_verbs = { alc880_volume_init_verbs,
3615 alc880_pin_asus_init_verbs,
3616 alc880_gpio1_init_verbs },
3617 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3618 .dac_nids = alc880_asus_dac_nids,
3619 .dig_out_nid = ALC880_DIGOUT_NID,
3620 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3621 .channel_mode = alc880_asus_modes,
3623 .input_mux = &alc880_capture_source,
3625 [ALC880_UNIWILL_DIG] = {
3626 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3627 .init_verbs = { alc880_volume_init_verbs,
3628 alc880_pin_asus_init_verbs },
3629 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3630 .dac_nids = alc880_asus_dac_nids,
3631 .dig_out_nid = ALC880_DIGOUT_NID,
3632 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3633 .channel_mode = alc880_asus_modes,
3635 .input_mux = &alc880_capture_source,
3637 [ALC880_UNIWILL] = {
3638 .mixers = { alc880_uniwill_mixer },
3639 .init_verbs = { alc880_volume_init_verbs,
3640 alc880_uniwill_init_verbs },
3641 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3642 .dac_nids = alc880_asus_dac_nids,
3643 .dig_out_nid = ALC880_DIGOUT_NID,
3644 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3645 .channel_mode = alc880_threestack_modes,
3647 .input_mux = &alc880_capture_source,
3648 .unsol_event = alc880_uniwill_unsol_event,
3649 .init_hook = alc880_uniwill_automute,
3651 [ALC880_UNIWILL_P53] = {
3652 .mixers = { alc880_uniwill_p53_mixer },
3653 .init_verbs = { alc880_volume_init_verbs,
3654 alc880_uniwill_p53_init_verbs },
3655 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3656 .dac_nids = alc880_asus_dac_nids,
3657 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3658 .channel_mode = alc880_threestack_modes,
3659 .input_mux = &alc880_capture_source,
3660 .unsol_event = alc880_uniwill_p53_unsol_event,
3661 .init_hook = alc880_uniwill_p53_hp_automute,
3663 [ALC880_FUJITSU] = {
3664 .mixers = { alc880_fujitsu_mixer,
3665 alc880_pcbeep_mixer, },
3666 .init_verbs = { alc880_volume_init_verbs,
3667 alc880_uniwill_p53_init_verbs,
3668 alc880_beep_init_verbs },
3669 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3670 .dac_nids = alc880_dac_nids,
3671 .dig_out_nid = ALC880_DIGOUT_NID,
3672 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3673 .channel_mode = alc880_2_jack_modes,
3674 .input_mux = &alc880_capture_source,
3675 .unsol_event = alc880_uniwill_p53_unsol_event,
3676 .init_hook = alc880_uniwill_p53_hp_automute,
3679 .mixers = { alc880_three_stack_mixer },
3680 .init_verbs = { alc880_volume_init_verbs,
3681 alc880_pin_clevo_init_verbs },
3682 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3683 .dac_nids = alc880_dac_nids,
3685 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3686 .channel_mode = alc880_threestack_modes,
3688 .input_mux = &alc880_capture_source,
3691 .mixers = { alc880_lg_mixer },
3692 .init_verbs = { alc880_volume_init_verbs,
3693 alc880_lg_init_verbs },
3694 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3695 .dac_nids = alc880_lg_dac_nids,
3696 .dig_out_nid = ALC880_DIGOUT_NID,
3697 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3698 .channel_mode = alc880_lg_ch_modes,
3700 .input_mux = &alc880_lg_capture_source,
3701 .unsol_event = alc880_lg_unsol_event,
3702 .init_hook = alc880_lg_automute,
3703 #ifdef CONFIG_SND_HDA_POWER_SAVE
3704 .loopbacks = alc880_lg_loopbacks,
3708 .mixers = { alc880_lg_lw_mixer },
3709 .init_verbs = { alc880_volume_init_verbs,
3710 alc880_lg_lw_init_verbs },
3711 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3712 .dac_nids = alc880_dac_nids,
3713 .dig_out_nid = ALC880_DIGOUT_NID,
3714 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3715 .channel_mode = alc880_lg_lw_modes,
3716 .input_mux = &alc880_lg_lw_capture_source,
3717 .unsol_event = alc880_lg_lw_unsol_event,
3718 .init_hook = alc880_lg_lw_automute,
3720 [ALC880_MEDION_RIM] = {
3721 .mixers = { alc880_medion_rim_mixer },
3722 .init_verbs = { alc880_volume_init_verbs,
3723 alc880_medion_rim_init_verbs,
3724 alc_gpio2_init_verbs },
3725 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3726 .dac_nids = alc880_dac_nids,
3727 .dig_out_nid = ALC880_DIGOUT_NID,
3728 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3729 .channel_mode = alc880_2_jack_modes,
3730 .input_mux = &alc880_medion_rim_capture_source,
3731 .unsol_event = alc880_medion_rim_unsol_event,
3732 .init_hook = alc880_medion_rim_automute,
3734 #ifdef CONFIG_SND_DEBUG
3736 .mixers = { alc880_test_mixer },
3737 .init_verbs = { alc880_test_init_verbs },
3738 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3739 .dac_nids = alc880_test_dac_nids,
3740 .dig_out_nid = ALC880_DIGOUT_NID,
3741 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3742 .channel_mode = alc880_test_modes,
3743 .input_mux = &alc880_test_capture_source,
3749 * Automatic parse of I/O pins from the BIOS configuration
3754 ALC_CTL_WIDGET_MUTE,
3757 static struct snd_kcontrol_new alc880_control_templates[] = {
3758 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3759 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3760 HDA_BIND_MUTE(NULL, 0, 0, 0),
3763 /* add dynamic controls */
3764 static int add_control(struct alc_spec *spec, int type, const char *name,
3767 struct snd_kcontrol_new *knew;
3769 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3770 knew = snd_array_new(&spec->kctls);
3773 *knew = alc880_control_templates[type];
3774 knew->name = kstrdup(name, GFP_KERNEL);
3777 knew->private_value = val;
3781 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3782 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3783 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3784 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3785 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3786 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3787 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3788 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3789 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3790 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3791 #define ALC880_PIN_CD_NID 0x1c
3793 /* fill in the dac_nids table from the parsed pin configuration */
3794 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3795 const struct auto_pin_cfg *cfg)
3801 memset(assigned, 0, sizeof(assigned));
3802 spec->multiout.dac_nids = spec->private_dac_nids;
3804 /* check the pins hardwired to audio widget */
3805 for (i = 0; i < cfg->line_outs; i++) {
3806 nid = cfg->line_out_pins[i];
3807 if (alc880_is_fixed_pin(nid)) {
3808 int idx = alc880_fixed_pin_idx(nid);
3809 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3813 /* left pins can be connect to any audio widget */
3814 for (i = 0; i < cfg->line_outs; i++) {
3815 nid = cfg->line_out_pins[i];
3816 if (alc880_is_fixed_pin(nid))
3818 /* search for an empty channel */
3819 for (j = 0; j < cfg->line_outs; j++) {
3821 spec->multiout.dac_nids[i] =
3822 alc880_idx_to_dac(j);
3828 spec->multiout.num_dacs = cfg->line_outs;
3832 /* add playback controls from the parsed DAC table */
3833 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3834 const struct auto_pin_cfg *cfg)
3837 static const char *chname[4] = {
3838 "Front", "Surround", NULL /*CLFE*/, "Side"
3843 for (i = 0; i < cfg->line_outs; i++) {
3844 if (!spec->multiout.dac_nids[i])
3846 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3849 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3850 "Center Playback Volume",
3851 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3855 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3856 "LFE Playback Volume",
3857 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3861 err = add_control(spec, ALC_CTL_BIND_MUTE,
3862 "Center Playback Switch",
3863 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3867 err = add_control(spec, ALC_CTL_BIND_MUTE,
3868 "LFE Playback Switch",
3869 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3874 sprintf(name, "%s Playback Volume", chname[i]);
3875 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3876 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3880 sprintf(name, "%s Playback Switch", chname[i]);
3881 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3882 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3891 /* add playback controls for speaker and HP outputs */
3892 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3902 if (alc880_is_fixed_pin(pin)) {
3903 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3904 /* specify the DAC as the extra output */
3905 if (!spec->multiout.hp_nid)
3906 spec->multiout.hp_nid = nid;
3908 spec->multiout.extra_out_nid[0] = nid;
3909 /* control HP volume/switch on the output mixer amp */
3910 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3911 sprintf(name, "%s Playback Volume", pfx);
3912 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3913 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3916 sprintf(name, "%s Playback Switch", pfx);
3917 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3918 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3921 } else if (alc880_is_multi_pin(pin)) {
3922 /* set manual connection */
3923 /* we have only a switch on HP-out PIN */
3924 sprintf(name, "%s Playback Switch", pfx);
3925 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3926 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3933 /* create input playback/capture controls for the given pin */
3934 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3935 const char *ctlname,
3936 int idx, hda_nid_t mix_nid)
3941 sprintf(name, "%s Playback Volume", ctlname);
3942 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3943 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3946 sprintf(name, "%s Playback Switch", ctlname);
3947 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3948 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3954 /* create playback/capture controls for input pins */
3955 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3956 const struct auto_pin_cfg *cfg)
3958 struct hda_input_mux *imux = &spec->private_imux;
3961 for (i = 0; i < AUTO_PIN_LAST; i++) {
3962 if (alc880_is_input_pin(cfg->input_pins[i])) {
3963 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3964 err = new_analog_input(spec, cfg->input_pins[i],
3965 auto_pin_cfg_labels[i],
3969 imux->items[imux->num_items].label =
3970 auto_pin_cfg_labels[i];
3971 imux->items[imux->num_items].index =
3972 alc880_input_pin_idx(cfg->input_pins[i]);
3979 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3980 unsigned int pin_type)
3982 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3985 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3989 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3990 hda_nid_t nid, int pin_type,
3993 alc_set_pin_output(codec, nid, pin_type);
3994 /* need the manual connection? */
3995 if (alc880_is_multi_pin(nid)) {
3996 struct alc_spec *spec = codec->spec;
3997 int idx = alc880_multi_pin_idx(nid);
3998 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3999 AC_VERB_SET_CONNECT_SEL,
4000 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4004 static int get_pin_type(int line_out_type)
4006 if (line_out_type == AUTO_PIN_HP_OUT)
4012 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4014 struct alc_spec *spec = codec->spec;
4017 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4018 for (i = 0; i < spec->autocfg.line_outs; i++) {
4019 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4020 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4021 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4025 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4027 struct alc_spec *spec = codec->spec;
4030 pin = spec->autocfg.speaker_pins[0];
4031 if (pin) /* connect to front */
4032 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4033 pin = spec->autocfg.hp_pins[0];
4034 if (pin) /* connect to front */
4035 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4038 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4040 struct alc_spec *spec = codec->spec;
4043 for (i = 0; i < AUTO_PIN_LAST; i++) {
4044 hda_nid_t nid = spec->autocfg.input_pins[i];
4045 if (alc880_is_input_pin(nid)) {
4046 snd_hda_codec_write(codec, nid, 0,
4047 AC_VERB_SET_PIN_WIDGET_CONTROL,
4048 i <= AUTO_PIN_FRONT_MIC ?
4049 PIN_VREF80 : PIN_IN);
4050 if (nid != ALC880_PIN_CD_NID)
4051 snd_hda_codec_write(codec, nid, 0,
4052 AC_VERB_SET_AMP_GAIN_MUTE,
4058 /* parse the BIOS configuration and set up the alc_spec */
4059 /* return 1 if successful, 0 if the proper config is not found,
4060 * or a negative error code
4062 static int alc880_parse_auto_config(struct hda_codec *codec)
4064 struct alc_spec *spec = codec->spec;
4066 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4068 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4072 if (!spec->autocfg.line_outs)
4073 return 0; /* can't find valid BIOS pin config */
4075 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4078 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4081 err = alc880_auto_create_extra_out(spec,
4082 spec->autocfg.speaker_pins[0],
4086 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4090 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4094 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4096 if (spec->autocfg.dig_out_pin)
4097 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4098 if (spec->autocfg.dig_in_pin)
4099 spec->dig_in_nid = ALC880_DIGIN_NID;
4101 if (spec->kctls.list)
4102 add_mixer(spec, spec->kctls.list);
4104 add_verb(spec, alc880_volume_init_verbs);
4106 spec->num_mux_defs = 1;
4107 spec->input_mux = &spec->private_imux;
4109 store_pin_configs(codec);
4113 /* additional initialization for auto-configuration model */
4114 static void alc880_auto_init(struct hda_codec *codec)
4116 struct alc_spec *spec = codec->spec;
4117 alc880_auto_init_multi_out(codec);
4118 alc880_auto_init_extra_out(codec);
4119 alc880_auto_init_analog_input(codec);
4120 if (spec->unsol_event)
4121 alc_inithook(codec);
4125 * OK, here we have finally the patch for ALC880
4128 static void set_capture_mixer(struct alc_spec *spec)
4130 static struct snd_kcontrol_new *caps[3] = {
4135 if (spec->num_adc_nids > 0 && spec->num_adc_nids < 3)
4136 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4139 static int patch_alc880(struct hda_codec *codec)
4141 struct alc_spec *spec;
4145 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4151 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4154 if (board_config < 0) {
4155 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4156 "trying auto-probe from BIOS...\n");
4157 board_config = ALC880_AUTO;
4160 if (board_config == ALC880_AUTO) {
4161 /* automatic parse from the BIOS config */
4162 err = alc880_parse_auto_config(codec);
4168 "hda_codec: Cannot set up configuration "
4169 "from BIOS. Using 3-stack mode...\n");
4170 board_config = ALC880_3ST;
4174 if (board_config != ALC880_AUTO)
4175 setup_preset(spec, &alc880_presets[board_config]);
4177 spec->stream_name_analog = "ALC880 Analog";
4178 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4179 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4180 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4182 spec->stream_name_digital = "ALC880 Digital";
4183 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4184 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4186 if (!spec->adc_nids && spec->input_mux) {
4187 /* check whether NID 0x07 is valid */
4188 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4190 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4191 if (wcap != AC_WID_AUD_IN) {
4192 spec->adc_nids = alc880_adc_nids_alt;
4193 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4195 spec->adc_nids = alc880_adc_nids;
4196 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4199 set_capture_mixer(spec);
4201 spec->vmaster_nid = 0x0c;
4203 codec->patch_ops = alc_patch_ops;
4204 if (board_config == ALC880_AUTO)
4205 spec->init_hook = alc880_auto_init;
4206 #ifdef CONFIG_SND_HDA_POWER_SAVE
4207 if (!spec->loopback.amplist)
4208 spec->loopback.amplist = alc880_loopbacks;
4219 static hda_nid_t alc260_dac_nids[1] = {
4224 static hda_nid_t alc260_adc_nids[1] = {
4229 static hda_nid_t alc260_adc_nids_alt[1] = {
4234 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4235 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4237 static hda_nid_t alc260_dual_adc_nids[2] = {
4242 #define ALC260_DIGOUT_NID 0x03
4243 #define ALC260_DIGIN_NID 0x06
4245 static struct hda_input_mux alc260_capture_source = {
4249 { "Front Mic", 0x1 },
4255 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4256 * headphone jack and the internal CD lines since these are the only pins at
4257 * which audio can appear. For flexibility, also allow the option of
4258 * recording the mixer output on the second ADC (ADC0 doesn't have a
4259 * connection to the mixer output).
4261 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4265 { "Mic/Line", 0x0 },
4267 { "Headphone", 0x2 },
4273 { "Mic/Line", 0x0 },
4275 { "Headphone", 0x2 },
4282 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4283 * the Fujitsu S702x, but jacks are marked differently.
4285 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4292 { "Headphone", 0x5 },
4301 { "Headphone", 0x6 },
4307 * This is just place-holder, so there's something for alc_build_pcms to look
4308 * at when it calculates the maximum number of channels. ALC260 has no mixer
4309 * element which allows changing the channel mode, so the verb list is
4312 static struct hda_channel_mode alc260_modes[1] = {
4317 /* Mixer combinations
4319 * basic: base_output + input + pc_beep + capture
4320 * HP: base_output + input + capture_alt
4321 * HP_3013: hp_3013 + input + capture
4322 * fujitsu: fujitsu + capture
4323 * acer: acer + capture
4326 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4327 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4328 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4329 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4330 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4331 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4332 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4336 static struct snd_kcontrol_new alc260_input_mixer[] = {
4337 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4338 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4339 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4340 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4342 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4343 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4344 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4348 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4349 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4350 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4354 /* update HP, line and mono out pins according to the master switch */
4355 static void alc260_hp_master_update(struct hda_codec *codec,
4356 hda_nid_t hp, hda_nid_t line,
4359 struct alc_spec *spec = codec->spec;
4360 unsigned int val = spec->master_sw ? PIN_HP : 0;
4361 /* change HP and line-out pins */
4362 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4364 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4366 /* mono (speaker) depending on the HP jack sense */
4367 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4368 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4372 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4373 struct snd_ctl_elem_value *ucontrol)
4375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4376 struct alc_spec *spec = codec->spec;
4377 *ucontrol->value.integer.value = spec->master_sw;
4381 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4382 struct snd_ctl_elem_value *ucontrol)
4384 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4385 struct alc_spec *spec = codec->spec;
4386 int val = !!*ucontrol->value.integer.value;
4387 hda_nid_t hp, line, mono;
4389 if (val == spec->master_sw)
4391 spec->master_sw = val;
4392 hp = (kcontrol->private_value >> 16) & 0xff;
4393 line = (kcontrol->private_value >> 8) & 0xff;
4394 mono = kcontrol->private_value & 0xff;
4395 alc260_hp_master_update(codec, hp, line, mono);
4399 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4401 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4402 .name = "Master Playback Switch",
4403 .info = snd_ctl_boolean_mono_info,
4404 .get = alc260_hp_master_sw_get,
4405 .put = alc260_hp_master_sw_put,
4406 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4408 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4409 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4410 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4411 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4412 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4414 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4418 static struct hda_verb alc260_hp_unsol_verbs[] = {
4419 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4423 static void alc260_hp_automute(struct hda_codec *codec)
4425 struct alc_spec *spec = codec->spec;
4426 unsigned int present;
4428 present = snd_hda_codec_read(codec, 0x10, 0,
4429 AC_VERB_GET_PIN_SENSE, 0);
4430 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4431 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4434 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4436 if ((res >> 26) == ALC880_HP_EVENT)
4437 alc260_hp_automute(codec);
4440 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4443 .name = "Master Playback Switch",
4444 .info = snd_ctl_boolean_mono_info,
4445 .get = alc260_hp_master_sw_get,
4446 .put = alc260_hp_master_sw_put,
4447 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4449 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4450 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4451 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4452 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4455 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4456 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4460 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4461 .ops = &snd_hda_bind_vol,
4463 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4464 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4465 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4470 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4471 .ops = &snd_hda_bind_sw,
4473 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4474 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4479 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4480 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4481 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4482 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4487 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4488 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4492 static void alc260_hp_3013_automute(struct hda_codec *codec)
4494 struct alc_spec *spec = codec->spec;
4495 unsigned int present;
4497 present = snd_hda_codec_read(codec, 0x15, 0,
4498 AC_VERB_GET_PIN_SENSE, 0);
4499 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4500 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4503 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4506 if ((res >> 26) == ALC880_HP_EVENT)
4507 alc260_hp_3013_automute(codec);
4510 static void alc260_hp_3012_automute(struct hda_codec *codec)
4512 unsigned int present, bits;
4514 present = snd_hda_codec_read(codec, 0x10, 0,
4515 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4517 bits = present ? 0 : PIN_OUT;
4518 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4520 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4522 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4526 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4529 if ((res >> 26) == ALC880_HP_EVENT)
4530 alc260_hp_3012_automute(codec);
4533 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4534 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4536 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4537 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4538 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4539 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4540 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4541 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4542 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4543 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4544 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4545 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4546 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4547 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4548 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4552 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4553 * versions of the ALC260 don't act on requests to enable mic bias from NID
4554 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4555 * datasheet doesn't mention this restriction. At this stage it's not clear
4556 * whether this behaviour is intentional or is a hardware bug in chip
4557 * revisions available in early 2006. Therefore for now allow the
4558 * "Headphone Jack Mode" control to span all choices, but if it turns out
4559 * that the lack of mic bias for this NID is intentional we could change the
4560 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4562 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4563 * don't appear to make the mic bias available from the "line" jack, even
4564 * though the NID used for this jack (0x14) can supply it. The theory is
4565 * that perhaps Acer have included blocking capacitors between the ALC260
4566 * and the output jack. If this turns out to be the case for all such
4567 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4568 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4570 * The C20x Tablet series have a mono internal speaker which is controlled
4571 * via the chip's Mono sum widget and pin complex, so include the necessary
4572 * controls for such models. On models without a "mono speaker" the control
4573 * won't do anything.
4575 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4576 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4577 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4578 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4579 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4581 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4583 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4584 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4586 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4587 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4588 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4589 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4590 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4591 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4592 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4596 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4597 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4599 static struct snd_kcontrol_new alc260_will_mixer[] = {
4600 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4601 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4603 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4604 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4605 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4606 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4607 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4608 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4609 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4610 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4611 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4615 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4616 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4618 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4619 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4620 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4622 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4623 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4624 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4625 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4626 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4627 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4628 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4633 * initialization verbs
4635 static struct hda_verb alc260_init_verbs[] = {
4636 /* Line In pin widget for input */
4637 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4638 /* CD pin widget for input */
4639 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4640 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4641 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4642 /* Mic2 (front panel) pin widget for input and vref at 80% */
4643 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4644 /* LINE-2 is used for line-out in rear */
4645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4646 /* select line-out */
4647 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4649 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4651 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4653 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4654 /* mute capture amp left and right */
4655 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4656 /* set connection select to line in (default select for this ADC) */
4657 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4658 /* mute capture amp left and right */
4659 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4660 /* set connection select to line in (default select for this ADC) */
4661 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4662 /* set vol=0 Line-Out mixer amp left and right */
4663 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4664 /* unmute pin widget amp left and right (no gain on this amp) */
4665 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4666 /* set vol=0 HP mixer amp left and right */
4667 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4668 /* unmute pin widget amp left and right (no gain on this amp) */
4669 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4670 /* set vol=0 Mono mixer amp left and right */
4671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4672 /* unmute pin widget amp left and right (no gain on this amp) */
4673 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4674 /* unmute LINE-2 out pin */
4675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4676 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4679 /* mute analog inputs */
4680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4685 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4686 /* mute Front out path */
4687 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4688 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4689 /* mute Headphone out path */
4690 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4692 /* mute Mono out path */
4693 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4694 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4698 #if 0 /* should be identical with alc260_init_verbs? */
4699 static struct hda_verb alc260_hp_init_verbs[] = {
4700 /* Headphone and output */
4701 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4703 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4704 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4705 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4706 /* Mic2 (front panel) pin widget for input and vref at 80% */
4707 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4708 /* Line In pin widget for input */
4709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4710 /* Line-2 pin widget for output */
4711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4712 /* CD pin widget for input */
4713 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4714 /* unmute amp left and right */
4715 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4716 /* set connection select to line in (default select for this ADC) */
4717 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4718 /* unmute Line-Out mixer amp left and right (volume = 0) */
4719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4720 /* mute pin widget amp left and right (no gain on this amp) */
4721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4722 /* unmute HP mixer amp left and right (volume = 0) */
4723 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4724 /* mute pin widget amp left and right (no gain on this amp) */
4725 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4726 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4729 /* mute analog inputs */
4730 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4731 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4732 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4734 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4735 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4736 /* Unmute Front out path */
4737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4739 /* Unmute Headphone out path */
4740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4741 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4742 /* Unmute Mono out path */
4743 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4744 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4749 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4750 /* Line out and output */
4751 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4753 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4754 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4755 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4756 /* Mic2 (front panel) pin widget for input and vref at 80% */
4757 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4758 /* Line In pin widget for input */
4759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4760 /* Headphone pin widget for output */
4761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4762 /* CD pin widget for input */
4763 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4764 /* unmute amp left and right */
4765 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4766 /* set connection select to line in (default select for this ADC) */
4767 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4768 /* unmute Line-Out mixer amp left and right (volume = 0) */
4769 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4770 /* mute pin widget amp left and right (no gain on this amp) */
4771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4772 /* unmute HP mixer amp left and right (volume = 0) */
4773 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4774 /* mute pin widget amp left and right (no gain on this amp) */
4775 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4776 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4779 /* mute analog inputs */
4780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4785 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4786 /* Unmute Front out path */
4787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4789 /* Unmute Headphone out path */
4790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4792 /* Unmute Mono out path */
4793 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4798 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4799 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4800 * audio = 0x16, internal speaker = 0x10.
4802 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4803 /* Disable all GPIOs */
4804 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4805 /* Internal speaker is connected to headphone pin */
4806 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4807 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4809 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4810 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4811 /* Ensure all other unused pins are disabled and muted. */
4812 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4813 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4814 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4815 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4816 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4817 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4818 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4819 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4821 /* Disable digital (SPDIF) pins */
4822 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4823 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4825 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4826 * when acting as an output.
4828 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4830 /* Start with output sum widgets muted and their output gains at min */
4831 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4834 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4837 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4838 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4839 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4841 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4842 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4843 /* Unmute Line1 pin widget output buffer since it starts as an output.
4844 * If the pin mode is changed by the user the pin mode control will
4845 * take care of enabling the pin's input/output buffers as needed.
4846 * Therefore there's no need to enable the input buffer at this
4849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4850 /* Unmute input buffer of pin widget used for Line-in (no equiv
4853 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4855 /* Mute capture amp left and right */
4856 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4857 /* Set ADC connection select to match default mixer setting - line
4860 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4862 /* Do the same for the second ADC: mute capture input amp and
4863 * set ADC connection to line in (on mic1 pin)
4865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4866 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4868 /* Mute all inputs to mixer widget (even unconnected ones) */
4869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4881 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4882 * similar laptops (adapted from Fujitsu init verbs).
4884 static struct hda_verb alc260_acer_init_verbs[] = {
4885 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4886 * the headphone jack. Turn this on and rely on the standard mute
4887 * methods whenever the user wants to turn these outputs off.
4889 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4890 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4891 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4892 /* Internal speaker/Headphone jack is connected to Line-out pin */
4893 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4894 /* Internal microphone/Mic jack is connected to Mic1 pin */
4895 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4896 /* Line In jack is connected to Line1 pin */
4897 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4898 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4899 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4900 /* Ensure all other unused pins are disabled and muted. */
4901 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4902 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4903 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4904 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4905 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4906 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4907 /* Disable digital (SPDIF) pins */
4908 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4909 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4911 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4912 * bus when acting as outputs.
4914 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4915 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4917 /* Start with output sum widgets muted and their output gains at min */
4918 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4919 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4920 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4921 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4922 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4923 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4924 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4925 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4926 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4928 /* Unmute Line-out pin widget amp left and right
4929 * (no equiv mixer ctrl)
4931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4932 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4933 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4934 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4935 * inputs. If the pin mode is changed by the user the pin mode control
4936 * will take care of enabling the pin's input/output buffers as needed.
4937 * Therefore there's no need to enable the input buffer at this
4940 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4941 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4943 /* Mute capture amp left and right */
4944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4945 /* Set ADC connection select to match default mixer setting - mic
4948 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4950 /* Do similar with the second ADC: mute capture input amp and
4951 * set ADC connection to mic to match ALSA's default state.
4953 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4954 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4956 /* Mute all inputs to mixer widget (even unconnected ones) */
4957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4964 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4969 static struct hda_verb alc260_will_verbs[] = {
4970 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4971 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4972 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4973 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4974 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4975 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4979 static struct hda_verb alc260_replacer_672v_verbs[] = {
4980 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4981 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4982 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4984 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4985 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4986 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4988 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4992 /* toggle speaker-output according to the hp-jack state */
4993 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4995 unsigned int present;
4997 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4998 present = snd_hda_codec_read(codec, 0x0f, 0,
4999 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5001 snd_hda_codec_write_cache(codec, 0x01, 0,
5002 AC_VERB_SET_GPIO_DATA, 1);
5003 snd_hda_codec_write_cache(codec, 0x0f, 0,
5004 AC_VERB_SET_PIN_WIDGET_CONTROL,
5007 snd_hda_codec_write_cache(codec, 0x01, 0,
5008 AC_VERB_SET_GPIO_DATA, 0);
5009 snd_hda_codec_write_cache(codec, 0x0f, 0,
5010 AC_VERB_SET_PIN_WIDGET_CONTROL,
5015 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5018 if ((res >> 26) == ALC880_HP_EVENT)
5019 alc260_replacer_672v_automute(codec);
5022 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5023 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5024 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5025 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5026 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5027 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5029 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5030 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5031 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5032 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5036 /* Test configuration for debugging, modelled after the ALC880 test
5039 #ifdef CONFIG_SND_DEBUG
5040 static hda_nid_t alc260_test_dac_nids[1] = {
5043 static hda_nid_t alc260_test_adc_nids[2] = {
5046 /* For testing the ALC260, each input MUX needs its own definition since
5047 * the signal assignments are different. This assumes that the first ADC
5050 static struct hda_input_mux alc260_test_capture_sources[2] = {
5054 { "MIC1 pin", 0x0 },
5055 { "MIC2 pin", 0x1 },
5056 { "LINE1 pin", 0x2 },
5057 { "LINE2 pin", 0x3 },
5059 { "LINE-OUT pin", 0x5 },
5060 { "HP-OUT pin", 0x6 },
5066 { "MIC1 pin", 0x0 },
5067 { "MIC2 pin", 0x1 },
5068 { "LINE1 pin", 0x2 },
5069 { "LINE2 pin", 0x3 },
5072 { "LINE-OUT pin", 0x6 },
5073 { "HP-OUT pin", 0x7 },
5077 static struct snd_kcontrol_new alc260_test_mixer[] = {
5078 /* Output driver widgets */
5079 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5080 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5081 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5082 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5083 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5084 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5086 /* Modes for retasking pin widgets
5087 * Note: the ALC260 doesn't seem to act on requests to enable mic
5088 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5089 * mention this restriction. At this stage it's not clear whether
5090 * this behaviour is intentional or is a hardware bug in chip
5091 * revisions available at least up until early 2006. Therefore for
5092 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5093 * choices, but if it turns out that the lack of mic bias for these
5094 * NIDs is intentional we could change their modes from
5095 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5097 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5098 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5099 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5100 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5101 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5102 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5104 /* Loopback mixer controls */
5105 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5106 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5107 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5108 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5109 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5110 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5111 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5112 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5113 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5114 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5115 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5116 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5117 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5118 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5119 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5120 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5122 /* Controls for GPIO pins, assuming they are configured as outputs */
5123 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5124 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5125 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5126 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5128 /* Switches to allow the digital IO pins to be enabled. The datasheet
5129 * is ambigious as to which NID is which; testing on laptops which
5130 * make this output available should provide clarification.
5132 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5133 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5135 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5136 * this output to turn on an external amplifier.
5138 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5139 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5143 static struct hda_verb alc260_test_init_verbs[] = {
5144 /* Enable all GPIOs as outputs with an initial value of 0 */
5145 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5146 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5147 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5149 /* Enable retasking pins as output, initially without power amp */
5150 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5151 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5154 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5155 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5157 /* Disable digital (SPDIF) pins initially, but users can enable
5158 * them via a mixer switch. In the case of SPDIF-out, this initverb
5159 * payload also sets the generation to 0, output to be in "consumer"
5160 * PCM format, copyright asserted, no pre-emphasis and no validity
5163 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5164 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5166 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5167 * OUT1 sum bus when acting as an output.
5169 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5170 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5171 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5172 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5174 /* Start with output sum widgets muted and their output gains at min */
5175 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5176 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5177 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5178 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5179 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5180 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5181 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5182 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5183 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5185 /* Unmute retasking pin widget output buffers since the default
5186 * state appears to be output. As the pin mode is changed by the
5187 * user the pin mode control will take care of enabling the pin's
5188 * input/output buffers as needed.
5190 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5191 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5193 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5194 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5195 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5196 /* Also unmute the mono-out pin widget */
5197 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5199 /* Mute capture amp left and right */
5200 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5201 /* Set ADC connection select to match default mixer setting (mic1
5204 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5206 /* Do the same for the second ADC: mute capture input amp and
5207 * set ADC connection to mic1 pin
5209 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5210 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5212 /* Mute all inputs to mixer widget (even unconnected ones) */
5213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5217 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5218 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5219 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5220 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5226 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5227 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5229 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5230 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5233 * for BIOS auto-configuration
5236 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5237 const char *pfx, int *vol_bits)
5240 unsigned long vol_val, sw_val;
5244 if (nid >= 0x0f && nid < 0x11) {
5245 nid_vol = nid - 0x7;
5246 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5247 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5248 } else if (nid == 0x11) {
5249 nid_vol = nid - 0x7;
5250 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5251 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5252 } else if (nid >= 0x12 && nid <= 0x15) {
5254 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5255 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5259 if (!(*vol_bits & (1 << nid_vol))) {
5260 /* first control for the volume widget */
5261 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5262 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5265 *vol_bits |= (1 << nid_vol);
5267 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5268 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5274 /* add playback controls from the parsed DAC table */
5275 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5276 const struct auto_pin_cfg *cfg)
5282 spec->multiout.num_dacs = 1;
5283 spec->multiout.dac_nids = spec->private_dac_nids;
5284 spec->multiout.dac_nids[0] = 0x02;
5286 nid = cfg->line_out_pins[0];
5288 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5293 nid = cfg->speaker_pins[0];
5295 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5300 nid = cfg->hp_pins[0];
5302 err = alc260_add_playback_controls(spec, nid, "Headphone",
5310 /* create playback/capture controls for input pins */
5311 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5312 const struct auto_pin_cfg *cfg)
5314 struct hda_input_mux *imux = &spec->private_imux;
5317 for (i = 0; i < AUTO_PIN_LAST; i++) {
5318 if (cfg->input_pins[i] >= 0x12) {
5319 idx = cfg->input_pins[i] - 0x12;
5320 err = new_analog_input(spec, cfg->input_pins[i],
5321 auto_pin_cfg_labels[i], idx,
5325 imux->items[imux->num_items].label =
5326 auto_pin_cfg_labels[i];
5327 imux->items[imux->num_items].index = idx;
5330 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5331 idx = cfg->input_pins[i] - 0x09;
5332 err = new_analog_input(spec, cfg->input_pins[i],
5333 auto_pin_cfg_labels[i], idx,
5337 imux->items[imux->num_items].label =
5338 auto_pin_cfg_labels[i];
5339 imux->items[imux->num_items].index = idx;
5346 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5347 hda_nid_t nid, int pin_type,
5350 alc_set_pin_output(codec, nid, pin_type);
5351 /* need the manual connection? */
5353 int idx = nid - 0x12;
5354 snd_hda_codec_write(codec, idx + 0x0b, 0,
5355 AC_VERB_SET_CONNECT_SEL, sel_idx);
5359 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5361 struct alc_spec *spec = codec->spec;
5364 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5365 nid = spec->autocfg.line_out_pins[0];
5367 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5368 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5371 nid = spec->autocfg.speaker_pins[0];
5373 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5375 nid = spec->autocfg.hp_pins[0];
5377 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5380 #define ALC260_PIN_CD_NID 0x16
5381 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5383 struct alc_spec *spec = codec->spec;
5386 for (i = 0; i < AUTO_PIN_LAST; i++) {
5387 hda_nid_t nid = spec->autocfg.input_pins[i];
5389 snd_hda_codec_write(codec, nid, 0,
5390 AC_VERB_SET_PIN_WIDGET_CONTROL,
5391 i <= AUTO_PIN_FRONT_MIC ?
5392 PIN_VREF80 : PIN_IN);
5393 if (nid != ALC260_PIN_CD_NID)
5394 snd_hda_codec_write(codec, nid, 0,
5395 AC_VERB_SET_AMP_GAIN_MUTE,
5402 * generic initialization of ADC, input mixers and output mixers
5404 static struct hda_verb alc260_volume_init_verbs[] = {
5406 * Unmute ADC0-1 and set the default input to mic-in
5408 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5409 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5410 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5411 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5413 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5415 * Note: PASD motherboards uses the Line In 2 as the input for
5416 * front panel mic (mic 2)
5418 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5419 /* mute analog inputs */
5420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5427 * Set up output mixers (0x08 - 0x0a)
5429 /* set vol=0 to output mixers */
5430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5431 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5432 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5433 /* set up input amps for analog loopback */
5434 /* Amp Indices: DAC = 0, mixer = 1 */
5435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5436 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5437 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5439 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5440 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5445 static int alc260_parse_auto_config(struct hda_codec *codec)
5447 struct alc_spec *spec = codec->spec;
5449 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5451 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5455 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5458 if (!spec->kctls.list)
5459 return 0; /* can't find valid BIOS pin config */
5460 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5464 spec->multiout.max_channels = 2;
5466 if (spec->autocfg.dig_out_pin)
5467 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5468 if (spec->kctls.list)
5469 add_mixer(spec, spec->kctls.list);
5471 add_verb(spec, alc260_volume_init_verbs);
5473 spec->num_mux_defs = 1;
5474 spec->input_mux = &spec->private_imux;
5476 store_pin_configs(codec);
5480 /* additional initialization for auto-configuration model */
5481 static void alc260_auto_init(struct hda_codec *codec)
5483 struct alc_spec *spec = codec->spec;
5484 alc260_auto_init_multi_out(codec);
5485 alc260_auto_init_analog_input(codec);
5486 if (spec->unsol_event)
5487 alc_inithook(codec);
5490 #ifdef CONFIG_SND_HDA_POWER_SAVE
5491 static struct hda_amp_list alc260_loopbacks[] = {
5492 { 0x07, HDA_INPUT, 0 },
5493 { 0x07, HDA_INPUT, 1 },
5494 { 0x07, HDA_INPUT, 2 },
5495 { 0x07, HDA_INPUT, 3 },
5496 { 0x07, HDA_INPUT, 4 },
5502 * ALC260 configurations
5504 static const char *alc260_models[ALC260_MODEL_LAST] = {
5505 [ALC260_BASIC] = "basic",
5507 [ALC260_HP_3013] = "hp-3013",
5508 [ALC260_HP_DC7600] = "hp-dc7600",
5509 [ALC260_FUJITSU_S702X] = "fujitsu",
5510 [ALC260_ACER] = "acer",
5511 [ALC260_WILL] = "will",
5512 [ALC260_REPLACER_672V] = "replacer",
5513 #ifdef CONFIG_SND_DEBUG
5514 [ALC260_TEST] = "test",
5516 [ALC260_AUTO] = "auto",
5519 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5520 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5521 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5522 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5523 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5524 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5525 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5526 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5527 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5528 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5529 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5530 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5531 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5532 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5533 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5534 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5535 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5536 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5537 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5541 static struct alc_config_preset alc260_presets[] = {
5543 .mixers = { alc260_base_output_mixer,
5545 alc260_pc_beep_mixer },
5546 .init_verbs = { alc260_init_verbs },
5547 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5548 .dac_nids = alc260_dac_nids,
5549 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5550 .adc_nids = alc260_adc_nids,
5551 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5552 .channel_mode = alc260_modes,
5553 .input_mux = &alc260_capture_source,
5556 .mixers = { alc260_hp_output_mixer,
5557 alc260_input_mixer },
5558 .init_verbs = { alc260_init_verbs,
5559 alc260_hp_unsol_verbs },
5560 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5561 .dac_nids = alc260_dac_nids,
5562 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5563 .adc_nids = alc260_adc_nids_alt,
5564 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5565 .channel_mode = alc260_modes,
5566 .input_mux = &alc260_capture_source,
5567 .unsol_event = alc260_hp_unsol_event,
5568 .init_hook = alc260_hp_automute,
5570 [ALC260_HP_DC7600] = {
5571 .mixers = { alc260_hp_dc7600_mixer,
5572 alc260_input_mixer },
5573 .init_verbs = { alc260_init_verbs,
5574 alc260_hp_dc7600_verbs },
5575 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5576 .dac_nids = alc260_dac_nids,
5577 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5578 .adc_nids = alc260_adc_nids_alt,
5579 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5580 .channel_mode = alc260_modes,
5581 .input_mux = &alc260_capture_source,
5582 .unsol_event = alc260_hp_3012_unsol_event,
5583 .init_hook = alc260_hp_3012_automute,
5585 [ALC260_HP_3013] = {
5586 .mixers = { alc260_hp_3013_mixer,
5587 alc260_input_mixer },
5588 .init_verbs = { alc260_hp_3013_init_verbs,
5589 alc260_hp_3013_unsol_verbs },
5590 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5591 .dac_nids = alc260_dac_nids,
5592 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5593 .adc_nids = alc260_adc_nids_alt,
5594 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5595 .channel_mode = alc260_modes,
5596 .input_mux = &alc260_capture_source,
5597 .unsol_event = alc260_hp_3013_unsol_event,
5598 .init_hook = alc260_hp_3013_automute,
5600 [ALC260_FUJITSU_S702X] = {
5601 .mixers = { alc260_fujitsu_mixer },
5602 .init_verbs = { alc260_fujitsu_init_verbs },
5603 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5604 .dac_nids = alc260_dac_nids,
5605 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5606 .adc_nids = alc260_dual_adc_nids,
5607 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5608 .channel_mode = alc260_modes,
5609 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5610 .input_mux = alc260_fujitsu_capture_sources,
5613 .mixers = { alc260_acer_mixer },
5614 .init_verbs = { alc260_acer_init_verbs },
5615 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5616 .dac_nids = alc260_dac_nids,
5617 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5618 .adc_nids = alc260_dual_adc_nids,
5619 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5620 .channel_mode = alc260_modes,
5621 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5622 .input_mux = alc260_acer_capture_sources,
5625 .mixers = { alc260_will_mixer },
5626 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5627 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5628 .dac_nids = alc260_dac_nids,
5629 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5630 .adc_nids = alc260_adc_nids,
5631 .dig_out_nid = ALC260_DIGOUT_NID,
5632 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5633 .channel_mode = alc260_modes,
5634 .input_mux = &alc260_capture_source,
5636 [ALC260_REPLACER_672V] = {
5637 .mixers = { alc260_replacer_672v_mixer },
5638 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5639 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5640 .dac_nids = alc260_dac_nids,
5641 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5642 .adc_nids = alc260_adc_nids,
5643 .dig_out_nid = ALC260_DIGOUT_NID,
5644 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5645 .channel_mode = alc260_modes,
5646 .input_mux = &alc260_capture_source,
5647 .unsol_event = alc260_replacer_672v_unsol_event,
5648 .init_hook = alc260_replacer_672v_automute,
5650 #ifdef CONFIG_SND_DEBUG
5652 .mixers = { alc260_test_mixer },
5653 .init_verbs = { alc260_test_init_verbs },
5654 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5655 .dac_nids = alc260_test_dac_nids,
5656 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5657 .adc_nids = alc260_test_adc_nids,
5658 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5659 .channel_mode = alc260_modes,
5660 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5661 .input_mux = alc260_test_capture_sources,
5666 static int patch_alc260(struct hda_codec *codec)
5668 struct alc_spec *spec;
5669 int err, board_config;
5671 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5677 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5680 if (board_config < 0) {
5681 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5682 "trying auto-probe from BIOS...\n");
5683 board_config = ALC260_AUTO;
5686 if (board_config == ALC260_AUTO) {
5687 /* automatic parse from the BIOS config */
5688 err = alc260_parse_auto_config(codec);
5694 "hda_codec: Cannot set up configuration "
5695 "from BIOS. Using base mode...\n");
5696 board_config = ALC260_BASIC;
5700 if (board_config != ALC260_AUTO)
5701 setup_preset(spec, &alc260_presets[board_config]);
5703 spec->stream_name_analog = "ALC260 Analog";
5704 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5705 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5707 spec->stream_name_digital = "ALC260 Digital";
5708 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5709 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5711 if (!spec->adc_nids && spec->input_mux) {
5712 /* check whether NID 0x04 is valid */
5713 unsigned int wcap = get_wcaps(codec, 0x04);
5714 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5716 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5717 spec->adc_nids = alc260_adc_nids_alt;
5718 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5720 spec->adc_nids = alc260_adc_nids;
5721 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5724 set_capture_mixer(spec);
5726 spec->vmaster_nid = 0x08;
5728 codec->patch_ops = alc_patch_ops;
5729 if (board_config == ALC260_AUTO)
5730 spec->init_hook = alc260_auto_init;
5731 #ifdef CONFIG_SND_HDA_POWER_SAVE
5732 if (!spec->loopback.amplist)
5733 spec->loopback.amplist = alc260_loopbacks;
5743 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5744 * configuration. Each pin widget can choose any input DACs and a mixer.
5745 * Each ADC is connected from a mixer of all inputs. This makes possible
5746 * 6-channel independent captures.
5748 * In addition, an independent DAC for the multi-playback (not used in this
5751 #define ALC882_DIGOUT_NID 0x06
5752 #define ALC882_DIGIN_NID 0x0a
5754 static struct hda_channel_mode alc882_ch_modes[1] = {
5758 static hda_nid_t alc882_dac_nids[4] = {
5759 /* front, rear, clfe, rear_surr */
5760 0x02, 0x03, 0x04, 0x05
5763 /* identical with ALC880 */
5764 #define alc882_adc_nids alc880_adc_nids
5765 #define alc882_adc_nids_alt alc880_adc_nids_alt
5767 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5768 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5771 /* FIXME: should be a matrix-type input source selection */
5773 static struct hda_input_mux alc882_capture_source = {
5777 { "Front Mic", 0x1 },
5785 static struct hda_verb alc882_3ST_ch2_init[] = {
5786 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5787 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5788 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5789 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5796 static struct hda_verb alc882_3ST_ch6_init[] = {
5797 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5798 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5799 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5800 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5801 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5802 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5806 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5807 { 2, alc882_3ST_ch2_init },
5808 { 6, alc882_3ST_ch6_init },
5814 static struct hda_verb alc882_sixstack_ch6_init[] = {
5815 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5816 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5817 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5818 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5825 static struct hda_verb alc882_sixstack_ch8_init[] = {
5826 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5827 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5828 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5829 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5833 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5834 { 6, alc882_sixstack_ch6_init },
5835 { 8, alc882_sixstack_ch8_init },
5839 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5845 static struct hda_verb alc885_mbp_ch2_init[] = {
5846 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5847 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5848 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5855 static struct hda_verb alc885_mbp_ch6_init[] = {
5856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5858 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5859 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5860 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5864 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5865 { 2, alc885_mbp_ch2_init },
5866 { 6, alc885_mbp_ch6_init },
5870 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5871 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5873 static struct snd_kcontrol_new alc882_base_mixer[] = {
5874 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5875 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5876 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5877 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5878 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5879 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5880 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5881 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5882 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5883 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5884 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5885 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5886 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5887 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5888 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5890 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5892 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5893 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5895 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5896 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5900 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5901 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5902 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5903 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5904 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5905 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5906 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5908 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5909 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5910 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5913 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5914 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5915 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5921 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5923 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5924 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5928 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5929 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5930 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5936 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5937 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5938 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5939 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5940 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5941 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5945 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5946 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5948 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5949 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5950 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5952 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5953 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5954 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5955 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5956 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5957 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5958 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5959 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5961 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5965 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5966 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5967 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5974 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5976 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5977 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5981 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5984 .name = "Channel Mode",
5985 .info = alc_ch_mode_info,
5986 .get = alc_ch_mode_get,
5987 .put = alc_ch_mode_put,
5992 static struct hda_verb alc882_init_verbs[] = {
5993 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5994 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5995 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5996 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5998 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6000 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6003 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6004 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6007 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6010 /* Front Pin: output 0 (0x0c) */
6011 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6012 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6013 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6014 /* Rear Pin: output 1 (0x0d) */
6015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6017 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6018 /* CLFE Pin: output 2 (0x0e) */
6019 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6020 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6021 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6022 /* Side Pin: output 3 (0x0f) */
6023 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6024 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6025 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6026 /* Mic (rear) pin: input vref at 80% */
6027 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6028 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6029 /* Front Mic pin: input vref at 80% */
6030 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6031 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6032 /* Line In pin: input */
6033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6034 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6035 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6036 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6037 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6038 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6039 /* CD pin widget for input */
6040 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6042 /* FIXME: use matrix-type input source selection */
6043 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6044 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6046 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6048 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6059 /* ADC1: mute amp left and right */
6060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6061 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6062 /* ADC2: mute amp left and right */
6063 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6064 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6065 /* ADC3: mute amp left and right */
6066 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6067 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6072 static struct hda_verb alc882_eapd_verbs[] = {
6073 /* change to EAPD mode */
6074 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6075 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6080 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6081 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6082 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6084 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6085 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6086 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6087 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6091 static struct hda_verb alc882_macpro_init_verbs[] = {
6092 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6095 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6096 /* Front Pin: output 0 (0x0c) */
6097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6099 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6100 /* Front Mic pin: input vref at 80% */
6101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6103 /* Speaker: output */
6104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6105 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6106 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6107 /* Headphone output (output 0 - 0x0c) */
6108 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6110 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6112 /* FIXME: use matrix-type input source selection */
6113 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6114 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6129 /* ADC1: mute amp left and right */
6130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6131 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6132 /* ADC2: mute amp left and right */
6133 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6134 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6135 /* ADC3: mute amp left and right */
6136 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6137 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6142 /* Macbook Pro rev3 */
6143 static struct hda_verb alc885_mbp3_init_verbs[] = {
6144 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6145 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6147 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6149 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6150 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6151 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6152 /* Front Pin: output 0 (0x0c) */
6153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6154 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6155 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6156 /* HP Pin: output 0 (0x0d) */
6157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6158 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6159 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6160 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6161 /* Mic (rear) pin: input vref at 80% */
6162 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6164 /* Front Mic pin: input vref at 80% */
6165 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6166 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6167 /* Line In pin: use output 1 when in LineOut mode */
6168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6169 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6170 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6172 /* FIXME: use matrix-type input source selection */
6173 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6174 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6175 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6176 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6177 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6178 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6180 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6183 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6187 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6188 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6189 /* ADC1: mute amp left and right */
6190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6191 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6192 /* ADC2: mute amp left and right */
6193 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6194 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6195 /* ADC3: mute amp left and right */
6196 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6197 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6202 /* iMac 24 mixer. */
6203 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6204 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6205 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6209 /* iMac 24 init verbs. */
6210 static struct hda_verb alc885_imac24_init_verbs[] = {
6211 /* Internal speakers: output 0 (0x0c) */
6212 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6214 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6215 /* Internal speakers: output 0 (0x0c) */
6216 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6218 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6219 /* Headphone: output 0 (0x0c) */
6220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6222 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6223 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6224 /* Front Mic: input vref at 80% */
6225 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6226 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6230 /* Toggle speaker-output according to the hp-jack state */
6231 static void alc885_imac24_automute(struct hda_codec *codec)
6233 unsigned int present;
6235 present = snd_hda_codec_read(codec, 0x14, 0,
6236 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6237 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6238 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6239 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6240 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6243 /* Processes unsolicited events. */
6244 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6247 /* Headphone insertion or removal. */
6248 if ((res >> 26) == ALC880_HP_EVENT)
6249 alc885_imac24_automute(codec);
6252 static void alc885_mbp3_automute(struct hda_codec *codec)
6254 unsigned int present;
6256 present = snd_hda_codec_read(codec, 0x15, 0,
6257 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6258 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6259 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6260 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6261 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6264 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6267 /* Headphone insertion or removal. */
6268 if ((res >> 26) == ALC880_HP_EVENT)
6269 alc885_mbp3_automute(codec);
6273 static struct hda_verb alc882_targa_verbs[] = {
6274 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6275 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6277 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6278 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6280 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6281 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6282 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6284 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6285 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6286 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6287 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6291 /* toggle speaker-output according to the hp-jack state */
6292 static void alc882_targa_automute(struct hda_codec *codec)
6294 unsigned int present;
6296 present = snd_hda_codec_read(codec, 0x14, 0,
6297 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6298 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6299 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6300 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6304 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6306 /* Looks like the unsol event is incompatible with the standard
6307 * definition. 4bit tag is placed at 26 bit!
6309 if (((res >> 26) == ALC880_HP_EVENT)) {
6310 alc882_targa_automute(codec);
6314 static struct hda_verb alc882_asus_a7j_verbs[] = {
6315 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6316 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6318 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6319 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6320 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6322 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6323 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6324 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6326 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6327 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6328 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6332 static struct hda_verb alc882_asus_a7m_verbs[] = {
6333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6336 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6338 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6340 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6342 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6344 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6345 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6346 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6350 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6352 unsigned int gpiostate, gpiomask, gpiodir;
6354 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6355 AC_VERB_GET_GPIO_DATA, 0);
6358 gpiostate |= (1 << pin);
6360 gpiostate &= ~(1 << pin);
6362 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6363 AC_VERB_GET_GPIO_MASK, 0);
6364 gpiomask |= (1 << pin);
6366 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6367 AC_VERB_GET_GPIO_DIRECTION, 0);
6368 gpiodir |= (1 << pin);
6371 snd_hda_codec_write(codec, codec->afg, 0,
6372 AC_VERB_SET_GPIO_MASK, gpiomask);
6373 snd_hda_codec_write(codec, codec->afg, 0,
6374 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6378 snd_hda_codec_write(codec, codec->afg, 0,
6379 AC_VERB_SET_GPIO_DATA, gpiostate);
6382 /* set up GPIO at initialization */
6383 static void alc885_macpro_init_hook(struct hda_codec *codec)
6385 alc882_gpio_mute(codec, 0, 0);
6386 alc882_gpio_mute(codec, 1, 0);
6389 /* set up GPIO and update auto-muting at initialization */
6390 static void alc885_imac24_init_hook(struct hda_codec *codec)
6392 alc885_macpro_init_hook(codec);
6393 alc885_imac24_automute(codec);
6397 * generic initialization of ADC, input mixers and output mixers
6399 static struct hda_verb alc882_auto_init_verbs[] = {
6401 * Unmute ADC0-2 and set the default input to mic-in
6403 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6405 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6406 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6407 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6408 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6410 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6412 * Note: PASD motherboards uses the Line In 2 as the input for
6413 * front panel mic (mic 2)
6415 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6416 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6417 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6418 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6423 * Set up output mixers (0x0c - 0x0f)
6425 /* set vol=0 to output mixers */
6426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6427 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6428 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6430 /* set up input amps for analog loopback */
6431 /* Amp Indices: DAC = 0, mixer = 1 */
6432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6435 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6437 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6439 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6440 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6441 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6443 /* FIXME: use matrix-type input source selection */
6444 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6445 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6464 #ifdef CONFIG_SND_HDA_POWER_SAVE
6465 #define alc882_loopbacks alc880_loopbacks
6468 /* pcm configuration: identiacal with ALC880 */
6469 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6470 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6471 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6472 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6475 * configuration and preset
6477 static const char *alc882_models[ALC882_MODEL_LAST] = {
6478 [ALC882_3ST_DIG] = "3stack-dig",
6479 [ALC882_6ST_DIG] = "6stack-dig",
6480 [ALC882_ARIMA] = "arima",
6481 [ALC882_W2JC] = "w2jc",
6482 [ALC882_TARGA] = "targa",
6483 [ALC882_ASUS_A7J] = "asus-a7j",
6484 [ALC882_ASUS_A7M] = "asus-a7m",
6485 [ALC885_MACPRO] = "macpro",
6486 [ALC885_MBP3] = "mbp3",
6487 [ALC885_IMAC24] = "imac24",
6488 [ALC882_AUTO] = "auto",
6491 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6492 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6493 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6494 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6495 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6496 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6497 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6498 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6499 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6500 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6501 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6502 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6503 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6507 static struct alc_config_preset alc882_presets[] = {
6508 [ALC882_3ST_DIG] = {
6509 .mixers = { alc882_base_mixer },
6510 .init_verbs = { alc882_init_verbs },
6511 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6512 .dac_nids = alc882_dac_nids,
6513 .dig_out_nid = ALC882_DIGOUT_NID,
6514 .dig_in_nid = ALC882_DIGIN_NID,
6515 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6516 .channel_mode = alc882_ch_modes,
6518 .input_mux = &alc882_capture_source,
6520 [ALC882_6ST_DIG] = {
6521 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6522 .init_verbs = { alc882_init_verbs },
6523 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6524 .dac_nids = alc882_dac_nids,
6525 .dig_out_nid = ALC882_DIGOUT_NID,
6526 .dig_in_nid = ALC882_DIGIN_NID,
6527 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6528 .channel_mode = alc882_sixstack_modes,
6529 .input_mux = &alc882_capture_source,
6532 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6533 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6534 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6535 .dac_nids = alc882_dac_nids,
6536 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6537 .channel_mode = alc882_sixstack_modes,
6538 .input_mux = &alc882_capture_source,
6541 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6542 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6543 alc880_gpio1_init_verbs },
6544 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6545 .dac_nids = alc882_dac_nids,
6546 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6547 .channel_mode = alc880_threestack_modes,
6549 .input_mux = &alc882_capture_source,
6550 .dig_out_nid = ALC882_DIGOUT_NID,
6553 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6554 .init_verbs = { alc885_mbp3_init_verbs,
6555 alc880_gpio1_init_verbs },
6556 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6557 .dac_nids = alc882_dac_nids,
6558 .channel_mode = alc885_mbp_6ch_modes,
6559 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6560 .input_mux = &alc882_capture_source,
6561 .dig_out_nid = ALC882_DIGOUT_NID,
6562 .dig_in_nid = ALC882_DIGIN_NID,
6563 .unsol_event = alc885_mbp3_unsol_event,
6564 .init_hook = alc885_mbp3_automute,
6567 .mixers = { alc882_macpro_mixer },
6568 .init_verbs = { alc882_macpro_init_verbs },
6569 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6570 .dac_nids = alc882_dac_nids,
6571 .dig_out_nid = ALC882_DIGOUT_NID,
6572 .dig_in_nid = ALC882_DIGIN_NID,
6573 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6574 .channel_mode = alc882_ch_modes,
6575 .input_mux = &alc882_capture_source,
6576 .init_hook = alc885_macpro_init_hook,
6579 .mixers = { alc885_imac24_mixer },
6580 .init_verbs = { alc885_imac24_init_verbs },
6581 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6582 .dac_nids = alc882_dac_nids,
6583 .dig_out_nid = ALC882_DIGOUT_NID,
6584 .dig_in_nid = ALC882_DIGIN_NID,
6585 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6586 .channel_mode = alc882_ch_modes,
6587 .input_mux = &alc882_capture_source,
6588 .unsol_event = alc885_imac24_unsol_event,
6589 .init_hook = alc885_imac24_init_hook,
6592 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6593 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6594 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6595 .dac_nids = alc882_dac_nids,
6596 .dig_out_nid = ALC882_DIGOUT_NID,
6597 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6598 .adc_nids = alc882_adc_nids,
6599 .capsrc_nids = alc882_capsrc_nids,
6600 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6601 .channel_mode = alc882_3ST_6ch_modes,
6603 .input_mux = &alc882_capture_source,
6604 .unsol_event = alc882_targa_unsol_event,
6605 .init_hook = alc882_targa_automute,
6607 [ALC882_ASUS_A7J] = {
6608 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6609 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6610 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6611 .dac_nids = alc882_dac_nids,
6612 .dig_out_nid = ALC882_DIGOUT_NID,
6613 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6614 .adc_nids = alc882_adc_nids,
6615 .capsrc_nids = alc882_capsrc_nids,
6616 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6617 .channel_mode = alc882_3ST_6ch_modes,
6619 .input_mux = &alc882_capture_source,
6621 [ALC882_ASUS_A7M] = {
6622 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6623 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6624 alc880_gpio1_init_verbs,
6625 alc882_asus_a7m_verbs },
6626 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6627 .dac_nids = alc882_dac_nids,
6628 .dig_out_nid = ALC882_DIGOUT_NID,
6629 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6630 .channel_mode = alc880_threestack_modes,
6632 .input_mux = &alc882_capture_source,
6641 PINFIX_ABIT_AW9D_MAX
6644 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6645 { 0x15, 0x01080104 }, /* side */
6646 { 0x16, 0x01011012 }, /* rear */
6647 { 0x17, 0x01016011 }, /* clfe */
6651 static const struct alc_pincfg *alc882_pin_fixes[] = {
6652 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6655 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6656 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6661 * BIOS auto configuration
6663 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6664 hda_nid_t nid, int pin_type,
6668 struct alc_spec *spec = codec->spec;
6671 alc_set_pin_output(codec, nid, pin_type);
6672 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6675 idx = spec->multiout.dac_nids[dac_idx] - 2;
6676 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6680 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6682 struct alc_spec *spec = codec->spec;
6685 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6686 for (i = 0; i <= HDA_SIDE; i++) {
6687 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6688 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6690 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6695 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6697 struct alc_spec *spec = codec->spec;
6700 pin = spec->autocfg.hp_pins[0];
6701 if (pin) /* connect to front */
6703 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6704 pin = spec->autocfg.speaker_pins[0];
6706 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6709 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6710 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6712 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6714 struct alc_spec *spec = codec->spec;
6717 for (i = 0; i < AUTO_PIN_LAST; i++) {
6718 hda_nid_t nid = spec->autocfg.input_pins[i];
6723 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6724 unsigned int pincap;
6725 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6726 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6730 snd_hda_codec_write(codec, nid, 0,
6731 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6732 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6733 snd_hda_codec_write(codec, nid, 0,
6734 AC_VERB_SET_AMP_GAIN_MUTE,
6739 static void alc882_auto_init_input_src(struct hda_codec *codec)
6741 struct alc_spec *spec = codec->spec;
6742 const struct hda_input_mux *imux = spec->input_mux;
6745 for (c = 0; c < spec->num_adc_nids; c++) {
6746 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6747 hda_nid_t nid = spec->capsrc_nids[c];
6748 int conns, mute, idx, item;
6750 conns = snd_hda_get_connections(codec, nid, conn_list,
6751 ARRAY_SIZE(conn_list));
6754 for (idx = 0; idx < conns; idx++) {
6755 /* if the current connection is the selected one,
6756 * unmute it as default - otherwise mute it
6758 mute = AMP_IN_MUTE(idx);
6759 for (item = 0; item < imux->num_items; item++) {
6760 if (imux->items[item].index == idx) {
6761 if (spec->cur_mux[c] == item)
6762 mute = AMP_IN_UNMUTE(idx);
6766 snd_hda_codec_write(codec, nid, 0,
6767 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6772 /* add mic boosts if needed */
6773 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6775 struct alc_spec *spec = codec->spec;
6779 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6780 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6781 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6783 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6787 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6788 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6789 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6791 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6798 /* almost identical with ALC880 parser... */
6799 static int alc882_parse_auto_config(struct hda_codec *codec)
6801 struct alc_spec *spec = codec->spec;
6802 int err = alc880_parse_auto_config(codec);
6807 return 0; /* no config found */
6809 err = alc_auto_add_mic_boost(codec);
6813 /* hack - override the init verbs */
6814 spec->init_verbs[0] = alc882_auto_init_verbs;
6816 return 1; /* config found */
6819 /* additional initialization for auto-configuration model */
6820 static void alc882_auto_init(struct hda_codec *codec)
6822 struct alc_spec *spec = codec->spec;
6823 alc882_auto_init_multi_out(codec);
6824 alc882_auto_init_hp_out(codec);
6825 alc882_auto_init_analog_input(codec);
6826 alc882_auto_init_input_src(codec);
6827 if (spec->unsol_event)
6828 alc_inithook(codec);
6831 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6833 static int patch_alc882(struct hda_codec *codec)
6835 struct alc_spec *spec;
6836 int err, board_config;
6838 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6844 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6848 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6849 /* Pick up systems that don't supply PCI SSID */
6850 switch (codec->subsystem_id) {
6851 case 0x106b0c00: /* Mac Pro */
6852 board_config = ALC885_MACPRO;
6854 case 0x106b1000: /* iMac 24 */
6855 case 0x106b2800: /* AppleTV */
6856 board_config = ALC885_IMAC24;
6858 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6859 case 0x106b00a4: /* MacbookPro4,1 */
6860 case 0x106b2c00: /* Macbook Pro rev3 */
6861 case 0x106b3600: /* Macbook 3.1 */
6862 board_config = ALC885_MBP3;
6865 /* ALC889A is handled better as ALC888-compatible */
6866 if (codec->revision_id == 0x100101 ||
6867 codec->revision_id == 0x100103) {
6869 return patch_alc883(codec);
6871 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6872 "trying auto-probe from BIOS...\n");
6873 board_config = ALC882_AUTO;
6877 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6879 if (board_config == ALC882_AUTO) {
6880 /* automatic parse from the BIOS config */
6881 err = alc882_parse_auto_config(codec);
6887 "hda_codec: Cannot set up configuration "
6888 "from BIOS. Using base mode...\n");
6889 board_config = ALC882_3ST_DIG;
6893 if (board_config != ALC882_AUTO)
6894 setup_preset(spec, &alc882_presets[board_config]);
6896 if (codec->vendor_id == 0x10ec0885) {
6897 spec->stream_name_analog = "ALC885 Analog";
6898 spec->stream_name_digital = "ALC885 Digital";
6900 spec->stream_name_analog = "ALC882 Analog";
6901 spec->stream_name_digital = "ALC882 Digital";
6904 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6905 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6906 /* FIXME: setup DAC5 */
6907 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6908 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6910 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6911 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6913 spec->is_mix_capture = 1; /* matrix-style capture */
6914 if (!spec->adc_nids && spec->input_mux) {
6915 /* check whether NID 0x07 is valid */
6916 unsigned int wcap = get_wcaps(codec, 0x07);
6918 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6919 if (wcap != AC_WID_AUD_IN) {
6920 spec->adc_nids = alc882_adc_nids_alt;
6921 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6922 spec->capsrc_nids = alc882_capsrc_nids_alt;
6924 spec->adc_nids = alc882_adc_nids;
6925 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6926 spec->capsrc_nids = alc882_capsrc_nids;
6929 set_capture_mixer(spec);
6931 spec->vmaster_nid = 0x0c;
6933 codec->patch_ops = alc_patch_ops;
6934 if (board_config == ALC882_AUTO)
6935 spec->init_hook = alc882_auto_init;
6936 #ifdef CONFIG_SND_HDA_POWER_SAVE
6937 if (!spec->loopback.amplist)
6938 spec->loopback.amplist = alc882_loopbacks;
6947 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6948 * configuration. Each pin widget can choose any input DACs and a mixer.
6949 * Each ADC is connected from a mixer of all inputs. This makes possible
6950 * 6-channel independent captures.
6952 * In addition, an independent DAC for the multi-playback (not used in this
6955 #define ALC883_DIGOUT_NID 0x06
6956 #define ALC883_DIGIN_NID 0x0a
6958 #define ALC1200_DIGOUT_NID 0x10
6960 static hda_nid_t alc883_dac_nids[4] = {
6961 /* front, rear, clfe, rear_surr */
6962 0x02, 0x03, 0x04, 0x05
6965 static hda_nid_t alc883_adc_nids[2] = {
6970 static hda_nid_t alc883_adc_nids_alt[1] = {
6975 static hda_nid_t alc883_adc_nids_rev[2] = {
6980 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6982 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6985 /* FIXME: should be a matrix-type input source selection */
6987 static struct hda_input_mux alc883_capture_source = {
6991 { "Front Mic", 0x1 },
6997 static struct hda_input_mux alc883_3stack_6ch_intel = {
7001 { "Front Mic", 0x0 },
7007 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7015 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7025 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7033 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7037 { "Front Mic", 0x1 },
7042 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7053 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7060 static struct hda_verb alc883_3ST_ch2_init[] = {
7061 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7062 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7063 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7064 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7071 static struct hda_verb alc883_3ST_ch4_init[] = {
7072 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7073 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7074 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7075 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7076 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7083 static struct hda_verb alc883_3ST_ch6_init[] = {
7084 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7085 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7086 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7087 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7088 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7089 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7093 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7094 { 2, alc883_3ST_ch2_init },
7095 { 4, alc883_3ST_ch4_init },
7096 { 6, alc883_3ST_ch6_init },
7102 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7103 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7104 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7105 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7106 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7113 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7114 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7115 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7116 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7117 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7118 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7125 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7126 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7127 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7128 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7129 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7130 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7131 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7135 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7136 { 2, alc883_3ST_ch2_intel_init },
7137 { 4, alc883_3ST_ch4_intel_init },
7138 { 6, alc883_3ST_ch6_intel_init },
7144 static struct hda_verb alc883_sixstack_ch6_init[] = {
7145 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7146 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7147 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7148 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7155 static struct hda_verb alc883_sixstack_ch8_init[] = {
7156 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7157 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7158 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7159 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7163 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7164 { 6, alc883_sixstack_ch6_init },
7165 { 8, alc883_sixstack_ch8_init },
7168 static struct hda_verb alc883_medion_eapd_verbs[] = {
7169 /* eanable EAPD on medion laptop */
7170 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7171 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7175 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7176 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7179 static struct snd_kcontrol_new alc883_base_mixer[] = {
7180 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7181 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7182 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7183 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7184 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7185 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7186 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7187 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7188 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7189 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7190 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7191 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7192 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7193 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7194 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7196 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7199 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7200 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7201 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7202 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7206 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7207 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7208 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7215 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7217 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7218 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7219 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7223 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7225 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7226 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7227 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7229 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7230 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7231 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7232 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7233 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7237 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7238 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7239 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7240 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7241 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7245 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7246 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7247 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7251 static struct snd_kcontrol_new alc883_3ST_2ch_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_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7255 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7256 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7257 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7258 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7260 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7261 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7262 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7263 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7264 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7265 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7266 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7270 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7272 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7273 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7274 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7275 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7276 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7277 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7278 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7279 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7288 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7289 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7290 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7291 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7295 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7296 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7297 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7298 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7299 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7300 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7302 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7303 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7304 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7306 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7307 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7308 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7309 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7311 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7313 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7314 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7315 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7316 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7317 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7321 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7322 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7323 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7324 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7325 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7326 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7327 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7328 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7329 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7336 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7338 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7339 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7340 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7341 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7342 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7346 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7347 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7348 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7349 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7350 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7351 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7352 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7353 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7354 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7355 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7356 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7357 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7361 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7362 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7366 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7367 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7368 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7369 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7373 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7375 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7376 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7377 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7381 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7382 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7383 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7384 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7385 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7386 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7388 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7393 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7395 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7396 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7397 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7398 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7399 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7401 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7402 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7406 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7407 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7409 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7410 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7411 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7413 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7419 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7420 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7421 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7426 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7431 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7432 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7433 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7434 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7435 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7436 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7437 0x0d, 1, 0x0, HDA_OUTPUT),
7438 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7439 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7440 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7441 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7442 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7443 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7444 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7445 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7446 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7447 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7448 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7450 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7451 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7452 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7454 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7458 static struct hda_bind_ctls alc883_bind_cap_vol = {
7459 .ops = &snd_hda_bind_vol,
7461 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7462 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7467 static struct hda_bind_ctls alc883_bind_cap_switch = {
7468 .ops = &snd_hda_bind_sw,
7470 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7471 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7476 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7478 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7479 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7480 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7481 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7483 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7488 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7489 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7490 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7493 /* .name = "Capture Source", */
7494 .name = "Input Source",
7496 .info = alc_mux_enum_info,
7497 .get = alc_mux_enum_get,
7498 .put = alc_mux_enum_put,
7503 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7505 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7506 .name = "Channel Mode",
7507 .info = alc_ch_mode_info,
7508 .get = alc_ch_mode_get,
7509 .put = alc_ch_mode_put,
7514 static struct hda_verb alc883_init_verbs[] = {
7515 /* ADC1: mute amp left and right */
7516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7517 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7518 /* ADC2: mute amp left and right */
7519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7520 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7521 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7527 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7528 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7530 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7531 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7532 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7534 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7535 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7536 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7538 /* mute analog input loopbacks */
7539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7545 /* Front Pin: output 0 (0x0c) */
7546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7547 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7548 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7549 /* Rear Pin: output 1 (0x0d) */
7550 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7551 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7552 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7553 /* CLFE Pin: output 2 (0x0e) */
7554 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7555 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7556 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7557 /* Side Pin: output 3 (0x0f) */
7558 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7559 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7560 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7561 /* Mic (rear) pin: input vref at 80% */
7562 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7563 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7564 /* Front Mic pin: input vref at 80% */
7565 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7567 /* Line In pin: input */
7568 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7569 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7570 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7571 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7572 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7573 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7574 /* CD pin widget for input */
7575 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7577 /* FIXME: use matrix-type input source selection */
7578 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7592 /* toggle speaker-output according to the hp-jack state */
7593 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7595 unsigned int present;
7597 present = snd_hda_codec_read(codec, 0x15, 0,
7598 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7599 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7600 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7601 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7602 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7605 /* auto-toggle front mic */
7607 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7609 unsigned int present;
7612 present = snd_hda_codec_read(codec, 0x18, 0,
7613 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7614 bits = present ? HDA_AMP_MUTE : 0;
7615 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7619 static void alc883_mitac_automute(struct hda_codec *codec)
7621 alc883_mitac_hp_automute(codec);
7622 /* alc883_mitac_mic_automute(codec); */
7625 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7628 switch (res >> 26) {
7629 case ALC880_HP_EVENT:
7630 alc883_mitac_hp_automute(codec);
7632 case ALC880_MIC_EVENT:
7633 /* alc883_mitac_mic_automute(codec); */
7638 static struct hda_verb alc883_mitac_verbs[] = {
7640 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7643 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7644 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7646 /* enable unsolicited event */
7647 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7648 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7653 static struct hda_verb alc883_clevo_m720_verbs[] = {
7655 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7656 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7658 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7659 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 /* enable unsolicited event */
7662 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7663 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7668 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7670 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7671 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7673 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7676 /* enable unsolicited event */
7677 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7682 static struct hda_verb alc883_tagra_verbs[] = {
7683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7686 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7687 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7689 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7690 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7691 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7694 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7695 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7696 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7701 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7702 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7703 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7704 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7708 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7709 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7710 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7711 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7716 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7719 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7720 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7721 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7725 static struct hda_verb alc883_haier_w66_verbs[] = {
7726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7731 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7732 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7733 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7738 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7743 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7744 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7745 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7746 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7750 static struct hda_verb alc888_3st_hp_verbs[] = {
7751 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7752 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7753 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7757 static struct hda_verb alc888_6st_dell_verbs[] = {
7758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7762 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7763 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7764 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7765 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7766 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7770 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7771 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7772 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7773 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7774 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7778 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7779 { 2, alc888_3st_hp_2ch_init },
7780 { 6, alc888_3st_hp_6ch_init },
7783 /* toggle front-jack and RCA according to the hp-jack state */
7784 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7786 unsigned int present;
7788 present = snd_hda_codec_read(codec, 0x1b, 0,
7789 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7790 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7791 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7792 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7793 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7796 /* toggle RCA according to the front-jack state */
7797 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7799 unsigned int present;
7801 present = snd_hda_codec_read(codec, 0x14, 0,
7802 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7803 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7804 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7807 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7810 if ((res >> 26) == ALC880_HP_EVENT)
7811 alc888_lenovo_ms7195_front_automute(codec);
7812 if ((res >> 26) == ALC880_FRONT_EVENT)
7813 alc888_lenovo_ms7195_rca_automute(codec);
7816 static struct hda_verb alc883_medion_md2_verbs[] = {
7817 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7818 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7822 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7826 /* toggle speaker-output according to the hp-jack state */
7827 static void alc883_medion_md2_automute(struct hda_codec *codec)
7829 unsigned int present;
7831 present = snd_hda_codec_read(codec, 0x14, 0,
7832 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7833 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7834 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7837 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7840 if ((res >> 26) == ALC880_HP_EVENT)
7841 alc883_medion_md2_automute(codec);
7844 /* toggle speaker-output according to the hp-jack state */
7845 static void alc883_tagra_automute(struct hda_codec *codec)
7847 unsigned int present;
7850 present = snd_hda_codec_read(codec, 0x14, 0,
7851 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7852 bits = present ? HDA_AMP_MUTE : 0;
7853 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7854 HDA_AMP_MUTE, bits);
7855 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7859 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7861 if ((res >> 26) == ALC880_HP_EVENT)
7862 alc883_tagra_automute(codec);
7865 /* toggle speaker-output according to the hp-jack state */
7866 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7868 unsigned int present;
7871 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7872 & AC_PINSENSE_PRESENCE;
7873 bits = present ? HDA_AMP_MUTE : 0;
7874 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7875 HDA_AMP_MUTE, bits);
7878 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7880 unsigned int present;
7882 present = snd_hda_codec_read(codec, 0x18, 0,
7883 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7884 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7885 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7888 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7890 alc883_clevo_m720_hp_automute(codec);
7891 alc883_clevo_m720_mic_automute(codec);
7894 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7897 switch (res >> 26) {
7898 case ALC880_HP_EVENT:
7899 alc883_clevo_m720_hp_automute(codec);
7901 case ALC880_MIC_EVENT:
7902 alc883_clevo_m720_mic_automute(codec);
7907 /* toggle speaker-output according to the hp-jack state */
7908 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7910 unsigned int present;
7913 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7914 & AC_PINSENSE_PRESENCE;
7915 bits = present ? HDA_AMP_MUTE : 0;
7916 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7917 HDA_AMP_MUTE, bits);
7920 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7923 if ((res >> 26) == ALC880_HP_EVENT)
7924 alc883_2ch_fujitsu_pi2515_automute(codec);
7927 static void alc883_haier_w66_automute(struct hda_codec *codec)
7929 unsigned int present;
7932 present = snd_hda_codec_read(codec, 0x1b, 0,
7933 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7934 bits = present ? 0x80 : 0;
7935 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7939 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7942 if ((res >> 26) == ALC880_HP_EVENT)
7943 alc883_haier_w66_automute(codec);
7946 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7948 unsigned int present;
7951 present = snd_hda_codec_read(codec, 0x14, 0,
7952 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7953 bits = present ? HDA_AMP_MUTE : 0;
7954 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7955 HDA_AMP_MUTE, bits);
7958 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7960 unsigned int present;
7963 present = snd_hda_codec_read(codec, 0x1b, 0,
7964 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7965 bits = present ? HDA_AMP_MUTE : 0;
7966 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7967 HDA_AMP_MUTE, bits);
7968 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7969 HDA_AMP_MUTE, bits);
7972 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7975 if ((res >> 26) == ALC880_HP_EVENT)
7976 alc883_lenovo_101e_all_automute(codec);
7977 if ((res >> 26) == ALC880_FRONT_EVENT)
7978 alc883_lenovo_101e_ispeaker_automute(codec);
7981 /* toggle speaker-output according to the hp-jack state */
7982 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7984 unsigned int present;
7986 present = snd_hda_codec_read(codec, 0x14, 0,
7987 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7988 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7989 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7990 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7991 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7994 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7997 if ((res >> 26) == ALC880_HP_EVENT)
7998 alc883_acer_aspire_automute(codec);
8001 static struct hda_verb alc883_acer_eapd_verbs[] = {
8002 /* HP Pin: output 0 (0x0c) */
8003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8004 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8005 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8006 /* Front Pin: output 0 (0x0c) */
8007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8009 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8010 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8011 /* eanable EAPD on medion laptop */
8012 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8013 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8014 /* enable unsolicited event */
8015 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8019 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8021 unsigned int present;
8023 present = snd_hda_codec_read(codec, 0x1b, 0,
8024 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8025 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8026 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8027 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8028 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8029 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8030 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8031 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8032 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8035 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8038 switch (res >> 26) {
8039 case ALC880_HP_EVENT:
8040 printk("hp_event\n");
8041 alc888_6st_dell_front_automute(codec);
8046 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8049 unsigned int present;
8051 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8052 present = snd_hda_codec_read(codec, 0x1b, 0,
8053 AC_VERB_GET_PIN_SENSE, 0);
8054 present = (present & 0x80000000) != 0;
8056 /* mute internal speaker */
8057 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8058 HDA_AMP_MUTE, HDA_AMP_MUTE);
8059 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8060 HDA_AMP_MUTE, HDA_AMP_MUTE);
8061 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8062 HDA_AMP_MUTE, HDA_AMP_MUTE);
8063 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8064 HDA_AMP_MUTE, HDA_AMP_MUTE);
8065 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8066 HDA_AMP_MUTE, HDA_AMP_MUTE);
8068 /* unmute internal speaker if necessary */
8069 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8071 HDA_AMP_MUTE, mute);
8072 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8073 HDA_AMP_MUTE, mute);
8074 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8075 HDA_AMP_MUTE, mute);
8076 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8077 HDA_AMP_MUTE, mute);
8078 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8079 HDA_AMP_MUTE, mute);
8083 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8086 if ((res >> 26) == ALC880_HP_EVENT)
8087 alc888_lenovo_sky_front_automute(codec);
8091 * generic initialization of ADC, input mixers and output mixers
8093 static struct hda_verb alc883_auto_init_verbs[] = {
8095 * Unmute ADC0-2 and set the default input to mic-in
8097 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8098 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8099 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8100 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8102 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8104 * Note: PASD motherboards uses the Line In 2 as the input for
8105 * front panel mic (mic 2)
8107 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8109 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8110 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8111 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8115 * Set up output mixers (0x0c - 0x0f)
8117 /* set vol=0 to output mixers */
8118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8122 /* set up input amps for analog loopback */
8123 /* Amp Indices: DAC = 0, mixer = 1 */
8124 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8126 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8127 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8128 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8129 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8132 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8133 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8135 /* FIXME: use matrix-type input source selection */
8136 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8141 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8147 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8153 static struct hda_verb alc888_asus_m90v_verbs[] = {
8154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8157 /* enable unsolicited event */
8158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8163 static void alc883_nb_mic_automute(struct hda_codec *codec)
8165 unsigned int present;
8167 present = snd_hda_codec_read(codec, 0x18, 0,
8168 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8169 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8170 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8171 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8172 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8175 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8177 unsigned int present;
8180 present = snd_hda_codec_read(codec, 0x1b, 0,
8181 AC_VERB_GET_PIN_SENSE, 0)
8182 & AC_PINSENSE_PRESENCE;
8183 bits = present ? 0 : PIN_OUT;
8184 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8186 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8188 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8192 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8195 switch (res >> 26) {
8196 case ALC880_HP_EVENT:
8197 alc883_M90V_speaker_automute(codec);
8199 case ALC880_MIC_EVENT:
8200 alc883_nb_mic_automute(codec);
8205 static void alc883_mode2_inithook(struct hda_codec *codec)
8207 alc883_M90V_speaker_automute(codec);
8208 alc883_nb_mic_automute(codec);
8211 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8213 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8217 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8218 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8219 /* enable unsolicited event */
8220 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8224 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8226 unsigned int present;
8229 present = snd_hda_codec_read(codec, 0x14, 0,
8230 AC_VERB_GET_PIN_SENSE, 0)
8231 & AC_PINSENSE_PRESENCE;
8232 bits = present ? 0 : PIN_OUT;
8233 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8237 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8240 switch (res >> 26) {
8241 case ALC880_HP_EVENT:
8242 alc883_eee1601_speaker_automute(codec);
8247 static void alc883_eee1601_inithook(struct hda_codec *codec)
8249 alc883_eee1601_speaker_automute(codec);
8252 #ifdef CONFIG_SND_HDA_POWER_SAVE
8253 #define alc883_loopbacks alc880_loopbacks
8256 /* pcm configuration: identiacal with ALC880 */
8257 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8258 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8259 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8260 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8261 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8264 * configuration and preset
8266 static const char *alc883_models[ALC883_MODEL_LAST] = {
8267 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8268 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8269 [ALC883_3ST_6ch] = "3stack-6ch",
8270 [ALC883_6ST_DIG] = "6stack-dig",
8271 [ALC883_TARGA_DIG] = "targa-dig",
8272 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8273 [ALC883_ACER] = "acer",
8274 [ALC883_ACER_ASPIRE] = "acer-aspire",
8275 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8276 [ALC883_MEDION] = "medion",
8277 [ALC883_MEDION_MD2] = "medion-md2",
8278 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8279 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8280 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8281 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8282 [ALC888_LENOVO_SKY] = "lenovo-sky",
8283 [ALC883_HAIER_W66] = "haier-w66",
8284 [ALC888_3ST_HP] = "3stack-hp",
8285 [ALC888_6ST_DELL] = "6stack-dell",
8286 [ALC883_MITAC] = "mitac",
8287 [ALC883_CLEVO_M720] = "clevo-m720",
8288 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8289 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8290 [ALC1200_ASUS_P5Q] = "asus-p5q",
8291 [ALC883_AUTO] = "auto",
8294 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8295 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8296 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8297 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8298 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8299 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8300 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8301 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8302 ALC888_ACER_ASPIRE_4930G),
8303 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8304 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8305 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8306 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8307 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8308 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8309 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8310 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8311 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8312 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8313 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8314 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8315 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8316 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8317 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8318 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8319 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8320 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8321 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8322 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8323 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8324 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8325 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8326 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8327 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8328 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8329 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8330 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8331 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8332 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8333 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8334 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8335 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8336 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8337 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8338 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8339 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8340 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8341 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8342 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8343 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8344 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8345 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8346 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8347 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8348 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8349 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8350 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8351 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8352 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8353 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8354 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8355 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8356 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8357 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8358 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8359 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8360 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8364 static struct alc_config_preset alc883_presets[] = {
8365 [ALC883_3ST_2ch_DIG] = {
8366 .mixers = { alc883_3ST_2ch_mixer },
8367 .init_verbs = { alc883_init_verbs },
8368 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8369 .dac_nids = alc883_dac_nids,
8370 .dig_out_nid = ALC883_DIGOUT_NID,
8371 .dig_in_nid = ALC883_DIGIN_NID,
8372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8373 .channel_mode = alc883_3ST_2ch_modes,
8374 .input_mux = &alc883_capture_source,
8376 [ALC883_3ST_6ch_DIG] = {
8377 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8378 .init_verbs = { alc883_init_verbs },
8379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8380 .dac_nids = alc883_dac_nids,
8381 .dig_out_nid = ALC883_DIGOUT_NID,
8382 .dig_in_nid = ALC883_DIGIN_NID,
8383 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8384 .channel_mode = alc883_3ST_6ch_modes,
8386 .input_mux = &alc883_capture_source,
8388 [ALC883_3ST_6ch] = {
8389 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8390 .init_verbs = { alc883_init_verbs },
8391 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8392 .dac_nids = alc883_dac_nids,
8393 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8394 .channel_mode = alc883_3ST_6ch_modes,
8396 .input_mux = &alc883_capture_source,
8398 [ALC883_3ST_6ch_INTEL] = {
8399 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8400 .init_verbs = { alc883_init_verbs },
8401 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8402 .dac_nids = alc883_dac_nids,
8403 .dig_out_nid = ALC883_DIGOUT_NID,
8404 .dig_in_nid = ALC883_DIGIN_NID,
8405 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8406 .channel_mode = alc883_3ST_6ch_intel_modes,
8408 .input_mux = &alc883_3stack_6ch_intel,
8410 [ALC883_6ST_DIG] = {
8411 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8412 .init_verbs = { alc883_init_verbs },
8413 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8414 .dac_nids = alc883_dac_nids,
8415 .dig_out_nid = ALC883_DIGOUT_NID,
8416 .dig_in_nid = ALC883_DIGIN_NID,
8417 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8418 .channel_mode = alc883_sixstack_modes,
8419 .input_mux = &alc883_capture_source,
8421 [ALC883_TARGA_DIG] = {
8422 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8423 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8424 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8425 .dac_nids = alc883_dac_nids,
8426 .dig_out_nid = ALC883_DIGOUT_NID,
8427 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8428 .channel_mode = alc883_3ST_6ch_modes,
8430 .input_mux = &alc883_capture_source,
8431 .unsol_event = alc883_tagra_unsol_event,
8432 .init_hook = alc883_tagra_automute,
8434 [ALC883_TARGA_2ch_DIG] = {
8435 .mixers = { alc883_tagra_2ch_mixer},
8436 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8437 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8438 .dac_nids = alc883_dac_nids,
8439 .adc_nids = alc883_adc_nids_alt,
8440 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8441 .dig_out_nid = ALC883_DIGOUT_NID,
8442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8443 .channel_mode = alc883_3ST_2ch_modes,
8444 .input_mux = &alc883_capture_source,
8445 .unsol_event = alc883_tagra_unsol_event,
8446 .init_hook = alc883_tagra_automute,
8449 .mixers = { alc883_base_mixer },
8450 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8451 * and the headphone jack. Turn this on and rely on the
8452 * standard mute methods whenever the user wants to turn
8453 * these outputs off.
8455 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8457 .dac_nids = alc883_dac_nids,
8458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8459 .channel_mode = alc883_3ST_2ch_modes,
8460 .input_mux = &alc883_capture_source,
8462 [ALC883_ACER_ASPIRE] = {
8463 .mixers = { alc883_acer_aspire_mixer },
8464 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8465 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8466 .dac_nids = alc883_dac_nids,
8467 .dig_out_nid = ALC883_DIGOUT_NID,
8468 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8469 .channel_mode = alc883_3ST_2ch_modes,
8470 .input_mux = &alc883_capture_source,
8471 .unsol_event = alc883_acer_aspire_unsol_event,
8472 .init_hook = alc883_acer_aspire_automute,
8474 [ALC888_ACER_ASPIRE_4930G] = {
8475 .mixers = { alc888_acer_aspire_4930g_mixer,
8476 alc883_chmode_mixer },
8477 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8478 alc888_acer_aspire_4930g_verbs },
8479 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8480 .dac_nids = alc883_dac_nids,
8481 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8482 .adc_nids = alc883_adc_nids_rev,
8483 .capsrc_nids = alc883_capsrc_nids_rev,
8484 .dig_out_nid = ALC883_DIGOUT_NID,
8485 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8486 .channel_mode = alc883_3ST_6ch_modes,
8489 ARRAY_SIZE(alc888_acer_aspire_4930g_capture_source),
8490 .input_mux = alc888_acer_aspire_4930g_capture_source,
8491 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8492 .init_hook = alc888_acer_aspire_4930g_automute,
8495 .mixers = { alc883_fivestack_mixer,
8496 alc883_chmode_mixer },
8497 .init_verbs = { alc883_init_verbs,
8498 alc883_medion_eapd_verbs },
8499 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8500 .dac_nids = alc883_dac_nids,
8501 .adc_nids = alc883_adc_nids_alt,
8502 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8503 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8504 .channel_mode = alc883_sixstack_modes,
8505 .input_mux = &alc883_capture_source,
8507 [ALC883_MEDION_MD2] = {
8508 .mixers = { alc883_medion_md2_mixer},
8509 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8510 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8511 .dac_nids = alc883_dac_nids,
8512 .dig_out_nid = ALC883_DIGOUT_NID,
8513 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8514 .channel_mode = alc883_3ST_2ch_modes,
8515 .input_mux = &alc883_capture_source,
8516 .unsol_event = alc883_medion_md2_unsol_event,
8517 .init_hook = alc883_medion_md2_automute,
8519 [ALC883_LAPTOP_EAPD] = {
8520 .mixers = { alc883_base_mixer },
8521 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8522 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8523 .dac_nids = alc883_dac_nids,
8524 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8525 .channel_mode = alc883_3ST_2ch_modes,
8526 .input_mux = &alc883_capture_source,
8528 [ALC883_CLEVO_M720] = {
8529 .mixers = { alc883_clevo_m720_mixer },
8530 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8531 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8532 .dac_nids = alc883_dac_nids,
8533 .dig_out_nid = ALC883_DIGOUT_NID,
8534 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8535 .channel_mode = alc883_3ST_2ch_modes,
8536 .input_mux = &alc883_capture_source,
8537 .unsol_event = alc883_clevo_m720_unsol_event,
8538 .init_hook = alc883_clevo_m720_automute,
8540 [ALC883_LENOVO_101E_2ch] = {
8541 .mixers = { alc883_lenovo_101e_2ch_mixer},
8542 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8543 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8544 .dac_nids = alc883_dac_nids,
8545 .adc_nids = alc883_adc_nids_alt,
8546 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8547 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8548 .channel_mode = alc883_3ST_2ch_modes,
8549 .input_mux = &alc883_lenovo_101e_capture_source,
8550 .unsol_event = alc883_lenovo_101e_unsol_event,
8551 .init_hook = alc883_lenovo_101e_all_automute,
8553 [ALC883_LENOVO_NB0763] = {
8554 .mixers = { alc883_lenovo_nb0763_mixer },
8555 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8556 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8557 .dac_nids = alc883_dac_nids,
8558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8559 .channel_mode = alc883_3ST_2ch_modes,
8561 .input_mux = &alc883_lenovo_nb0763_capture_source,
8562 .unsol_event = alc883_medion_md2_unsol_event,
8563 .init_hook = alc883_medion_md2_automute,
8565 [ALC888_LENOVO_MS7195_DIG] = {
8566 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8567 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8568 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8569 .dac_nids = alc883_dac_nids,
8570 .dig_out_nid = ALC883_DIGOUT_NID,
8571 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8572 .channel_mode = alc883_3ST_6ch_modes,
8574 .input_mux = &alc883_capture_source,
8575 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8576 .init_hook = alc888_lenovo_ms7195_front_automute,
8578 [ALC883_HAIER_W66] = {
8579 .mixers = { alc883_tagra_2ch_mixer},
8580 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8581 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8582 .dac_nids = alc883_dac_nids,
8583 .dig_out_nid = ALC883_DIGOUT_NID,
8584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8585 .channel_mode = alc883_3ST_2ch_modes,
8586 .input_mux = &alc883_capture_source,
8587 .unsol_event = alc883_haier_w66_unsol_event,
8588 .init_hook = alc883_haier_w66_automute,
8591 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8592 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8593 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8594 .dac_nids = alc883_dac_nids,
8595 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8596 .channel_mode = alc888_3st_hp_modes,
8598 .input_mux = &alc883_capture_source,
8600 [ALC888_6ST_DELL] = {
8601 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8602 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8603 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8604 .dac_nids = alc883_dac_nids,
8605 .dig_out_nid = ALC883_DIGOUT_NID,
8606 .dig_in_nid = ALC883_DIGIN_NID,
8607 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8608 .channel_mode = alc883_sixstack_modes,
8609 .input_mux = &alc883_capture_source,
8610 .unsol_event = alc888_6st_dell_unsol_event,
8611 .init_hook = alc888_6st_dell_front_automute,
8614 .mixers = { alc883_mitac_mixer },
8615 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8617 .dac_nids = alc883_dac_nids,
8618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8619 .channel_mode = alc883_3ST_2ch_modes,
8620 .input_mux = &alc883_capture_source,
8621 .unsol_event = alc883_mitac_unsol_event,
8622 .init_hook = alc883_mitac_automute,
8624 [ALC883_FUJITSU_PI2515] = {
8625 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8626 .init_verbs = { alc883_init_verbs,
8627 alc883_2ch_fujitsu_pi2515_verbs},
8628 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8629 .dac_nids = alc883_dac_nids,
8630 .dig_out_nid = ALC883_DIGOUT_NID,
8631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8632 .channel_mode = alc883_3ST_2ch_modes,
8633 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8634 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8635 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8637 [ALC888_LENOVO_SKY] = {
8638 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8639 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8641 .dac_nids = alc883_dac_nids,
8642 .dig_out_nid = ALC883_DIGOUT_NID,
8643 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8644 .channel_mode = alc883_sixstack_modes,
8646 .input_mux = &alc883_lenovo_sky_capture_source,
8647 .unsol_event = alc883_lenovo_sky_unsol_event,
8648 .init_hook = alc888_lenovo_sky_front_automute,
8650 [ALC888_ASUS_M90V] = {
8651 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8652 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8654 .dac_nids = alc883_dac_nids,
8655 .dig_out_nid = ALC883_DIGOUT_NID,
8656 .dig_in_nid = ALC883_DIGIN_NID,
8657 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8658 .channel_mode = alc883_3ST_6ch_modes,
8660 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8661 .unsol_event = alc883_mode2_unsol_event,
8662 .init_hook = alc883_mode2_inithook,
8664 [ALC888_ASUS_EEE1601] = {
8665 .mixers = { alc883_asus_eee1601_mixer },
8666 .cap_mixer = alc883_asus_eee1601_cap_mixer,
8667 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8668 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8669 .dac_nids = alc883_dac_nids,
8670 .dig_out_nid = ALC883_DIGOUT_NID,
8671 .dig_in_nid = ALC883_DIGIN_NID,
8672 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8673 .channel_mode = alc883_3ST_2ch_modes,
8675 .input_mux = &alc883_asus_eee1601_capture_source,
8676 .unsol_event = alc883_eee1601_unsol_event,
8677 .init_hook = alc883_eee1601_inithook,
8679 [ALC1200_ASUS_P5Q] = {
8680 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8681 .init_verbs = { alc883_init_verbs },
8682 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8683 .dac_nids = alc883_dac_nids,
8684 .dig_out_nid = ALC1200_DIGOUT_NID,
8685 .dig_in_nid = ALC883_DIGIN_NID,
8686 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8687 .channel_mode = alc883_sixstack_modes,
8688 .input_mux = &alc883_capture_source,
8694 * BIOS auto configuration
8696 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8697 hda_nid_t nid, int pin_type,
8701 struct alc_spec *spec = codec->spec;
8704 alc_set_pin_output(codec, nid, pin_type);
8705 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8708 idx = spec->multiout.dac_nids[dac_idx] - 2;
8709 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8713 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8715 struct alc_spec *spec = codec->spec;
8718 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8719 for (i = 0; i <= HDA_SIDE; i++) {
8720 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8721 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8723 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8728 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8730 struct alc_spec *spec = codec->spec;
8733 pin = spec->autocfg.hp_pins[0];
8734 if (pin) /* connect to front */
8736 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8737 pin = spec->autocfg.speaker_pins[0];
8739 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8742 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8743 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8745 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8747 struct alc_spec *spec = codec->spec;
8750 for (i = 0; i < AUTO_PIN_LAST; i++) {
8751 hda_nid_t nid = spec->autocfg.input_pins[i];
8752 if (alc883_is_input_pin(nid)) {
8753 snd_hda_codec_write(codec, nid, 0,
8754 AC_VERB_SET_PIN_WIDGET_CONTROL,
8755 (i <= AUTO_PIN_FRONT_MIC ?
8756 PIN_VREF80 : PIN_IN));
8757 if (nid != ALC883_PIN_CD_NID)
8758 snd_hda_codec_write(codec, nid, 0,
8759 AC_VERB_SET_AMP_GAIN_MUTE,
8765 #define alc883_auto_init_input_src alc882_auto_init_input_src
8767 /* almost identical with ALC880 parser... */
8768 static int alc883_parse_auto_config(struct hda_codec *codec)
8770 struct alc_spec *spec = codec->spec;
8771 int err = alc880_parse_auto_config(codec);
8776 return 0; /* no config found */
8778 err = alc_auto_add_mic_boost(codec);
8782 /* hack - override the init verbs */
8783 spec->init_verbs[0] = alc883_auto_init_verbs;
8785 return 1; /* config found */
8788 /* additional initialization for auto-configuration model */
8789 static void alc883_auto_init(struct hda_codec *codec)
8791 struct alc_spec *spec = codec->spec;
8792 alc883_auto_init_multi_out(codec);
8793 alc883_auto_init_hp_out(codec);
8794 alc883_auto_init_analog_input(codec);
8795 alc883_auto_init_input_src(codec);
8796 if (spec->unsol_event)
8797 alc_inithook(codec);
8800 static int patch_alc883(struct hda_codec *codec)
8802 struct alc_spec *spec;
8803 int err, board_config;
8805 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8811 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8813 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8816 if (board_config < 0) {
8817 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8818 "trying auto-probe from BIOS...\n");
8819 board_config = ALC883_AUTO;
8822 if (board_config == ALC883_AUTO) {
8823 /* automatic parse from the BIOS config */
8824 err = alc883_parse_auto_config(codec);
8830 "hda_codec: Cannot set up configuration "
8831 "from BIOS. Using base mode...\n");
8832 board_config = ALC883_3ST_2ch_DIG;
8836 if (board_config != ALC883_AUTO)
8837 setup_preset(spec, &alc883_presets[board_config]);
8839 switch (codec->vendor_id) {
8841 if (codec->revision_id == 0x100101) {
8842 spec->stream_name_analog = "ALC1200 Analog";
8843 spec->stream_name_digital = "ALC1200 Digital";
8845 spec->stream_name_analog = "ALC888 Analog";
8846 spec->stream_name_digital = "ALC888 Digital";
8850 spec->stream_name_analog = "ALC889 Analog";
8851 spec->stream_name_digital = "ALC889 Digital";
8854 spec->stream_name_analog = "ALC883 Analog";
8855 spec->stream_name_digital = "ALC883 Digital";
8859 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8860 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8861 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8863 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8864 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8866 if (!spec->num_adc_nids) {
8867 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8868 spec->adc_nids = alc883_adc_nids;
8870 if (!spec->capsrc_nids)
8871 spec->capsrc_nids = alc883_capsrc_nids;
8872 spec->is_mix_capture = 1; /* matrix-style capture */
8873 if (!spec->cap_mixer)
8874 set_capture_mixer(spec);
8876 spec->vmaster_nid = 0x0c;
8878 codec->patch_ops = alc_patch_ops;
8879 if (board_config == ALC883_AUTO)
8880 spec->init_hook = alc883_auto_init;
8882 #ifdef CONFIG_SND_HDA_POWER_SAVE
8883 if (!spec->loopback.amplist)
8884 spec->loopback.amplist = alc883_loopbacks;
8894 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8895 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8897 #define alc262_dac_nids alc260_dac_nids
8898 #define alc262_adc_nids alc882_adc_nids
8899 #define alc262_adc_nids_alt alc882_adc_nids_alt
8900 #define alc262_capsrc_nids alc882_capsrc_nids
8901 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8903 #define alc262_modes alc260_modes
8904 #define alc262_capture_source alc882_capture_source
8906 static hda_nid_t alc262_dmic_adc_nids[1] = {
8911 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8913 static struct snd_kcontrol_new alc262_base_mixer[] = {
8914 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8915 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8921 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8923 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8924 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8925 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8926 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8927 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8928 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8930 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8931 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8935 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8936 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8937 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8938 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8939 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8940 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8941 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8942 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8944 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8945 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8946 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8947 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8948 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8949 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8950 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8955 /* update HP, line and mono-out pins according to the master switch */
8956 static void alc262_hp_master_update(struct hda_codec *codec)
8958 struct alc_spec *spec = codec->spec;
8959 int val = spec->master_sw;
8962 snd_hda_codec_write_cache(codec, 0x1b, 0,
8963 AC_VERB_SET_PIN_WIDGET_CONTROL,
8965 snd_hda_codec_write_cache(codec, 0x15, 0,
8966 AC_VERB_SET_PIN_WIDGET_CONTROL,
8968 /* mono (speaker) depending on the HP jack sense */
8969 val = val && !spec->jack_present;
8970 snd_hda_codec_write_cache(codec, 0x16, 0,
8971 AC_VERB_SET_PIN_WIDGET_CONTROL,
8975 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8977 struct alc_spec *spec = codec->spec;
8978 unsigned int presence;
8979 presence = snd_hda_codec_read(codec, 0x1b, 0,
8980 AC_VERB_GET_PIN_SENSE, 0);
8981 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8982 alc262_hp_master_update(codec);
8985 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8987 if ((res >> 26) != ALC880_HP_EVENT)
8989 alc262_hp_bpc_automute(codec);
8992 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8994 struct alc_spec *spec = codec->spec;
8995 unsigned int presence;
8996 presence = snd_hda_codec_read(codec, 0x15, 0,
8997 AC_VERB_GET_PIN_SENSE, 0);
8998 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8999 alc262_hp_master_update(codec);
9002 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9005 if ((res >> 26) != ALC880_HP_EVENT)
9007 alc262_hp_wildwest_automute(codec);
9010 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9011 struct snd_ctl_elem_value *ucontrol)
9013 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9014 struct alc_spec *spec = codec->spec;
9015 *ucontrol->value.integer.value = spec->master_sw;
9019 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9020 struct snd_ctl_elem_value *ucontrol)
9022 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9023 struct alc_spec *spec = codec->spec;
9024 int val = !!*ucontrol->value.integer.value;
9026 if (val == spec->master_sw)
9028 spec->master_sw = val;
9029 alc262_hp_master_update(codec);
9033 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9035 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9036 .name = "Master Playback Switch",
9037 .info = snd_ctl_boolean_mono_info,
9038 .get = alc262_hp_master_sw_get,
9039 .put = alc262_hp_master_sw_put,
9041 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9042 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9043 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9044 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9046 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9050 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9051 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9052 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9053 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9054 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9055 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9056 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9057 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9058 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9059 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9060 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9061 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9065 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9068 .name = "Master Playback Switch",
9069 .info = snd_ctl_boolean_mono_info,
9070 .get = alc262_hp_master_sw_get,
9071 .put = alc262_hp_master_sw_put,
9073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9074 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9076 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9077 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9079 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9081 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9082 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9083 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9085 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9086 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9087 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9088 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9089 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9093 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9094 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9095 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9096 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9100 /* mute/unmute internal speaker according to the hp jack and mute state */
9101 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9103 struct alc_spec *spec = codec->spec;
9105 if (force || !spec->sense_updated) {
9106 unsigned int present;
9107 present = snd_hda_codec_read(codec, 0x15, 0,
9108 AC_VERB_GET_PIN_SENSE, 0);
9109 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9110 spec->sense_updated = 1;
9112 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9113 spec->jack_present ? HDA_AMP_MUTE : 0);
9116 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9119 if ((res >> 26) != ALC880_HP_EVENT)
9121 alc262_hp_t5735_automute(codec, 1);
9124 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9126 alc262_hp_t5735_automute(codec, 1);
9129 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9130 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9131 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9133 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9135 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9136 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9140 static struct hda_verb alc262_hp_t5735_verbs[] = {
9141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9142 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9144 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9148 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9149 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9150 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9151 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9152 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9153 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9154 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9158 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9160 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9161 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9162 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9164 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9165 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9166 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9167 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9168 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9172 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9179 /* bind hp and internal speaker mute (with plug check) */
9180 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9181 struct snd_ctl_elem_value *ucontrol)
9183 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9184 long *valp = ucontrol->value.integer.value;
9187 /* change hp mute */
9188 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9190 valp[0] ? 0 : HDA_AMP_MUTE);
9191 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9193 valp[1] ? 0 : HDA_AMP_MUTE);
9195 /* change speaker according to HP jack state */
9196 struct alc_spec *spec = codec->spec;
9198 if (spec->jack_present)
9199 mute = HDA_AMP_MUTE;
9201 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9203 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9204 HDA_AMP_MUTE, mute);
9209 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9210 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9213 .name = "Master Playback Switch",
9214 .info = snd_hda_mixer_amp_switch_info,
9215 .get = snd_hda_mixer_amp_switch_get,
9216 .put = alc262_sony_master_sw_put,
9217 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9221 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9222 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9226 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9227 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9228 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9229 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9232 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9233 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9237 #define alc262_capture_mixer alc882_capture_mixer
9238 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9241 * generic initialization of ADC, input mixers and output mixers
9243 static struct hda_verb alc262_init_verbs[] = {
9245 * Unmute ADC0-2 and set the default input to mic-in
9247 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9249 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9250 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9251 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9252 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9254 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9256 * Note: PASD motherboards uses the Line In 2 as the input for
9257 * front panel mic (mic 2)
9259 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9260 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9261 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9262 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9263 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9264 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9267 * Set up output mixers (0x0c - 0x0e)
9269 /* set vol=0 to output mixers */
9270 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9271 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9272 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9273 /* set up input amps for analog loopback */
9274 /* Amp Indices: DAC = 0, mixer = 1 */
9275 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9276 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9277 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9278 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9279 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9280 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9282 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9284 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9285 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9286 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9287 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9291 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9292 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9293 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9295 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9296 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9298 /* FIXME: use matrix-type input source selection */
9299 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9300 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9303 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9319 static struct hda_verb alc262_eapd_verbs[] = {
9320 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9321 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9325 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9326 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9331 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9332 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9333 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9334 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9336 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9341 static struct hda_verb alc262_sony_unsol_verbs[] = {
9342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9343 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9344 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9351 static struct hda_input_mux alc262_dmic_capture_source = {
9354 { "Int DMic", 0x9 },
9359 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9360 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9361 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9362 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9364 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9368 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9369 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9370 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9373 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9375 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9376 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9380 static void alc262_dmic_automute(struct hda_codec *codec)
9382 unsigned int present;
9384 present = snd_hda_codec_read(codec, 0x18, 0,
9385 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9386 snd_hda_codec_write(codec, 0x22, 0,
9387 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9390 /* toggle speaker-output according to the hp-jack state */
9391 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9393 unsigned int present;
9396 present = snd_hda_codec_read(codec, 0x15, 0,
9397 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9398 bits = present ? 0 : PIN_OUT;
9399 snd_hda_codec_write(codec, 0x14, 0,
9400 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9405 /* unsolicited event for HP jack sensing */
9406 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9409 if ((res >> 26) == ALC880_HP_EVENT)
9410 alc262_toshiba_s06_speaker_automute(codec);
9411 if ((res >> 26) == ALC880_MIC_EVENT)
9412 alc262_dmic_automute(codec);
9416 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9418 alc262_toshiba_s06_speaker_automute(codec);
9419 alc262_dmic_automute(codec);
9422 /* mute/unmute internal speaker according to the hp jack and mute state */
9423 static void alc262_hippo_automute(struct hda_codec *codec)
9425 struct alc_spec *spec = codec->spec;
9427 unsigned int present;
9429 /* need to execute and sync at first */
9430 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9431 present = snd_hda_codec_read(codec, 0x15, 0,
9432 AC_VERB_GET_PIN_SENSE, 0);
9433 spec->jack_present = (present & 0x80000000) != 0;
9434 if (spec->jack_present) {
9435 /* mute internal speaker */
9436 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9437 HDA_AMP_MUTE, HDA_AMP_MUTE);
9439 /* unmute internal speaker if necessary */
9440 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9441 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9442 HDA_AMP_MUTE, mute);
9446 /* unsolicited event for HP jack sensing */
9447 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9450 if ((res >> 26) != ALC880_HP_EVENT)
9452 alc262_hippo_automute(codec);
9455 static void alc262_hippo1_automute(struct hda_codec *codec)
9458 unsigned int present;
9460 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9461 present = snd_hda_codec_read(codec, 0x1b, 0,
9462 AC_VERB_GET_PIN_SENSE, 0);
9463 present = (present & 0x80000000) != 0;
9465 /* mute internal speaker */
9466 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9467 HDA_AMP_MUTE, HDA_AMP_MUTE);
9469 /* unmute internal speaker if necessary */
9470 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9471 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9472 HDA_AMP_MUTE, mute);
9476 /* unsolicited event for HP jack sensing */
9477 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9480 if ((res >> 26) != ALC880_HP_EVENT)
9482 alc262_hippo1_automute(codec);
9488 * 0x16 = internal speaker
9489 * 0x18 = external mic
9492 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9493 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9494 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9497 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9498 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9500 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9501 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9505 static struct hda_verb alc262_nec_verbs[] = {
9506 /* Unmute Speaker */
9507 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9510 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9513 /* External mic to headphone */
9514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9515 /* External mic to speaker */
9516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9522 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9523 * 0x1b = port replicator headphone out
9526 #define ALC_HP_EVENT 0x37
9528 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9529 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9531 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9536 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9537 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9542 static struct hda_input_mux alc262_fujitsu_capture_source = {
9551 static struct hda_input_mux alc262_HP_capture_source = {
9555 { "Front Mic", 0x1 },
9562 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9566 { "Front Mic", 0x2 },
9572 /* mute/unmute internal speaker according to the hp jacks and mute state */
9573 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9575 struct alc_spec *spec = codec->spec;
9578 if (force || !spec->sense_updated) {
9579 unsigned int present;
9580 /* need to execute and sync at first */
9581 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9582 /* check laptop HP jack */
9583 present = snd_hda_codec_read(codec, 0x14, 0,
9584 AC_VERB_GET_PIN_SENSE, 0);
9585 /* need to execute and sync at first */
9586 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9587 /* check docking HP jack */
9588 present |= snd_hda_codec_read(codec, 0x1b, 0,
9589 AC_VERB_GET_PIN_SENSE, 0);
9590 if (present & AC_PINSENSE_PRESENCE)
9591 spec->jack_present = 1;
9593 spec->jack_present = 0;
9594 spec->sense_updated = 1;
9596 /* unmute internal speaker only if both HPs are unplugged and
9597 * master switch is on
9599 if (spec->jack_present)
9600 mute = HDA_AMP_MUTE;
9602 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9603 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9604 HDA_AMP_MUTE, mute);
9607 /* unsolicited event for HP jack sensing */
9608 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9611 if ((res >> 26) != ALC_HP_EVENT)
9613 alc262_fujitsu_automute(codec, 1);
9616 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9618 alc262_fujitsu_automute(codec, 1);
9621 /* bind volumes of both NID 0x0c and 0x0d */
9622 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9623 .ops = &snd_hda_bind_vol,
9625 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9626 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9631 /* mute/unmute internal speaker according to the hp jack and mute state */
9632 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9634 struct alc_spec *spec = codec->spec;
9637 if (force || !spec->sense_updated) {
9638 unsigned int present_int_hp;
9639 /* need to execute and sync at first */
9640 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9641 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9642 AC_VERB_GET_PIN_SENSE, 0);
9643 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9644 spec->sense_updated = 1;
9646 if (spec->jack_present) {
9647 /* mute internal speaker */
9648 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9649 HDA_AMP_MUTE, HDA_AMP_MUTE);
9650 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9651 HDA_AMP_MUTE, HDA_AMP_MUTE);
9653 /* unmute internal speaker if necessary */
9654 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9655 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9656 HDA_AMP_MUTE, mute);
9657 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9658 HDA_AMP_MUTE, mute);
9662 /* unsolicited event for HP jack sensing */
9663 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9666 if ((res >> 26) != ALC_HP_EVENT)
9668 alc262_lenovo_3000_automute(codec, 1);
9671 /* bind hp and internal speaker mute (with plug check) */
9672 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9673 struct snd_ctl_elem_value *ucontrol)
9675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9676 long *valp = ucontrol->value.integer.value;
9679 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9681 valp ? 0 : HDA_AMP_MUTE);
9682 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9684 valp ? 0 : HDA_AMP_MUTE);
9687 alc262_fujitsu_automute(codec, 0);
9691 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9692 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9694 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9695 .name = "Master Playback Switch",
9696 .info = snd_hda_mixer_amp_switch_info,
9697 .get = snd_hda_mixer_amp_switch_get,
9698 .put = alc262_fujitsu_master_sw_put,
9699 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9701 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9702 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9703 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9704 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9705 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9708 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9710 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9714 /* bind hp and internal speaker mute (with plug check) */
9715 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9716 struct snd_ctl_elem_value *ucontrol)
9718 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9719 long *valp = ucontrol->value.integer.value;
9722 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9724 valp ? 0 : HDA_AMP_MUTE);
9727 alc262_lenovo_3000_automute(codec, 0);
9731 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9732 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9735 .name = "Master Playback Switch",
9736 .info = snd_hda_mixer_amp_switch_info,
9737 .get = snd_hda_mixer_amp_switch_get,
9738 .put = alc262_lenovo_3000_master_sw_put,
9739 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9741 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9742 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9743 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9746 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9747 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9748 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9752 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9753 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9756 .name = "Master Playback Switch",
9757 .info = snd_hda_mixer_amp_switch_info,
9758 .get = snd_hda_mixer_amp_switch_get,
9759 .put = alc262_sony_master_sw_put,
9760 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9764 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9765 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9766 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9767 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9771 /* additional init verbs for Benq laptops */
9772 static struct hda_verb alc262_EAPD_verbs[] = {
9773 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9774 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9778 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9779 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9782 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9783 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9787 /* Samsung Q1 Ultra Vista model setup */
9788 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9789 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9790 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9793 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9794 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9798 static struct hda_verb alc262_ultra_verbs[] = {
9800 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9807 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9812 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9813 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9815 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9816 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9817 /* ADC, choose mic */
9818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9819 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9820 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9821 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9822 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9823 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9824 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9825 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9826 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9827 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9831 /* mute/unmute internal speaker according to the hp jack and mute state */
9832 static void alc262_ultra_automute(struct hda_codec *codec)
9834 struct alc_spec *spec = codec->spec;
9838 /* auto-mute only when HP is used as HP */
9839 if (!spec->cur_mux[0]) {
9840 unsigned int present;
9841 /* need to execute and sync at first */
9842 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9843 present = snd_hda_codec_read(codec, 0x15, 0,
9844 AC_VERB_GET_PIN_SENSE, 0);
9845 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9846 if (spec->jack_present)
9847 mute = HDA_AMP_MUTE;
9849 /* mute/unmute internal speaker */
9850 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9851 HDA_AMP_MUTE, mute);
9852 /* mute/unmute HP */
9853 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9854 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9857 /* unsolicited event for HP jack sensing */
9858 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9861 if ((res >> 26) != ALC880_HP_EVENT)
9863 alc262_ultra_automute(codec);
9866 static struct hda_input_mux alc262_ultra_capture_source = {
9870 { "Headphone", 0x7 },
9874 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9875 struct snd_ctl_elem_value *ucontrol)
9877 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9878 struct alc_spec *spec = codec->spec;
9881 ret = alc_mux_enum_put(kcontrol, ucontrol);
9884 /* reprogram the HP pin as mic or HP according to the input source */
9885 snd_hda_codec_write_cache(codec, 0x15, 0,
9886 AC_VERB_SET_PIN_WIDGET_CONTROL,
9887 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9888 alc262_ultra_automute(codec); /* mute/unmute HP */
9892 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9893 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9894 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9897 .name = "Capture Source",
9898 .info = alc_mux_enum_info,
9899 .get = alc_mux_enum_get,
9900 .put = alc262_ultra_mux_enum_put,
9905 /* add playback controls from the parsed DAC table */
9906 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9907 const struct auto_pin_cfg *cfg)
9912 spec->multiout.num_dacs = 1; /* only use one dac */
9913 spec->multiout.dac_nids = spec->private_dac_nids;
9914 spec->multiout.dac_nids[0] = 2;
9916 nid = cfg->line_out_pins[0];
9918 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9919 "Front Playback Volume",
9920 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9923 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9924 "Front Playback Switch",
9925 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9930 nid = cfg->speaker_pins[0];
9933 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9934 "Speaker Playback Volume",
9935 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9939 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9940 "Speaker Playback Switch",
9941 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9946 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9947 "Speaker Playback Switch",
9948 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9954 nid = cfg->hp_pins[0];
9956 /* spec->multiout.hp_nid = 2; */
9958 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9959 "Headphone Playback Volume",
9960 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9964 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9965 "Headphone Playback Switch",
9966 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9971 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9972 "Headphone Playback Switch",
9973 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9982 /* identical with ALC880 */
9983 #define alc262_auto_create_analog_input_ctls \
9984 alc880_auto_create_analog_input_ctls
9987 * generic initialization of ADC, input mixers and output mixers
9989 static struct hda_verb alc262_volume_init_verbs[] = {
9991 * Unmute ADC0-2 and set the default input to mic-in
9993 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9995 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9996 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9997 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10000 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10002 * Note: PASD motherboards uses the Line In 2 as the input for
10003 * front panel mic (mic 2)
10005 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10013 * Set up output mixers (0x0c - 0x0f)
10015 /* set vol=0 to output mixers */
10016 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10017 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10018 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10020 /* set up input amps for analog loopback */
10021 /* Amp Indices: DAC = 0, mixer = 1 */
10022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10024 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10025 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10026 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10027 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10029 /* FIXME: use matrix-type input source selection */
10030 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10031 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10032 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10033 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10034 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10037 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10038 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10039 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10050 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10052 * Unmute ADC0-2 and set the default input to mic-in
10054 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10056 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10057 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10058 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10059 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10061 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10063 * Note: PASD motherboards uses the Line In 2 as the input for
10064 * front panel mic (mic 2)
10066 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10070 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10072 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10073 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10076 * Set up output mixers (0x0c - 0x0e)
10078 /* set vol=0 to output mixers */
10079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10080 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10083 /* set up input amps for analog loopback */
10084 /* Amp Indices: DAC = 0, mixer = 1 */
10085 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10087 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10089 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10090 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10092 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10094 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10096 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10097 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10099 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10100 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10102 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10103 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10104 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10105 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10106 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10108 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10110 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10111 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10112 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10113 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10116 /* FIXME: use matrix-type input source selection */
10117 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10118 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10119 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10125 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10130 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10134 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10139 static struct hda_verb alc262_HP_BPC_WildWest_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 front
10153 * 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)},
10163 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
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)},
10182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10184 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10186 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10188 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10190 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10193 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10194 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10196 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10197 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10200 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10201 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10203 /* FIXME: use matrix-type input source selection */
10204 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10205 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10211 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10212 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10219 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10227 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10230 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10235 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10239 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10241 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10242 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10243 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10244 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10246 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10247 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10248 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10253 #ifdef CONFIG_SND_HDA_POWER_SAVE
10254 #define alc262_loopbacks alc880_loopbacks
10257 /* pcm configuration: identiacal with ALC880 */
10258 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10259 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10260 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10261 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10264 * BIOS auto configuration
10266 static int alc262_parse_auto_config(struct hda_codec *codec)
10268 struct alc_spec *spec = codec->spec;
10270 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10272 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10276 if (!spec->autocfg.line_outs)
10277 return 0; /* can't find valid BIOS pin config */
10278 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10281 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10285 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10287 if (spec->autocfg.dig_out_pin)
10288 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10289 if (spec->autocfg.dig_in_pin)
10290 spec->dig_in_nid = ALC262_DIGIN_NID;
10292 if (spec->kctls.list)
10293 add_mixer(spec, spec->kctls.list);
10295 add_verb(spec, alc262_volume_init_verbs);
10296 spec->num_mux_defs = 1;
10297 spec->input_mux = &spec->private_imux;
10299 err = alc_auto_add_mic_boost(codec);
10303 store_pin_configs(codec);
10307 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10308 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10309 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10310 #define alc262_auto_init_input_src alc882_auto_init_input_src
10313 /* init callback for auto-configuration model -- overriding the default init */
10314 static void alc262_auto_init(struct hda_codec *codec)
10316 struct alc_spec *spec = codec->spec;
10317 alc262_auto_init_multi_out(codec);
10318 alc262_auto_init_hp_out(codec);
10319 alc262_auto_init_analog_input(codec);
10320 alc262_auto_init_input_src(codec);
10321 if (spec->unsol_event)
10322 alc_inithook(codec);
10326 * configuration and preset
10328 static const char *alc262_models[ALC262_MODEL_LAST] = {
10329 [ALC262_BASIC] = "basic",
10330 [ALC262_HIPPO] = "hippo",
10331 [ALC262_HIPPO_1] = "hippo_1",
10332 [ALC262_FUJITSU] = "fujitsu",
10333 [ALC262_HP_BPC] = "hp-bpc",
10334 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10335 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10336 [ALC262_HP_RP5700] = "hp-rp5700",
10337 [ALC262_BENQ_ED8] = "benq",
10338 [ALC262_BENQ_T31] = "benq-t31",
10339 [ALC262_SONY_ASSAMD] = "sony-assamd",
10340 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10341 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10342 [ALC262_ULTRA] = "ultra",
10343 [ALC262_LENOVO_3000] = "lenovo-3000",
10344 [ALC262_NEC] = "nec",
10345 [ALC262_AUTO] = "auto",
10348 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10349 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10350 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10351 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10352 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10353 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10354 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10355 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10356 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10357 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10358 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10359 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10360 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10361 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10362 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10363 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10364 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10365 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10366 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10367 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10368 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10369 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10370 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10371 ALC262_HP_TC_T5735),
10372 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10373 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10374 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10375 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10376 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10377 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10378 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10379 ALC262_TOSHIBA_RX1),
10380 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10381 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10382 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10383 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10384 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10385 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10386 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10387 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10388 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10392 static struct alc_config_preset alc262_presets[] = {
10394 .mixers = { alc262_base_mixer },
10395 .init_verbs = { alc262_init_verbs },
10396 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10397 .dac_nids = alc262_dac_nids,
10399 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10400 .channel_mode = alc262_modes,
10401 .input_mux = &alc262_capture_source,
10404 .mixers = { alc262_base_mixer },
10405 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10406 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10407 .dac_nids = alc262_dac_nids,
10409 .dig_out_nid = ALC262_DIGOUT_NID,
10410 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10411 .channel_mode = alc262_modes,
10412 .input_mux = &alc262_capture_source,
10413 .unsol_event = alc262_hippo_unsol_event,
10414 .init_hook = alc262_hippo_automute,
10416 [ALC262_HIPPO_1] = {
10417 .mixers = { alc262_hippo1_mixer },
10418 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10419 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10420 .dac_nids = alc262_dac_nids,
10422 .dig_out_nid = ALC262_DIGOUT_NID,
10423 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10424 .channel_mode = alc262_modes,
10425 .input_mux = &alc262_capture_source,
10426 .unsol_event = alc262_hippo1_unsol_event,
10427 .init_hook = alc262_hippo1_automute,
10429 [ALC262_FUJITSU] = {
10430 .mixers = { alc262_fujitsu_mixer },
10431 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10432 alc262_fujitsu_unsol_verbs },
10433 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10434 .dac_nids = alc262_dac_nids,
10436 .dig_out_nid = ALC262_DIGOUT_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10438 .channel_mode = alc262_modes,
10439 .input_mux = &alc262_fujitsu_capture_source,
10440 .unsol_event = alc262_fujitsu_unsol_event,
10441 .init_hook = alc262_fujitsu_init_hook,
10443 [ALC262_HP_BPC] = {
10444 .mixers = { alc262_HP_BPC_mixer },
10445 .init_verbs = { alc262_HP_BPC_init_verbs },
10446 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10447 .dac_nids = alc262_dac_nids,
10449 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10450 .channel_mode = alc262_modes,
10451 .input_mux = &alc262_HP_capture_source,
10452 .unsol_event = alc262_hp_bpc_unsol_event,
10453 .init_hook = alc262_hp_bpc_automute,
10455 [ALC262_HP_BPC_D7000_WF] = {
10456 .mixers = { alc262_HP_BPC_WildWest_mixer },
10457 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10458 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10459 .dac_nids = alc262_dac_nids,
10461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10462 .channel_mode = alc262_modes,
10463 .input_mux = &alc262_HP_D7000_capture_source,
10464 .unsol_event = alc262_hp_wildwest_unsol_event,
10465 .init_hook = alc262_hp_wildwest_automute,
10467 [ALC262_HP_BPC_D7000_WL] = {
10468 .mixers = { alc262_HP_BPC_WildWest_mixer,
10469 alc262_HP_BPC_WildWest_option_mixer },
10470 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10471 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10472 .dac_nids = alc262_dac_nids,
10474 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10475 .channel_mode = alc262_modes,
10476 .input_mux = &alc262_HP_D7000_capture_source,
10477 .unsol_event = alc262_hp_wildwest_unsol_event,
10478 .init_hook = alc262_hp_wildwest_automute,
10480 [ALC262_HP_TC_T5735] = {
10481 .mixers = { alc262_hp_t5735_mixer },
10482 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10483 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10484 .dac_nids = alc262_dac_nids,
10486 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10487 .channel_mode = alc262_modes,
10488 .input_mux = &alc262_capture_source,
10489 .unsol_event = alc262_hp_t5735_unsol_event,
10490 .init_hook = alc262_hp_t5735_init_hook,
10492 [ALC262_HP_RP5700] = {
10493 .mixers = { alc262_hp_rp5700_mixer },
10494 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10495 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10496 .dac_nids = alc262_dac_nids,
10497 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10498 .channel_mode = alc262_modes,
10499 .input_mux = &alc262_hp_rp5700_capture_source,
10501 [ALC262_BENQ_ED8] = {
10502 .mixers = { alc262_base_mixer },
10503 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10504 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10505 .dac_nids = alc262_dac_nids,
10507 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10508 .channel_mode = alc262_modes,
10509 .input_mux = &alc262_capture_source,
10511 [ALC262_SONY_ASSAMD] = {
10512 .mixers = { alc262_sony_mixer },
10513 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10514 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10515 .dac_nids = alc262_dac_nids,
10517 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10518 .channel_mode = alc262_modes,
10519 .input_mux = &alc262_capture_source,
10520 .unsol_event = alc262_hippo_unsol_event,
10521 .init_hook = alc262_hippo_automute,
10523 [ALC262_BENQ_T31] = {
10524 .mixers = { alc262_benq_t31_mixer },
10525 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10527 .dac_nids = alc262_dac_nids,
10529 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10530 .channel_mode = alc262_modes,
10531 .input_mux = &alc262_capture_source,
10532 .unsol_event = alc262_hippo_unsol_event,
10533 .init_hook = alc262_hippo_automute,
10536 .mixers = { alc262_ultra_mixer },
10537 .cap_mixer = alc262_ultra_capture_mixer,
10538 .init_verbs = { alc262_ultra_verbs },
10539 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10540 .dac_nids = alc262_dac_nids,
10541 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10542 .channel_mode = alc262_modes,
10543 .input_mux = &alc262_ultra_capture_source,
10544 .adc_nids = alc262_adc_nids, /* ADC0 */
10545 .capsrc_nids = alc262_capsrc_nids,
10546 .num_adc_nids = 1, /* single ADC */
10547 .unsol_event = alc262_ultra_unsol_event,
10548 .init_hook = alc262_ultra_automute,
10550 [ALC262_LENOVO_3000] = {
10551 .mixers = { alc262_lenovo_3000_mixer },
10552 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10553 alc262_lenovo_3000_unsol_verbs },
10554 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10555 .dac_nids = alc262_dac_nids,
10557 .dig_out_nid = ALC262_DIGOUT_NID,
10558 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10559 .channel_mode = alc262_modes,
10560 .input_mux = &alc262_fujitsu_capture_source,
10561 .unsol_event = alc262_lenovo_3000_unsol_event,
10564 .mixers = { alc262_nec_mixer },
10565 .init_verbs = { alc262_nec_verbs },
10566 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10567 .dac_nids = alc262_dac_nids,
10569 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10570 .channel_mode = alc262_modes,
10571 .input_mux = &alc262_capture_source,
10573 [ALC262_TOSHIBA_S06] = {
10574 .mixers = { alc262_toshiba_s06_mixer },
10575 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10576 alc262_eapd_verbs },
10577 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10578 .capsrc_nids = alc262_dmic_capsrc_nids,
10579 .dac_nids = alc262_dac_nids,
10580 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10581 .dig_out_nid = ALC262_DIGOUT_NID,
10582 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10583 .channel_mode = alc262_modes,
10584 .input_mux = &alc262_dmic_capture_source,
10585 .unsol_event = alc262_toshiba_s06_unsol_event,
10586 .init_hook = alc262_toshiba_s06_init_hook,
10588 [ALC262_TOSHIBA_RX1] = {
10589 .mixers = { alc262_toshiba_rx1_mixer },
10590 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10591 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10592 .dac_nids = alc262_dac_nids,
10594 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10595 .channel_mode = alc262_modes,
10596 .input_mux = &alc262_capture_source,
10597 .unsol_event = alc262_hippo_unsol_event,
10598 .init_hook = alc262_hippo_automute,
10602 static int patch_alc262(struct hda_codec *codec)
10604 struct alc_spec *spec;
10608 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10612 codec->spec = spec;
10614 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10619 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10620 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10621 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10622 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10626 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10628 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10632 if (board_config < 0) {
10633 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10634 "trying auto-probe from BIOS...\n");
10635 board_config = ALC262_AUTO;
10638 if (board_config == ALC262_AUTO) {
10639 /* automatic parse from the BIOS config */
10640 err = alc262_parse_auto_config(codec);
10646 "hda_codec: Cannot set up configuration "
10647 "from BIOS. Using base mode...\n");
10648 board_config = ALC262_BASIC;
10652 if (board_config != ALC262_AUTO)
10653 setup_preset(spec, &alc262_presets[board_config]);
10655 spec->stream_name_analog = "ALC262 Analog";
10656 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10657 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10659 spec->stream_name_digital = "ALC262 Digital";
10660 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10661 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10663 spec->is_mix_capture = 1;
10664 if (!spec->adc_nids && spec->input_mux) {
10665 /* check whether NID 0x07 is valid */
10666 unsigned int wcap = get_wcaps(codec, 0x07);
10669 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10670 if (wcap != AC_WID_AUD_IN) {
10671 spec->adc_nids = alc262_adc_nids_alt;
10672 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10673 spec->capsrc_nids = alc262_capsrc_nids_alt;
10675 spec->adc_nids = alc262_adc_nids;
10676 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10677 spec->capsrc_nids = alc262_capsrc_nids;
10680 if (!spec->cap_mixer)
10681 set_capture_mixer(spec);
10683 spec->vmaster_nid = 0x0c;
10685 codec->patch_ops = alc_patch_ops;
10686 if (board_config == ALC262_AUTO)
10687 spec->init_hook = alc262_auto_init;
10688 #ifdef CONFIG_SND_HDA_POWER_SAVE
10689 if (!spec->loopback.amplist)
10690 spec->loopback.amplist = alc262_loopbacks;
10697 * ALC268 channel source setting (2 channel)
10699 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10700 #define alc268_modes alc260_modes
10702 static hda_nid_t alc268_dac_nids[2] = {
10707 static hda_nid_t alc268_adc_nids[2] = {
10712 static hda_nid_t alc268_adc_nids_alt[1] = {
10717 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10719 static struct snd_kcontrol_new alc268_base_mixer[] = {
10720 /* output mixer control */
10721 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10722 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10723 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10724 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10725 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10726 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10727 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10731 /* bind Beep switches of both NID 0x0f and 0x10 */
10732 static struct hda_bind_ctls alc268_bind_beep_sw = {
10733 .ops = &snd_hda_bind_sw,
10735 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10736 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10741 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10742 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10743 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10747 static struct hda_verb alc268_eapd_verbs[] = {
10748 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10749 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10753 /* Toshiba specific */
10754 #define alc268_toshiba_automute alc262_hippo_automute
10756 static struct hda_verb alc268_toshiba_verbs[] = {
10757 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10761 static struct hda_input_mux alc268_acer_lc_capture_source = {
10769 /* Acer specific */
10770 /* bind volumes of both NID 0x02 and 0x03 */
10771 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10772 .ops = &snd_hda_bind_vol,
10774 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10775 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10780 /* mute/unmute internal speaker according to the hp jack and mute state */
10781 static void alc268_acer_automute(struct hda_codec *codec, int force)
10783 struct alc_spec *spec = codec->spec;
10786 if (force || !spec->sense_updated) {
10787 unsigned int present;
10788 present = snd_hda_codec_read(codec, 0x14, 0,
10789 AC_VERB_GET_PIN_SENSE, 0);
10790 spec->jack_present = (present & 0x80000000) != 0;
10791 spec->sense_updated = 1;
10793 if (spec->jack_present)
10794 mute = HDA_AMP_MUTE; /* mute internal speaker */
10795 else /* unmute internal speaker if necessary */
10796 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10797 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10798 HDA_AMP_MUTE, mute);
10802 /* bind hp and internal speaker mute (with plug check) */
10803 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10804 struct snd_ctl_elem_value *ucontrol)
10806 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10807 long *valp = ucontrol->value.integer.value;
10810 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10812 valp[0] ? 0 : HDA_AMP_MUTE);
10813 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10815 valp[1] ? 0 : HDA_AMP_MUTE);
10817 alc268_acer_automute(codec, 0);
10821 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10822 /* output mixer control */
10823 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10826 .name = "Master Playback Switch",
10827 .info = snd_hda_mixer_amp_switch_info,
10828 .get = snd_hda_mixer_amp_switch_get,
10829 .put = alc268_acer_master_sw_put,
10830 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10832 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10836 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10837 /* output mixer control */
10838 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10841 .name = "Master Playback Switch",
10842 .info = snd_hda_mixer_amp_switch_info,
10843 .get = snd_hda_mixer_amp_switch_get,
10844 .put = alc268_acer_master_sw_put,
10845 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10847 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10848 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10849 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10853 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
10854 /* output mixer control */
10855 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10857 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10858 .name = "Master Playback Switch",
10859 .info = snd_hda_mixer_amp_switch_info,
10860 .get = snd_hda_mixer_amp_switch_get,
10861 .put = alc268_acer_master_sw_put,
10862 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10864 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10865 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10869 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10872 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10873 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10874 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10875 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10879 static struct hda_verb alc268_acer_verbs[] = {
10880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10881 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10882 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10883 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10884 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10885 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10886 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10890 /* unsolicited event for HP jack sensing */
10891 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10894 if ((res >> 26) != ALC880_HP_EVENT)
10896 alc268_toshiba_automute(codec);
10899 static void alc268_acer_unsol_event(struct hda_codec *codec,
10902 if ((res >> 26) != ALC880_HP_EVENT)
10904 alc268_acer_automute(codec, 1);
10907 static void alc268_acer_init_hook(struct hda_codec *codec)
10909 alc268_acer_automute(codec, 1);
10912 /* toggle speaker-output according to the hp-jack state */
10913 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10915 unsigned int present;
10916 unsigned char bits;
10918 present = snd_hda_codec_read(codec, 0x15, 0,
10919 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10920 bits = present ? AMP_IN_MUTE(0) : 0;
10921 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10922 AMP_IN_MUTE(0), bits);
10923 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10924 AMP_IN_MUTE(0), bits);
10928 static void alc268_acer_mic_automute(struct hda_codec *codec)
10930 unsigned int present;
10932 present = snd_hda_codec_read(codec, 0x18, 0,
10933 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10934 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10935 present ? 0x0 : 0x6);
10938 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10941 if ((res >> 26) == ALC880_HP_EVENT)
10942 alc268_aspire_one_speaker_automute(codec);
10943 if ((res >> 26) == ALC880_MIC_EVENT)
10944 alc268_acer_mic_automute(codec);
10947 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10949 alc268_aspire_one_speaker_automute(codec);
10950 alc268_acer_mic_automute(codec);
10953 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10954 /* output mixer control */
10955 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10956 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10957 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10958 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10959 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10960 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10964 static struct hda_verb alc268_dell_verbs[] = {
10965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10967 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10971 /* mute/unmute internal speaker according to the hp jack and mute state */
10972 static void alc268_dell_automute(struct hda_codec *codec)
10974 unsigned int present;
10977 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10978 if (present & 0x80000000)
10979 mute = HDA_AMP_MUTE;
10981 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10982 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10983 HDA_AMP_MUTE, mute);
10986 static void alc268_dell_unsol_event(struct hda_codec *codec,
10989 if ((res >> 26) != ALC880_HP_EVENT)
10991 alc268_dell_automute(codec);
10994 #define alc268_dell_init_hook alc268_dell_automute
10996 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10997 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10998 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10999 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11001 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11002 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11003 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11004 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11008 static struct hda_verb alc267_quanta_il1_verbs[] = {
11009 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11010 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11014 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11016 unsigned int present;
11018 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11019 & AC_PINSENSE_PRESENCE;
11020 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11021 present ? 0 : PIN_OUT);
11024 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11026 unsigned int present;
11028 present = snd_hda_codec_read(codec, 0x18, 0,
11029 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11030 snd_hda_codec_write(codec, 0x23, 0,
11031 AC_VERB_SET_CONNECT_SEL,
11032 present ? 0x00 : 0x01);
11035 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11037 alc267_quanta_il1_hp_automute(codec);
11038 alc267_quanta_il1_mic_automute(codec);
11041 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11044 switch (res >> 26) {
11045 case ALC880_HP_EVENT:
11046 alc267_quanta_il1_hp_automute(codec);
11048 case ALC880_MIC_EVENT:
11049 alc267_quanta_il1_mic_automute(codec);
11055 * generic initialization of ADC, input mixers and output mixers
11057 static struct hda_verb alc268_base_init_verbs[] = {
11058 /* Unmute DAC0-1 and set vol = 0 */
11059 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11060 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11061 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11062 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11063 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11064 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11067 * Set up output mixers (0x0c - 0x0e)
11069 /* set vol=0 to output mixers */
11070 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11072 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11073 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11075 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11076 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11078 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11080 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11082 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11083 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11084 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11085 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11089 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11090 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11092 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11093 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11095 /* set PCBEEP vol = 0, mute connections */
11096 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11097 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11098 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11100 /* Unmute Selector 23h,24h and set the default input to mic-in */
11102 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11104 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11105 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11111 * generic initialization of ADC, input mixers and output mixers
11113 static struct hda_verb alc268_volume_init_verbs[] = {
11114 /* set output DAC */
11115 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11116 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11117 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11118 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11120 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11121 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11122 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11123 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11124 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11126 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11127 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11128 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11129 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11130 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11132 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11135 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11137 /* set PCBEEP vol = 0, mute connections */
11138 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11139 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11140 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11145 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11146 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11147 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11150 /* The multiple "Capture Source" controls confuse alsamixer
11151 * So call somewhat different..
11153 /* .name = "Capture Source", */
11154 .name = "Input Source",
11156 .info = alc_mux_enum_info,
11157 .get = alc_mux_enum_get,
11158 .put = alc_mux_enum_put,
11163 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11164 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11165 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11166 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11167 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11169 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11170 /* The multiple "Capture Source" controls confuse alsamixer
11171 * So call somewhat different..
11173 /* .name = "Capture Source", */
11174 .name = "Input Source",
11176 .info = alc_mux_enum_info,
11177 .get = alc_mux_enum_get,
11178 .put = alc_mux_enum_put,
11183 static struct hda_input_mux alc268_capture_source = {
11187 { "Front Mic", 0x1 },
11193 static struct hda_input_mux alc268_acer_capture_source = {
11197 { "Internal Mic", 0x1 },
11202 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11206 { "Internal Mic", 0x6 },
11211 #ifdef CONFIG_SND_DEBUG
11212 static struct snd_kcontrol_new alc268_test_mixer[] = {
11213 /* Volume widgets */
11214 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11215 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11216 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11217 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11218 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11219 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11220 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11221 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11222 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11223 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11224 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11225 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11226 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11227 /* The below appears problematic on some hardwares */
11228 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11229 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11230 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11231 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11232 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11234 /* Modes for retasking pin widgets */
11235 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11236 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11237 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11238 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11240 /* Controls for GPIO pins, assuming they are configured as outputs */
11241 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11242 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11243 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11244 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11246 /* Switches to allow the digital SPDIF output pin to be enabled.
11247 * The ALC268 does not have an SPDIF input.
11249 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11251 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11252 * this output to turn on an external amplifier.
11254 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11255 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11261 /* create input playback/capture controls for the given pin */
11262 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11263 const char *ctlname, int idx)
11268 sprintf(name, "%s Playback Volume", ctlname);
11270 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11271 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11275 } else if (nid == 0x15) {
11276 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11277 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11283 sprintf(name, "%s Playback Switch", ctlname);
11284 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11285 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11291 /* add playback controls from the parsed DAC table */
11292 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11293 const struct auto_pin_cfg *cfg)
11298 spec->multiout.num_dacs = 2; /* only use one dac */
11299 spec->multiout.dac_nids = spec->private_dac_nids;
11300 spec->multiout.dac_nids[0] = 2;
11301 spec->multiout.dac_nids[1] = 3;
11303 nid = cfg->line_out_pins[0];
11305 alc268_new_analog_output(spec, nid, "Front", 0);
11307 nid = cfg->speaker_pins[0];
11309 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11310 "Speaker Playback Volume",
11311 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11315 nid = cfg->hp_pins[0];
11317 alc268_new_analog_output(spec, nid, "Headphone", 0);
11319 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11321 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11322 "Mono Playback Switch",
11323 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11330 /* create playback/capture controls for input pins */
11331 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11332 const struct auto_pin_cfg *cfg)
11334 struct hda_input_mux *imux = &spec->private_imux;
11337 for (i = 0; i < AUTO_PIN_LAST; i++) {
11338 switch(cfg->input_pins[i]) {
11340 idx1 = 0; /* Mic 1 */
11343 idx1 = 1; /* Mic 2 */
11346 idx1 = 2; /* Line In */
11353 idx1 = 6; /* digital mics */
11358 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11359 imux->items[imux->num_items].index = idx1;
11365 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11367 struct alc_spec *spec = codec->spec;
11368 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11369 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11370 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11371 unsigned int dac_vol1, dac_vol2;
11374 snd_hda_codec_write(codec, speaker_nid, 0,
11375 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11376 snd_hda_codec_write(codec, 0x0f, 0,
11377 AC_VERB_SET_AMP_GAIN_MUTE,
11379 snd_hda_codec_write(codec, 0x10, 0,
11380 AC_VERB_SET_AMP_GAIN_MUTE,
11383 snd_hda_codec_write(codec, 0x0f, 0,
11384 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11385 snd_hda_codec_write(codec, 0x10, 0,
11386 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11389 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11390 if (line_nid == 0x14)
11391 dac_vol2 = AMP_OUT_ZERO;
11392 else if (line_nid == 0x15)
11393 dac_vol1 = AMP_OUT_ZERO;
11394 if (hp_nid == 0x14)
11395 dac_vol2 = AMP_OUT_ZERO;
11396 else if (hp_nid == 0x15)
11397 dac_vol1 = AMP_OUT_ZERO;
11398 if (line_nid != 0x16 || hp_nid != 0x16 ||
11399 spec->autocfg.line_out_pins[1] != 0x16 ||
11400 spec->autocfg.line_out_pins[2] != 0x16)
11401 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11403 snd_hda_codec_write(codec, 0x02, 0,
11404 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11405 snd_hda_codec_write(codec, 0x03, 0,
11406 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11409 /* pcm configuration: identiacal with ALC880 */
11410 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11411 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11412 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11413 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11416 * BIOS auto configuration
11418 static int alc268_parse_auto_config(struct hda_codec *codec)
11420 struct alc_spec *spec = codec->spec;
11422 static hda_nid_t alc268_ignore[] = { 0 };
11424 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11428 if (!spec->autocfg.line_outs)
11429 return 0; /* can't find valid BIOS pin config */
11431 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11434 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11438 spec->multiout.max_channels = 2;
11440 /* digital only support output */
11441 if (spec->autocfg.dig_out_pin)
11442 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11444 if (spec->kctls.list)
11445 add_mixer(spec, spec->kctls.list);
11447 if (spec->autocfg.speaker_pins[0] != 0x1d)
11448 add_mixer(spec, alc268_beep_mixer);
11450 add_verb(spec, alc268_volume_init_verbs);
11451 spec->num_mux_defs = 1;
11452 spec->input_mux = &spec->private_imux;
11454 err = alc_auto_add_mic_boost(codec);
11458 store_pin_configs(codec);
11462 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11463 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11464 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11466 /* init callback for auto-configuration model -- overriding the default init */
11467 static void alc268_auto_init(struct hda_codec *codec)
11469 struct alc_spec *spec = codec->spec;
11470 alc268_auto_init_multi_out(codec);
11471 alc268_auto_init_hp_out(codec);
11472 alc268_auto_init_mono_speaker_out(codec);
11473 alc268_auto_init_analog_input(codec);
11474 if (spec->unsol_event)
11475 alc_inithook(codec);
11479 * configuration and preset
11481 static const char *alc268_models[ALC268_MODEL_LAST] = {
11482 [ALC267_QUANTA_IL1] = "quanta-il1",
11483 [ALC268_3ST] = "3stack",
11484 [ALC268_TOSHIBA] = "toshiba",
11485 [ALC268_ACER] = "acer",
11486 [ALC268_ACER_DMIC] = "acer-dmic",
11487 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11488 [ALC268_DELL] = "dell",
11489 [ALC268_ZEPTO] = "zepto",
11490 #ifdef CONFIG_SND_DEBUG
11491 [ALC268_TEST] = "test",
11493 [ALC268_AUTO] = "auto",
11496 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11497 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11498 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11499 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11500 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11501 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11502 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11503 ALC268_ACER_ASPIRE_ONE),
11504 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11505 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11506 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11507 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11508 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11509 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11510 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11511 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11512 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11513 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11517 static struct alc_config_preset alc268_presets[] = {
11518 [ALC267_QUANTA_IL1] = {
11519 .mixers = { alc267_quanta_il1_mixer },
11520 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11521 alc267_quanta_il1_verbs },
11522 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11523 .dac_nids = alc268_dac_nids,
11524 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11525 .adc_nids = alc268_adc_nids_alt,
11527 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11528 .channel_mode = alc268_modes,
11529 .input_mux = &alc268_capture_source,
11530 .unsol_event = alc267_quanta_il1_unsol_event,
11531 .init_hook = alc267_quanta_il1_automute,
11534 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11535 alc268_beep_mixer },
11536 .init_verbs = { alc268_base_init_verbs },
11537 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11538 .dac_nids = alc268_dac_nids,
11539 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11540 .adc_nids = alc268_adc_nids_alt,
11541 .capsrc_nids = alc268_capsrc_nids,
11543 .dig_out_nid = ALC268_DIGOUT_NID,
11544 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11545 .channel_mode = alc268_modes,
11546 .input_mux = &alc268_capture_source,
11548 [ALC268_TOSHIBA] = {
11549 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11550 alc268_beep_mixer },
11551 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11552 alc268_toshiba_verbs },
11553 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11554 .dac_nids = alc268_dac_nids,
11555 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11556 .adc_nids = alc268_adc_nids_alt,
11557 .capsrc_nids = alc268_capsrc_nids,
11559 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11560 .channel_mode = alc268_modes,
11561 .input_mux = &alc268_capture_source,
11562 .unsol_event = alc268_toshiba_unsol_event,
11563 .init_hook = alc268_toshiba_automute,
11566 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11567 alc268_beep_mixer },
11568 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11569 alc268_acer_verbs },
11570 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11571 .dac_nids = alc268_dac_nids,
11572 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11573 .adc_nids = alc268_adc_nids_alt,
11574 .capsrc_nids = alc268_capsrc_nids,
11576 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11577 .channel_mode = alc268_modes,
11578 .input_mux = &alc268_acer_capture_source,
11579 .unsol_event = alc268_acer_unsol_event,
11580 .init_hook = alc268_acer_init_hook,
11582 [ALC268_ACER_DMIC] = {
11583 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11584 alc268_beep_mixer },
11585 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11586 alc268_acer_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,
11591 .capsrc_nids = alc268_capsrc_nids,
11593 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11594 .channel_mode = alc268_modes,
11595 .input_mux = &alc268_acer_dmic_capture_source,
11596 .unsol_event = alc268_acer_unsol_event,
11597 .init_hook = alc268_acer_init_hook,
11599 [ALC268_ACER_ASPIRE_ONE] = {
11600 .mixers = { alc268_acer_aspire_one_mixer,
11601 alc268_capture_alt_mixer },
11602 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11603 alc268_acer_aspire_one_verbs },
11604 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11605 .dac_nids = alc268_dac_nids,
11606 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11607 .adc_nids = alc268_adc_nids_alt,
11608 .capsrc_nids = alc268_capsrc_nids,
11610 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11611 .channel_mode = alc268_modes,
11612 .input_mux = &alc268_acer_lc_capture_source,
11613 .unsol_event = alc268_acer_lc_unsol_event,
11614 .init_hook = alc268_acer_lc_init_hook,
11617 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11618 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11619 alc268_dell_verbs },
11620 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11621 .dac_nids = alc268_dac_nids,
11623 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11624 .channel_mode = alc268_modes,
11625 .unsol_event = alc268_dell_unsol_event,
11626 .init_hook = alc268_dell_init_hook,
11627 .input_mux = &alc268_capture_source,
11630 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11631 alc268_beep_mixer },
11632 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11633 alc268_toshiba_verbs },
11634 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11635 .dac_nids = alc268_dac_nids,
11636 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11637 .adc_nids = alc268_adc_nids_alt,
11638 .capsrc_nids = alc268_capsrc_nids,
11640 .dig_out_nid = ALC268_DIGOUT_NID,
11641 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11642 .channel_mode = alc268_modes,
11643 .input_mux = &alc268_capture_source,
11644 .unsol_event = alc268_toshiba_unsol_event,
11645 .init_hook = alc268_toshiba_automute
11647 #ifdef CONFIG_SND_DEBUG
11649 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11650 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11651 alc268_volume_init_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 .dig_out_nid = ALC268_DIGOUT_NID,
11659 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11660 .channel_mode = alc268_modes,
11661 .input_mux = &alc268_capture_source,
11666 static int patch_alc268(struct hda_codec *codec)
11668 struct alc_spec *spec;
11672 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11676 codec->spec = spec;
11678 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11682 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11683 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11684 "trying auto-probe from BIOS...\n");
11685 board_config = ALC268_AUTO;
11688 if (board_config == ALC268_AUTO) {
11689 /* automatic parse from the BIOS config */
11690 err = alc268_parse_auto_config(codec);
11696 "hda_codec: Cannot set up configuration "
11697 "from BIOS. Using base mode...\n");
11698 board_config = ALC268_3ST;
11702 if (board_config != ALC268_AUTO)
11703 setup_preset(spec, &alc268_presets[board_config]);
11705 if (codec->vendor_id == 0x10ec0267) {
11706 spec->stream_name_analog = "ALC267 Analog";
11707 spec->stream_name_digital = "ALC267 Digital";
11709 spec->stream_name_analog = "ALC268 Analog";
11710 spec->stream_name_digital = "ALC268 Digital";
11713 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11714 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11715 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11717 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11719 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11720 /* override the amp caps for beep generator */
11721 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11722 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11723 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11724 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11725 (0 << AC_AMPCAP_MUTE_SHIFT));
11727 if (!spec->adc_nids && spec->input_mux) {
11728 /* check whether NID 0x07 is valid */
11729 unsigned int wcap = get_wcaps(codec, 0x07);
11733 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11734 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11735 spec->adc_nids = alc268_adc_nids_alt;
11736 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11737 add_mixer(spec, alc268_capture_alt_mixer);
11739 spec->adc_nids = alc268_adc_nids;
11740 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11741 add_mixer(spec, alc268_capture_mixer);
11743 spec->capsrc_nids = alc268_capsrc_nids;
11744 /* set default input source */
11745 for (i = 0; i < spec->num_adc_nids; i++)
11746 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11747 0, AC_VERB_SET_CONNECT_SEL,
11748 spec->input_mux->items[0].index);
11751 spec->vmaster_nid = 0x02;
11753 codec->patch_ops = alc_patch_ops;
11754 if (board_config == ALC268_AUTO)
11755 spec->init_hook = alc268_auto_init;
11761 * ALC269 channel source setting (2 channel)
11763 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11765 #define alc269_dac_nids alc260_dac_nids
11767 static hda_nid_t alc269_adc_nids[1] = {
11772 static hda_nid_t alc269_capsrc_nids[1] = {
11776 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11780 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11788 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11796 #define alc269_modes alc260_modes
11797 #define alc269_capture_source alc880_lg_lw_capture_source
11799 static struct snd_kcontrol_new alc269_base_mixer[] = {
11800 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11801 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11802 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11803 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11804 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11805 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11806 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11807 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11808 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11809 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11810 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11811 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11812 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11813 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11817 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11818 /* output mixer control */
11819 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11821 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11822 .name = "Master Playback Switch",
11823 .info = snd_hda_mixer_amp_switch_info,
11824 .get = snd_hda_mixer_amp_switch_get,
11825 .put = alc268_acer_master_sw_put,
11826 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11830 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11831 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11832 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11833 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11834 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11835 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11839 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
11840 /* output mixer control */
11841 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11844 .name = "Master Playback Switch",
11845 .info = snd_hda_mixer_amp_switch_info,
11846 .get = snd_hda_mixer_amp_switch_get,
11847 .put = alc268_acer_master_sw_put,
11848 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11851 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11853 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11854 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11855 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11856 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
11857 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
11858 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
11859 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11860 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11864 /* bind volumes of both NID 0x0c and 0x0d */
11865 static struct hda_bind_ctls alc269_epc_bind_vol = {
11866 .ops = &snd_hda_bind_vol,
11868 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11869 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11874 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11875 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11876 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11877 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11881 /* capture mixer elements */
11882 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11883 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11884 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11890 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11891 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11892 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11893 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11898 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11899 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11900 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11904 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11905 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11906 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11908 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11909 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11910 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11914 static struct hda_verb alc269_lifebook_verbs[] = {
11915 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11916 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
11917 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11918 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11919 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11921 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11922 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11924 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11928 /* toggle speaker-output according to the hp-jack state */
11929 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11931 unsigned int present;
11932 unsigned char bits;
11934 present = snd_hda_codec_read(codec, 0x15, 0,
11935 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11936 bits = present ? AMP_IN_MUTE(0) : 0;
11937 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11938 AMP_IN_MUTE(0), bits);
11939 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11940 AMP_IN_MUTE(0), bits);
11942 snd_hda_codec_write(codec, 0x20, 0,
11943 AC_VERB_SET_COEF_INDEX, 0x0c);
11944 snd_hda_codec_write(codec, 0x20, 0,
11945 AC_VERB_SET_PROC_COEF, 0x680);
11947 snd_hda_codec_write(codec, 0x20, 0,
11948 AC_VERB_SET_COEF_INDEX, 0x0c);
11949 snd_hda_codec_write(codec, 0x20, 0,
11950 AC_VERB_SET_PROC_COEF, 0x480);
11953 /* toggle speaker-output according to the hp-jacks state */
11954 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
11956 unsigned int present;
11957 unsigned char bits;
11959 /* Check laptop headphone socket */
11960 present = snd_hda_codec_read(codec, 0x15, 0,
11961 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11963 /* Check port replicator headphone socket */
11964 present |= snd_hda_codec_read(codec, 0x1a, 0,
11965 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11967 bits = present ? AMP_IN_MUTE(0) : 0;
11968 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11969 AMP_IN_MUTE(0), bits);
11970 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11971 AMP_IN_MUTE(0), bits);
11973 snd_hda_codec_write(codec, 0x20, 0,
11974 AC_VERB_SET_COEF_INDEX, 0x0c);
11975 snd_hda_codec_write(codec, 0x20, 0,
11976 AC_VERB_SET_PROC_COEF, 0x680);
11978 snd_hda_codec_write(codec, 0x20, 0,
11979 AC_VERB_SET_COEF_INDEX, 0x0c);
11980 snd_hda_codec_write(codec, 0x20, 0,
11981 AC_VERB_SET_PROC_COEF, 0x480);
11984 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11986 unsigned int present;
11988 present = snd_hda_codec_read(codec, 0x18, 0,
11989 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11990 snd_hda_codec_write(codec, 0x23, 0,
11991 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11994 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
11996 unsigned int present_laptop;
11997 unsigned int present_dock;
11999 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12000 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12002 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12003 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12005 /* Laptop mic port overrides dock mic port, design decision */
12007 snd_hda_codec_write(codec, 0x23, 0,
12008 AC_VERB_SET_CONNECT_SEL, 0x3);
12009 if (present_laptop)
12010 snd_hda_codec_write(codec, 0x23, 0,
12011 AC_VERB_SET_CONNECT_SEL, 0x0);
12012 if (!present_dock && !present_laptop)
12013 snd_hda_codec_write(codec, 0x23, 0,
12014 AC_VERB_SET_CONNECT_SEL, 0x1);
12017 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12020 if ((res >> 26) == ALC880_HP_EVENT)
12021 alc269_quanta_fl1_speaker_automute(codec);
12022 if ((res >> 26) == ALC880_MIC_EVENT)
12023 alc269_quanta_fl1_mic_automute(codec);
12026 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12029 if ((res >> 26) == ALC880_HP_EVENT)
12030 alc269_lifebook_speaker_automute(codec);
12031 if ((res >> 26) == ALC880_MIC_EVENT)
12032 alc269_lifebook_mic_autoswitch(codec);
12035 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12037 alc269_quanta_fl1_speaker_automute(codec);
12038 alc269_quanta_fl1_mic_automute(codec);
12041 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12043 alc269_lifebook_speaker_automute(codec);
12044 alc269_lifebook_mic_autoswitch(codec);
12047 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12048 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12049 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12050 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12051 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12052 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12053 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12054 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12058 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12059 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12060 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12061 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12063 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12064 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12068 /* toggle speaker-output according to the hp-jack state */
12069 static void alc269_speaker_automute(struct hda_codec *codec)
12071 unsigned int present;
12072 unsigned char bits;
12074 present = snd_hda_codec_read(codec, 0x15, 0,
12075 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12076 bits = present ? AMP_IN_MUTE(0) : 0;
12077 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12078 AMP_IN_MUTE(0), bits);
12079 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12080 AMP_IN_MUTE(0), bits);
12083 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12085 unsigned int present;
12087 present = snd_hda_codec_read(codec, 0x18, 0,
12088 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12089 snd_hda_codec_write(codec, 0x23, 0,
12090 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12093 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12095 unsigned int present;
12097 present = snd_hda_codec_read(codec, 0x18, 0,
12098 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12099 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12100 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12101 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12102 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12105 /* unsolicited event for HP jack sensing */
12106 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12109 if ((res >> 26) == ALC880_HP_EVENT)
12110 alc269_speaker_automute(codec);
12112 if ((res >> 26) == ALC880_MIC_EVENT)
12113 alc269_eeepc_dmic_automute(codec);
12116 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12118 alc269_speaker_automute(codec);
12119 alc269_eeepc_dmic_automute(codec);
12122 /* unsolicited event for HP jack sensing */
12123 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12126 if ((res >> 26) == ALC880_HP_EVENT)
12127 alc269_speaker_automute(codec);
12129 if ((res >> 26) == ALC880_MIC_EVENT)
12130 alc269_eeepc_amic_automute(codec);
12133 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12135 alc269_speaker_automute(codec);
12136 alc269_eeepc_amic_automute(codec);
12140 * generic initialization of ADC, input mixers and output mixers
12142 static struct hda_verb alc269_init_verbs[] = {
12144 * Unmute ADC0 and set the default input to mic-in
12146 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12148 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12149 * analog-loopback mixer widget
12150 * Note: PASD motherboards uses the Line In 2 as the input for
12151 * front panel mic (mic 2)
12153 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12161 * Set up output mixers (0x0c - 0x0e)
12163 /* set vol=0 to output mixers */
12164 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12165 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12167 /* set up input amps for analog loopback */
12168 /* Amp Indices: DAC = 0, mixer = 1 */
12169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12170 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12171 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12172 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12174 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12176 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12178 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12179 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12181 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12184 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12185 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12186 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12187 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12188 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12189 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12190 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12192 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12193 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12195 /* FIXME: use matrix-type input source selection */
12196 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12197 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12201 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12204 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12205 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12209 /* add playback controls from the parsed DAC table */
12210 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12211 const struct auto_pin_cfg *cfg)
12216 spec->multiout.num_dacs = 1; /* only use one dac */
12217 spec->multiout.dac_nids = spec->private_dac_nids;
12218 spec->multiout.dac_nids[0] = 2;
12220 nid = cfg->line_out_pins[0];
12222 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12223 "Front Playback Volume",
12224 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12227 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12228 "Front Playback Switch",
12229 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12234 nid = cfg->speaker_pins[0];
12236 if (!cfg->line_out_pins[0]) {
12237 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12238 "Speaker Playback Volume",
12239 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12245 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12246 "Speaker Playback Switch",
12247 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12252 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12253 "Speaker Playback Switch",
12254 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12260 nid = cfg->hp_pins[0];
12262 /* spec->multiout.hp_nid = 2; */
12263 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12264 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12265 "Headphone Playback Volume",
12266 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12272 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12273 "Headphone Playback Switch",
12274 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12279 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12280 "Headphone Playback Switch",
12281 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12290 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12291 const struct auto_pin_cfg *cfg)
12295 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12298 /* digital-mic input pin is excluded in alc880_auto_create..()
12299 * because it's under 0x18
12301 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12302 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12303 struct hda_input_mux *imux = &spec->private_imux;
12304 imux->items[imux->num_items].label = "Int Mic";
12305 imux->items[imux->num_items].index = 0x05;
12311 #ifdef CONFIG_SND_HDA_POWER_SAVE
12312 #define alc269_loopbacks alc880_loopbacks
12315 /* pcm configuration: identiacal with ALC880 */
12316 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12317 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12318 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12319 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12322 * BIOS auto configuration
12324 static int alc269_parse_auto_config(struct hda_codec *codec)
12326 struct alc_spec *spec = codec->spec;
12328 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12330 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12335 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12338 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12342 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12344 if (spec->autocfg.dig_out_pin)
12345 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12347 if (spec->kctls.list)
12348 add_mixer(spec, spec->kctls.list);
12350 /* create a beep mixer control if the pin 0x1d isn't assigned */
12351 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12352 if (spec->autocfg.input_pins[i] == 0x1d)
12354 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12355 add_mixer(spec, alc269_beep_mixer);
12357 add_verb(spec, alc269_init_verbs);
12358 spec->num_mux_defs = 1;
12359 spec->input_mux = &spec->private_imux;
12360 /* set default input source */
12361 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12362 0, AC_VERB_SET_CONNECT_SEL,
12363 spec->input_mux->items[0].index);
12365 err = alc_auto_add_mic_boost(codec);
12369 if (!spec->cap_mixer)
12370 set_capture_mixer(spec);
12372 store_pin_configs(codec);
12376 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12377 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12378 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12381 /* init callback for auto-configuration model -- overriding the default init */
12382 static void alc269_auto_init(struct hda_codec *codec)
12384 struct alc_spec *spec = codec->spec;
12385 alc269_auto_init_multi_out(codec);
12386 alc269_auto_init_hp_out(codec);
12387 alc269_auto_init_analog_input(codec);
12388 if (spec->unsol_event)
12389 alc_inithook(codec);
12393 * configuration and preset
12395 static const char *alc269_models[ALC269_MODEL_LAST] = {
12396 [ALC269_BASIC] = "basic",
12397 [ALC269_QUANTA_FL1] = "quanta",
12398 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12399 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12400 [ALC269_FUJITSU] = "fujitsu",
12401 [ALC269_LIFEBOOK] = "lifebook"
12404 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12405 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12406 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12407 ALC269_ASUS_EEEPC_P703),
12408 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12409 ALC269_ASUS_EEEPC_P901),
12410 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12411 ALC269_ASUS_EEEPC_P901),
12412 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12413 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12417 static struct alc_config_preset alc269_presets[] = {
12419 .mixers = { alc269_base_mixer },
12420 .init_verbs = { alc269_init_verbs },
12421 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12422 .dac_nids = alc269_dac_nids,
12424 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12425 .channel_mode = alc269_modes,
12426 .input_mux = &alc269_capture_source,
12428 [ALC269_QUANTA_FL1] = {
12429 .mixers = { alc269_quanta_fl1_mixer },
12430 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12431 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12432 .dac_nids = alc269_dac_nids,
12434 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12435 .channel_mode = alc269_modes,
12436 .input_mux = &alc269_capture_source,
12437 .unsol_event = alc269_quanta_fl1_unsol_event,
12438 .init_hook = alc269_quanta_fl1_init_hook,
12440 [ALC269_ASUS_EEEPC_P703] = {
12441 .mixers = { alc269_eeepc_mixer },
12442 .cap_mixer = alc269_epc_capture_mixer,
12443 .init_verbs = { alc269_init_verbs,
12444 alc269_eeepc_amic_init_verbs },
12445 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12446 .dac_nids = alc269_dac_nids,
12448 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12449 .channel_mode = alc269_modes,
12450 .input_mux = &alc269_eeepc_amic_capture_source,
12451 .unsol_event = alc269_eeepc_amic_unsol_event,
12452 .init_hook = alc269_eeepc_amic_inithook,
12454 [ALC269_ASUS_EEEPC_P901] = {
12455 .mixers = { alc269_eeepc_mixer },
12456 .cap_mixer = alc269_epc_capture_mixer,
12457 .init_verbs = { alc269_init_verbs,
12458 alc269_eeepc_dmic_init_verbs },
12459 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12460 .dac_nids = alc269_dac_nids,
12462 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12463 .channel_mode = alc269_modes,
12464 .input_mux = &alc269_eeepc_dmic_capture_source,
12465 .unsol_event = alc269_eeepc_dmic_unsol_event,
12466 .init_hook = alc269_eeepc_dmic_inithook,
12468 [ALC269_FUJITSU] = {
12469 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12470 .cap_mixer = alc269_epc_capture_mixer,
12471 .init_verbs = { alc269_init_verbs,
12472 alc269_eeepc_dmic_init_verbs },
12473 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12474 .dac_nids = alc269_dac_nids,
12476 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12477 .channel_mode = alc269_modes,
12478 .input_mux = &alc269_eeepc_dmic_capture_source,
12479 .unsol_event = alc269_eeepc_dmic_unsol_event,
12480 .init_hook = alc269_eeepc_dmic_inithook,
12482 [ALC269_LIFEBOOK] = {
12483 .mixers = { alc269_lifebook_mixer },
12484 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12485 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12486 .dac_nids = alc269_dac_nids,
12488 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12489 .channel_mode = alc269_modes,
12490 .input_mux = &alc269_capture_source,
12491 .unsol_event = alc269_lifebook_unsol_event,
12492 .init_hook = alc269_lifebook_init_hook,
12496 static int patch_alc269(struct hda_codec *codec)
12498 struct alc_spec *spec;
12502 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12506 codec->spec = spec;
12508 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12510 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12514 if (board_config < 0) {
12515 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12516 "trying auto-probe from BIOS...\n");
12517 board_config = ALC269_AUTO;
12520 if (board_config == ALC269_AUTO) {
12521 /* automatic parse from the BIOS config */
12522 err = alc269_parse_auto_config(codec);
12528 "hda_codec: Cannot set up configuration "
12529 "from BIOS. Using base mode...\n");
12530 board_config = ALC269_BASIC;
12534 if (board_config != ALC269_AUTO)
12535 setup_preset(spec, &alc269_presets[board_config]);
12537 spec->stream_name_analog = "ALC269 Analog";
12538 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12539 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12541 spec->stream_name_digital = "ALC269 Digital";
12542 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12543 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12545 spec->adc_nids = alc269_adc_nids;
12546 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12547 spec->capsrc_nids = alc269_capsrc_nids;
12548 if (!spec->cap_mixer)
12549 set_capture_mixer(spec);
12551 codec->patch_ops = alc_patch_ops;
12552 if (board_config == ALC269_AUTO)
12553 spec->init_hook = alc269_auto_init;
12554 #ifdef CONFIG_SND_HDA_POWER_SAVE
12555 if (!spec->loopback.amplist)
12556 spec->loopback.amplist = alc269_loopbacks;
12563 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12567 * set the path ways for 2 channel output
12568 * need to set the codec line out and mic 1 pin widgets to inputs
12570 static struct hda_verb alc861_threestack_ch2_init[] = {
12571 /* set pin widget 1Ah (line in) for input */
12572 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12573 /* set pin widget 18h (mic1/2) for input, for mic also enable
12576 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12578 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12580 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12581 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12587 * need to set the codec line out and mic 1 pin widgets to outputs
12589 static struct hda_verb alc861_threestack_ch6_init[] = {
12590 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12591 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12592 /* set pin widget 18h (mic1) for output (CLFE)*/
12593 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12595 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12596 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12598 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12600 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12601 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12606 static struct hda_channel_mode alc861_threestack_modes[2] = {
12607 { 2, alc861_threestack_ch2_init },
12608 { 6, alc861_threestack_ch6_init },
12610 /* Set mic1 as input and unmute the mixer */
12611 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12612 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12613 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12616 /* Set mic1 as output and mute mixer */
12617 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12618 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12619 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12623 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12624 { 2, alc861_uniwill_m31_ch2_init },
12625 { 4, alc861_uniwill_m31_ch4_init },
12628 /* Set mic1 and line-in as input and unmute the mixer */
12629 static struct hda_verb alc861_asus_ch2_init[] = {
12630 /* set pin widget 1Ah (line in) for input */
12631 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12632 /* set pin widget 18h (mic1/2) for input, for mic also enable
12635 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12637 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12639 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12640 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12644 /* Set mic1 nad line-in as output and mute mixer */
12645 static struct hda_verb alc861_asus_ch6_init[] = {
12646 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12647 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12648 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12649 /* set pin widget 18h (mic1) for output (CLFE)*/
12650 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12651 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12652 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12653 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12655 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12657 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12658 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12663 static struct hda_channel_mode alc861_asus_modes[2] = {
12664 { 2, alc861_asus_ch2_init },
12665 { 6, alc861_asus_ch6_init },
12670 static struct snd_kcontrol_new alc861_base_mixer[] = {
12671 /* output mixer control */
12672 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12673 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12674 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12675 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12676 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12678 /*Input mixer control */
12679 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12680 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12681 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12682 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12683 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12684 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12686 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12687 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12693 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12694 /* output mixer control */
12695 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12696 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12697 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12698 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12699 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12701 /* Input mixer control */
12702 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12703 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12704 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12705 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12706 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12707 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12709 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12710 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12711 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
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_threestack_modes),
12724 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12725 /* output mixer control */
12726 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12728 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12733 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12734 /* output mixer control */
12735 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12736 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12737 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12738 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12739 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12741 /* Input mixer control */
12742 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12743 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12744 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12745 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12746 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12747 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12749 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12750 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12751 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12755 .name = "Channel Mode",
12756 .info = alc_ch_mode_info,
12757 .get = alc_ch_mode_get,
12758 .put = alc_ch_mode_put,
12759 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12764 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12765 /* output mixer control */
12766 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12767 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12768 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12769 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12770 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12772 /* Input mixer control */
12773 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12774 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12775 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12776 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12777 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12778 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12780 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12781 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12786 .name = "Channel Mode",
12787 .info = alc_ch_mode_info,
12788 .get = alc_ch_mode_get,
12789 .put = alc_ch_mode_put,
12790 .private_value = ARRAY_SIZE(alc861_asus_modes),
12795 /* additional mixer */
12796 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12797 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12798 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12799 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12800 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12805 * generic initialization of ADC, input mixers and output mixers
12807 static struct hda_verb alc861_base_init_verbs[] = {
12809 * Unmute ADC0 and set the default input to mic-in
12811 /* port-A for surround (rear panel) */
12812 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12813 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12814 /* port-B for mic-in (rear panel) with vref */
12815 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12816 /* port-C for line-in (rear panel) */
12817 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12818 /* port-D for Front */
12819 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12820 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12821 /* port-E for HP out (front panel) */
12822 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12823 /* route front PCM to HP */
12824 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12825 /* port-F for mic-in (front panel) with vref */
12826 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12827 /* port-G for CLFE (rear panel) */
12828 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12829 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12830 /* port-H for side (rear panel) */
12831 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12832 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12834 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12835 /* route front mic to ADC1*/
12836 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12837 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12839 /* Unmute DAC0~3 & spdif out*/
12840 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12841 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12842 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12843 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12846 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12847 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12848 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12849 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12850 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12852 /* Unmute Stereo Mixer 15 */
12853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12858 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12859 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12860 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12861 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12862 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12863 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12864 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12866 /* hp used DAC 3 (Front) */
12867 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12868 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12873 static struct hda_verb alc861_threestack_init_verbs[] = {
12875 * Unmute ADC0 and set the default input to mic-in
12877 /* port-A for surround (rear panel) */
12878 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12879 /* port-B for mic-in (rear panel) with vref */
12880 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12881 /* port-C for line-in (rear panel) */
12882 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12883 /* port-D for Front */
12884 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12885 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12886 /* port-E for HP out (front panel) */
12887 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12888 /* route front PCM to HP */
12889 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12890 /* port-F for mic-in (front panel) with vref */
12891 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12892 /* port-G for CLFE (rear panel) */
12893 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12894 /* port-H for side (rear panel) */
12895 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12897 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12898 /* route front mic to ADC1*/
12899 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12900 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12901 /* Unmute DAC0~3 & spdif out*/
12902 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12903 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12904 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12905 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12906 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12908 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12909 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12910 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12911 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12912 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12914 /* Unmute Stereo Mixer 15 */
12915 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12920 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12921 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12922 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12923 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12925 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12927 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12928 /* hp used DAC 3 (Front) */
12929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12930 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12934 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12936 * Unmute ADC0 and set the default input to mic-in
12938 /* port-A for surround (rear panel) */
12939 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12940 /* port-B for mic-in (rear panel) with vref */
12941 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12942 /* port-C for line-in (rear panel) */
12943 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12944 /* port-D for Front */
12945 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12946 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12947 /* port-E for HP out (front panel) */
12948 /* this has to be set to VREF80 */
12949 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12950 /* route front PCM to HP */
12951 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12952 /* port-F for mic-in (front panel) with vref */
12953 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12954 /* port-G for CLFE (rear panel) */
12955 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12956 /* port-H for side (rear panel) */
12957 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12959 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12960 /* route front mic to ADC1*/
12961 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12962 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12963 /* Unmute DAC0~3 & spdif out*/
12964 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12965 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12966 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12967 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12970 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12971 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12972 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12973 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12974 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12976 /* Unmute Stereo Mixer 15 */
12977 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12979 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12980 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12982 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12983 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12984 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12985 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12986 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12987 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12988 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12989 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12990 /* hp used DAC 3 (Front) */
12991 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12992 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12996 static struct hda_verb alc861_asus_init_verbs[] = {
12998 * Unmute ADC0 and set the default input to mic-in
13000 /* port-A for surround (rear panel)
13001 * according to codec#0 this is the HP jack
13003 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13004 /* route front PCM to HP */
13005 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13006 /* port-B for mic-in (rear panel) with vref */
13007 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13008 /* port-C for line-in (rear panel) */
13009 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13010 /* port-D for Front */
13011 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13012 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13013 /* port-E for HP out (front panel) */
13014 /* this has to be set to VREF80 */
13015 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13016 /* route front PCM to HP */
13017 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13018 /* port-F for mic-in (front panel) with vref */
13019 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13020 /* port-G for CLFE (rear panel) */
13021 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13022 /* port-H for side (rear panel) */
13023 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13025 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13026 /* route front mic to ADC1*/
13027 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13029 /* Unmute DAC0~3 & spdif out*/
13030 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13031 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13032 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13033 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13034 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13035 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13036 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13037 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13038 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13039 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13041 /* Unmute Stereo Mixer 15 */
13042 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13043 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13047 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13048 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13049 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13050 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13051 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13053 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13054 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13055 /* hp used DAC 3 (Front) */
13056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13057 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13061 /* additional init verbs for ASUS laptops */
13062 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13063 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13064 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13069 * generic initialization of ADC, input mixers and output mixers
13071 static struct hda_verb alc861_auto_init_verbs[] = {
13073 * Unmute ADC0 and set the default input to mic-in
13075 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13076 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13078 /* Unmute DAC0~3 & spdif out*/
13079 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13080 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13081 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13082 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13085 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13086 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13087 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13088 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13089 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13091 /* Unmute Stereo Mixer 15 */
13092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13094 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13095 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13097 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13098 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13099 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13100 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13101 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13102 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13103 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13104 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13106 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13107 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13108 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13109 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13110 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13111 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13112 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13113 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13115 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13120 static struct hda_verb alc861_toshiba_init_verbs[] = {
13121 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13126 /* toggle speaker-output according to the hp-jack state */
13127 static void alc861_toshiba_automute(struct hda_codec *codec)
13129 unsigned int present;
13131 present = snd_hda_codec_read(codec, 0x0f, 0,
13132 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13133 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13134 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13135 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13136 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13139 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13142 if ((res >> 26) == ALC880_HP_EVENT)
13143 alc861_toshiba_automute(codec);
13146 /* pcm configuration: identiacal with ALC880 */
13147 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13148 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13149 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13150 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13153 #define ALC861_DIGOUT_NID 0x07
13155 static struct hda_channel_mode alc861_8ch_modes[1] = {
13159 static hda_nid_t alc861_dac_nids[4] = {
13160 /* front, surround, clfe, side */
13161 0x03, 0x06, 0x05, 0x04
13164 static hda_nid_t alc660_dac_nids[3] = {
13165 /* front, clfe, surround */
13169 static hda_nid_t alc861_adc_nids[1] = {
13174 static struct hda_input_mux alc861_capture_source = {
13178 { "Front Mic", 0x3 },
13185 /* fill in the dac_nids table from the parsed pin configuration */
13186 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13187 const struct auto_pin_cfg *cfg)
13192 spec->multiout.dac_nids = spec->private_dac_nids;
13193 for (i = 0; i < cfg->line_outs; i++) {
13194 nid = cfg->line_out_pins[i];
13196 if (i >= ARRAY_SIZE(alc861_dac_nids))
13198 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13201 spec->multiout.num_dacs = cfg->line_outs;
13205 /* add playback controls from the parsed DAC table */
13206 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13207 const struct auto_pin_cfg *cfg)
13210 static const char *chname[4] = {
13211 "Front", "Surround", NULL /*CLFE*/, "Side"
13216 for (i = 0; i < cfg->line_outs; i++) {
13217 nid = spec->multiout.dac_nids[i];
13222 err = add_control(spec, ALC_CTL_BIND_MUTE,
13223 "Center Playback Switch",
13224 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13228 err = add_control(spec, ALC_CTL_BIND_MUTE,
13229 "LFE Playback Switch",
13230 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13235 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13237 if (nid == alc861_dac_nids[idx])
13239 sprintf(name, "%s Playback Switch", chname[idx]);
13240 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13241 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13250 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13258 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13260 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13261 "Headphone Playback Switch",
13262 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13265 spec->multiout.hp_nid = nid;
13270 /* create playback/capture controls for input pins */
13271 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13272 const struct auto_pin_cfg *cfg)
13274 struct hda_input_mux *imux = &spec->private_imux;
13275 int i, err, idx, idx1;
13277 for (i = 0; i < AUTO_PIN_LAST; i++) {
13278 switch (cfg->input_pins[i]) {
13281 idx = 2; /* Line In */
13285 idx = 2; /* Line In */
13289 idx = 1; /* Mic In */
13293 idx = 1; /* Mic In */
13303 err = new_analog_input(spec, cfg->input_pins[i],
13304 auto_pin_cfg_labels[i], idx, 0x15);
13308 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13309 imux->items[imux->num_items].index = idx1;
13315 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13317 int pin_type, int dac_idx)
13319 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13321 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13325 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13327 struct alc_spec *spec = codec->spec;
13330 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13331 for (i = 0; i < spec->autocfg.line_outs; i++) {
13332 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13333 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13335 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13336 spec->multiout.dac_nids[i]);
13340 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13342 struct alc_spec *spec = codec->spec;
13345 pin = spec->autocfg.hp_pins[0];
13346 if (pin) /* connect to front */
13347 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13348 spec->multiout.dac_nids[0]);
13349 pin = spec->autocfg.speaker_pins[0];
13351 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13354 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13356 struct alc_spec *spec = codec->spec;
13359 for (i = 0; i < AUTO_PIN_LAST; i++) {
13360 hda_nid_t nid = spec->autocfg.input_pins[i];
13361 if (nid >= 0x0c && nid <= 0x11) {
13362 snd_hda_codec_write(codec, nid, 0,
13363 AC_VERB_SET_PIN_WIDGET_CONTROL,
13364 i <= AUTO_PIN_FRONT_MIC ?
13365 PIN_VREF80 : PIN_IN);
13370 /* parse the BIOS configuration and set up the alc_spec */
13371 /* return 1 if successful, 0 if the proper config is not found,
13372 * or a negative error code
13374 static int alc861_parse_auto_config(struct hda_codec *codec)
13376 struct alc_spec *spec = codec->spec;
13378 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13380 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13384 if (!spec->autocfg.line_outs)
13385 return 0; /* can't find valid BIOS pin config */
13387 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13390 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13393 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13396 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13400 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13402 if (spec->autocfg.dig_out_pin)
13403 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13405 if (spec->kctls.list)
13406 add_mixer(spec, spec->kctls.list);
13408 add_verb(spec, alc861_auto_init_verbs);
13410 spec->num_mux_defs = 1;
13411 spec->input_mux = &spec->private_imux;
13413 spec->adc_nids = alc861_adc_nids;
13414 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13415 set_capture_mixer(spec);
13417 store_pin_configs(codec);
13421 /* additional initialization for auto-configuration model */
13422 static void alc861_auto_init(struct hda_codec *codec)
13424 struct alc_spec *spec = codec->spec;
13425 alc861_auto_init_multi_out(codec);
13426 alc861_auto_init_hp_out(codec);
13427 alc861_auto_init_analog_input(codec);
13428 if (spec->unsol_event)
13429 alc_inithook(codec);
13432 #ifdef CONFIG_SND_HDA_POWER_SAVE
13433 static struct hda_amp_list alc861_loopbacks[] = {
13434 { 0x15, HDA_INPUT, 0 },
13435 { 0x15, HDA_INPUT, 1 },
13436 { 0x15, HDA_INPUT, 2 },
13437 { 0x15, HDA_INPUT, 3 },
13444 * configuration and preset
13446 static const char *alc861_models[ALC861_MODEL_LAST] = {
13447 [ALC861_3ST] = "3stack",
13448 [ALC660_3ST] = "3stack-660",
13449 [ALC861_3ST_DIG] = "3stack-dig",
13450 [ALC861_6ST_DIG] = "6stack-dig",
13451 [ALC861_UNIWILL_M31] = "uniwill-m31",
13452 [ALC861_TOSHIBA] = "toshiba",
13453 [ALC861_ASUS] = "asus",
13454 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13455 [ALC861_AUTO] = "auto",
13458 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13459 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13460 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13461 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13462 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13463 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13464 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13465 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13466 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13467 * Any other models that need this preset?
13469 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13470 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13471 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13472 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13473 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13474 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13475 /* FIXME: the below seems conflict */
13476 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13477 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13478 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13482 static struct alc_config_preset alc861_presets[] = {
13484 .mixers = { alc861_3ST_mixer },
13485 .init_verbs = { alc861_threestack_init_verbs },
13486 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13487 .dac_nids = alc861_dac_nids,
13488 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13489 .channel_mode = alc861_threestack_modes,
13491 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13492 .adc_nids = alc861_adc_nids,
13493 .input_mux = &alc861_capture_source,
13495 [ALC861_3ST_DIG] = {
13496 .mixers = { alc861_base_mixer },
13497 .init_verbs = { alc861_threestack_init_verbs },
13498 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13499 .dac_nids = alc861_dac_nids,
13500 .dig_out_nid = ALC861_DIGOUT_NID,
13501 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13502 .channel_mode = alc861_threestack_modes,
13504 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13505 .adc_nids = alc861_adc_nids,
13506 .input_mux = &alc861_capture_source,
13508 [ALC861_6ST_DIG] = {
13509 .mixers = { alc861_base_mixer },
13510 .init_verbs = { alc861_base_init_verbs },
13511 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13512 .dac_nids = alc861_dac_nids,
13513 .dig_out_nid = ALC861_DIGOUT_NID,
13514 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13515 .channel_mode = alc861_8ch_modes,
13516 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13517 .adc_nids = alc861_adc_nids,
13518 .input_mux = &alc861_capture_source,
13521 .mixers = { alc861_3ST_mixer },
13522 .init_verbs = { alc861_threestack_init_verbs },
13523 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13524 .dac_nids = alc660_dac_nids,
13525 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13526 .channel_mode = alc861_threestack_modes,
13528 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13529 .adc_nids = alc861_adc_nids,
13530 .input_mux = &alc861_capture_source,
13532 [ALC861_UNIWILL_M31] = {
13533 .mixers = { alc861_uniwill_m31_mixer },
13534 .init_verbs = { alc861_uniwill_m31_init_verbs },
13535 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13536 .dac_nids = alc861_dac_nids,
13537 .dig_out_nid = ALC861_DIGOUT_NID,
13538 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13539 .channel_mode = alc861_uniwill_m31_modes,
13541 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13542 .adc_nids = alc861_adc_nids,
13543 .input_mux = &alc861_capture_source,
13545 [ALC861_TOSHIBA] = {
13546 .mixers = { alc861_toshiba_mixer },
13547 .init_verbs = { alc861_base_init_verbs,
13548 alc861_toshiba_init_verbs },
13549 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13550 .dac_nids = alc861_dac_nids,
13551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13552 .channel_mode = alc883_3ST_2ch_modes,
13553 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13554 .adc_nids = alc861_adc_nids,
13555 .input_mux = &alc861_capture_source,
13556 .unsol_event = alc861_toshiba_unsol_event,
13557 .init_hook = alc861_toshiba_automute,
13560 .mixers = { alc861_asus_mixer },
13561 .init_verbs = { alc861_asus_init_verbs },
13562 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13563 .dac_nids = alc861_dac_nids,
13564 .dig_out_nid = ALC861_DIGOUT_NID,
13565 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13566 .channel_mode = alc861_asus_modes,
13569 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13570 .adc_nids = alc861_adc_nids,
13571 .input_mux = &alc861_capture_source,
13573 [ALC861_ASUS_LAPTOP] = {
13574 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13575 .init_verbs = { alc861_asus_init_verbs,
13576 alc861_asus_laptop_init_verbs },
13577 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13578 .dac_nids = alc861_dac_nids,
13579 .dig_out_nid = ALC861_DIGOUT_NID,
13580 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13581 .channel_mode = alc883_3ST_2ch_modes,
13583 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13584 .adc_nids = alc861_adc_nids,
13585 .input_mux = &alc861_capture_source,
13590 static int patch_alc861(struct hda_codec *codec)
13592 struct alc_spec *spec;
13596 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13600 codec->spec = spec;
13602 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13606 if (board_config < 0) {
13607 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13608 "trying auto-probe from BIOS...\n");
13609 board_config = ALC861_AUTO;
13612 if (board_config == ALC861_AUTO) {
13613 /* automatic parse from the BIOS config */
13614 err = alc861_parse_auto_config(codec);
13620 "hda_codec: Cannot set up configuration "
13621 "from BIOS. Using base mode...\n");
13622 board_config = ALC861_3ST_DIG;
13626 if (board_config != ALC861_AUTO)
13627 setup_preset(spec, &alc861_presets[board_config]);
13629 spec->stream_name_analog = "ALC861 Analog";
13630 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13631 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13633 spec->stream_name_digital = "ALC861 Digital";
13634 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13635 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13637 spec->vmaster_nid = 0x03;
13639 codec->patch_ops = alc_patch_ops;
13640 if (board_config == ALC861_AUTO)
13641 spec->init_hook = alc861_auto_init;
13642 #ifdef CONFIG_SND_HDA_POWER_SAVE
13643 if (!spec->loopback.amplist)
13644 spec->loopback.amplist = alc861_loopbacks;
13651 * ALC861-VD support
13655 * In addition, an independent DAC
13657 #define ALC861VD_DIGOUT_NID 0x06
13659 static hda_nid_t alc861vd_dac_nids[4] = {
13660 /* front, surr, clfe, side surr */
13661 0x02, 0x03, 0x04, 0x05
13664 /* dac_nids for ALC660vd are in a different order - according to
13665 * Realtek's driver.
13666 * This should probably tesult in a different mixer for 6stack models
13667 * of ALC660vd codecs, but for now there is only 3stack mixer
13668 * - and it is the same as in 861vd.
13669 * adc_nids in ALC660vd are (is) the same as in 861vd
13671 static hda_nid_t alc660vd_dac_nids[3] = {
13672 /* front, rear, clfe, rear_surr */
13676 static hda_nid_t alc861vd_adc_nids[1] = {
13681 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13684 /* FIXME: should be a matrix-type input source selection */
13685 static struct hda_input_mux alc861vd_capture_source = {
13689 { "Front Mic", 0x1 },
13695 static struct hda_input_mux alc861vd_dallas_capture_source = {
13698 { "Ext Mic", 0x0 },
13699 { "Int Mic", 0x1 },
13703 static struct hda_input_mux alc861vd_hp_capture_source = {
13706 { "Front Mic", 0x0 },
13707 { "ATAPI Mic", 0x1 },
13714 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13721 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13722 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13723 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13724 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13725 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13732 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13733 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13734 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13735 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13736 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13740 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13741 { 6, alc861vd_6stack_ch6_init },
13742 { 8, alc861vd_6stack_ch8_init },
13745 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13747 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13748 .name = "Channel Mode",
13749 .info = alc_ch_mode_info,
13750 .get = alc_ch_mode_get,
13751 .put = alc_ch_mode_put,
13756 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13757 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13759 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13760 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13761 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13763 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13764 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13766 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13768 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13770 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13771 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13773 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13774 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13778 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13782 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13783 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13784 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13786 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13787 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13789 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13790 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13792 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13793 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13798 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13799 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13800 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13802 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13804 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13808 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13809 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13810 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13812 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13813 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13815 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13816 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13818 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13819 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13824 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13825 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13826 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13827 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13835 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13836 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13839 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13840 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13845 /* Pin assignment: Speaker=0x14, HP = 0x15,
13846 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13848 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13849 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13850 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13851 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13852 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13853 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13854 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13855 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13856 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13857 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13858 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13859 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13860 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13864 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13865 * Front Mic=0x18, ATAPI Mic = 0x19,
13867 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13868 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13869 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13870 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13871 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13872 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13873 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13874 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13875 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13881 * generic initialization of ADC, input mixers and output mixers
13883 static struct hda_verb alc861vd_volume_init_verbs[] = {
13885 * Unmute ADC0 and set the default input to mic-in
13887 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13888 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13890 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13891 * the analog-loopback mixer widget
13893 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13897 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13898 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13900 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13901 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13902 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13903 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13904 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13907 * Set up output mixers (0x02 - 0x05)
13909 /* set vol=0 to output mixers */
13910 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13911 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13912 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13913 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13915 /* set up input amps for analog loopback */
13916 /* Amp Indices: DAC = 0, mixer = 1 */
13917 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13918 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13919 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13920 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13921 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13922 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13923 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13924 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13930 * 3-stack pin configuration:
13931 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13933 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13935 * Set pin mode and muting
13937 /* set front pin widgets 0x14 for output */
13938 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13939 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13940 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13942 /* Mic (rear) pin: input vref at 80% */
13943 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13944 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13945 /* Front Mic pin: input vref at 80% */
13946 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13947 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13948 /* Line In pin: input */
13949 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13950 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13951 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13952 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13953 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13954 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13955 /* CD pin widget for input */
13956 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13962 * 6-stack pin configuration:
13964 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13966 * Set pin mode and muting
13968 /* set front pin widgets 0x14 for output */
13969 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13971 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13973 /* Rear Pin: output 1 (0x0d) */
13974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13975 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13976 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13977 /* CLFE Pin: output 2 (0x0e) */
13978 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13979 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13980 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13981 /* Side Pin: output 3 (0x0f) */
13982 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13983 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13984 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13986 /* Mic (rear) pin: input vref at 80% */
13987 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13988 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13989 /* Front Mic pin: input vref at 80% */
13990 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13991 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13992 /* Line In pin: input */
13993 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13994 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13995 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13997 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13998 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13999 /* CD pin widget for input */
14000 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14005 static struct hda_verb alc861vd_eapd_verbs[] = {
14006 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14010 static struct hda_verb alc660vd_eapd_verbs[] = {
14011 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14012 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14016 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14020 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14021 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14025 /* toggle speaker-output according to the hp-jack state */
14026 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14028 unsigned int present;
14029 unsigned char bits;
14031 present = snd_hda_codec_read(codec, 0x1b, 0,
14032 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14033 bits = present ? HDA_AMP_MUTE : 0;
14034 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14035 HDA_AMP_MUTE, bits);
14038 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14040 unsigned int present;
14041 unsigned char bits;
14043 present = snd_hda_codec_read(codec, 0x18, 0,
14044 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14045 bits = present ? HDA_AMP_MUTE : 0;
14046 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14047 HDA_AMP_MUTE, bits);
14050 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14052 alc861vd_lenovo_hp_automute(codec);
14053 alc861vd_lenovo_mic_automute(codec);
14056 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14059 switch (res >> 26) {
14060 case ALC880_HP_EVENT:
14061 alc861vd_lenovo_hp_automute(codec);
14063 case ALC880_MIC_EVENT:
14064 alc861vd_lenovo_mic_automute(codec);
14069 static struct hda_verb alc861vd_dallas_verbs[] = {
14070 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14071 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14072 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14073 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14081 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14084 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14086 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14087 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14089 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14090 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14091 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14093 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14094 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14095 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14097 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14098 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14099 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14100 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14105 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14107 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14109 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14114 /* toggle speaker-output according to the hp-jack state */
14115 static void alc861vd_dallas_automute(struct hda_codec *codec)
14117 unsigned int present;
14119 present = snd_hda_codec_read(codec, 0x15, 0,
14120 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14121 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14122 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14125 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14127 if ((res >> 26) == ALC880_HP_EVENT)
14128 alc861vd_dallas_automute(codec);
14131 #ifdef CONFIG_SND_HDA_POWER_SAVE
14132 #define alc861vd_loopbacks alc880_loopbacks
14135 /* pcm configuration: identiacal with ALC880 */
14136 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14137 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14138 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14139 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14142 * configuration and preset
14144 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14145 [ALC660VD_3ST] = "3stack-660",
14146 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14147 [ALC660VD_ASUS_V1S] = "asus-v1s",
14148 [ALC861VD_3ST] = "3stack",
14149 [ALC861VD_3ST_DIG] = "3stack-digout",
14150 [ALC861VD_6ST_DIG] = "6stack-digout",
14151 [ALC861VD_LENOVO] = "lenovo",
14152 [ALC861VD_DALLAS] = "dallas",
14153 [ALC861VD_HP] = "hp",
14154 [ALC861VD_AUTO] = "auto",
14157 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14158 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14159 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14160 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14161 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14162 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14163 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14164 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14165 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14166 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14167 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14168 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14169 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14170 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14171 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14172 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14173 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14174 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14178 static struct alc_config_preset alc861vd_presets[] = {
14180 .mixers = { alc861vd_3st_mixer },
14181 .init_verbs = { alc861vd_volume_init_verbs,
14182 alc861vd_3stack_init_verbs },
14183 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14184 .dac_nids = alc660vd_dac_nids,
14185 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14186 .channel_mode = alc861vd_3stack_2ch_modes,
14187 .input_mux = &alc861vd_capture_source,
14189 [ALC660VD_3ST_DIG] = {
14190 .mixers = { alc861vd_3st_mixer },
14191 .init_verbs = { alc861vd_volume_init_verbs,
14192 alc861vd_3stack_init_verbs },
14193 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14194 .dac_nids = alc660vd_dac_nids,
14195 .dig_out_nid = ALC861VD_DIGOUT_NID,
14196 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14197 .channel_mode = alc861vd_3stack_2ch_modes,
14198 .input_mux = &alc861vd_capture_source,
14201 .mixers = { alc861vd_3st_mixer },
14202 .init_verbs = { alc861vd_volume_init_verbs,
14203 alc861vd_3stack_init_verbs },
14204 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14205 .dac_nids = alc861vd_dac_nids,
14206 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14207 .channel_mode = alc861vd_3stack_2ch_modes,
14208 .input_mux = &alc861vd_capture_source,
14210 [ALC861VD_3ST_DIG] = {
14211 .mixers = { alc861vd_3st_mixer },
14212 .init_verbs = { alc861vd_volume_init_verbs,
14213 alc861vd_3stack_init_verbs },
14214 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14215 .dac_nids = alc861vd_dac_nids,
14216 .dig_out_nid = ALC861VD_DIGOUT_NID,
14217 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14218 .channel_mode = alc861vd_3stack_2ch_modes,
14219 .input_mux = &alc861vd_capture_source,
14221 [ALC861VD_6ST_DIG] = {
14222 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14223 .init_verbs = { alc861vd_volume_init_verbs,
14224 alc861vd_6stack_init_verbs },
14225 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14226 .dac_nids = alc861vd_dac_nids,
14227 .dig_out_nid = ALC861VD_DIGOUT_NID,
14228 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14229 .channel_mode = alc861vd_6stack_modes,
14230 .input_mux = &alc861vd_capture_source,
14232 [ALC861VD_LENOVO] = {
14233 .mixers = { alc861vd_lenovo_mixer },
14234 .init_verbs = { alc861vd_volume_init_verbs,
14235 alc861vd_3stack_init_verbs,
14236 alc861vd_eapd_verbs,
14237 alc861vd_lenovo_unsol_verbs },
14238 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14239 .dac_nids = alc660vd_dac_nids,
14240 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14241 .channel_mode = alc861vd_3stack_2ch_modes,
14242 .input_mux = &alc861vd_capture_source,
14243 .unsol_event = alc861vd_lenovo_unsol_event,
14244 .init_hook = alc861vd_lenovo_automute,
14246 [ALC861VD_DALLAS] = {
14247 .mixers = { alc861vd_dallas_mixer },
14248 .init_verbs = { alc861vd_dallas_verbs },
14249 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14250 .dac_nids = alc861vd_dac_nids,
14251 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14252 .channel_mode = alc861vd_3stack_2ch_modes,
14253 .input_mux = &alc861vd_dallas_capture_source,
14254 .unsol_event = alc861vd_dallas_unsol_event,
14255 .init_hook = alc861vd_dallas_automute,
14258 .mixers = { alc861vd_hp_mixer },
14259 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14260 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14261 .dac_nids = alc861vd_dac_nids,
14262 .dig_out_nid = ALC861VD_DIGOUT_NID,
14263 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14264 .channel_mode = alc861vd_3stack_2ch_modes,
14265 .input_mux = &alc861vd_hp_capture_source,
14266 .unsol_event = alc861vd_dallas_unsol_event,
14267 .init_hook = alc861vd_dallas_automute,
14269 [ALC660VD_ASUS_V1S] = {
14270 .mixers = { alc861vd_lenovo_mixer },
14271 .init_verbs = { alc861vd_volume_init_verbs,
14272 alc861vd_3stack_init_verbs,
14273 alc861vd_eapd_verbs,
14274 alc861vd_lenovo_unsol_verbs },
14275 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14276 .dac_nids = alc660vd_dac_nids,
14277 .dig_out_nid = ALC861VD_DIGOUT_NID,
14278 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14279 .channel_mode = alc861vd_3stack_2ch_modes,
14280 .input_mux = &alc861vd_capture_source,
14281 .unsol_event = alc861vd_lenovo_unsol_event,
14282 .init_hook = alc861vd_lenovo_automute,
14287 * BIOS auto configuration
14289 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14290 hda_nid_t nid, int pin_type, int dac_idx)
14292 alc_set_pin_output(codec, nid, pin_type);
14295 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14297 struct alc_spec *spec = codec->spec;
14300 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14301 for (i = 0; i <= HDA_SIDE; i++) {
14302 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14303 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14305 alc861vd_auto_set_output_and_unmute(codec, nid,
14311 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14313 struct alc_spec *spec = codec->spec;
14316 pin = spec->autocfg.hp_pins[0];
14317 if (pin) /* connect to front and use dac 0 */
14318 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14319 pin = spec->autocfg.speaker_pins[0];
14321 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14324 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14325 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14327 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14329 struct alc_spec *spec = codec->spec;
14332 for (i = 0; i < AUTO_PIN_LAST; i++) {
14333 hda_nid_t nid = spec->autocfg.input_pins[i];
14334 if (alc861vd_is_input_pin(nid)) {
14335 snd_hda_codec_write(codec, nid, 0,
14336 AC_VERB_SET_PIN_WIDGET_CONTROL,
14337 i <= AUTO_PIN_FRONT_MIC ?
14338 PIN_VREF80 : PIN_IN);
14339 if (nid != ALC861VD_PIN_CD_NID)
14340 snd_hda_codec_write(codec, nid, 0,
14341 AC_VERB_SET_AMP_GAIN_MUTE,
14347 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14349 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14350 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14352 /* add playback controls from the parsed DAC table */
14353 /* Based on ALC880 version. But ALC861VD has separate,
14354 * different NIDs for mute/unmute switch and volume control */
14355 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14356 const struct auto_pin_cfg *cfg)
14359 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14360 hda_nid_t nid_v, nid_s;
14363 for (i = 0; i < cfg->line_outs; i++) {
14364 if (!spec->multiout.dac_nids[i])
14366 nid_v = alc861vd_idx_to_mixer_vol(
14368 spec->multiout.dac_nids[i]));
14369 nid_s = alc861vd_idx_to_mixer_switch(
14371 spec->multiout.dac_nids[i]));
14375 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14376 "Center Playback Volume",
14377 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14381 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14382 "LFE Playback Volume",
14383 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14387 err = add_control(spec, ALC_CTL_BIND_MUTE,
14388 "Center Playback Switch",
14389 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14393 err = add_control(spec, ALC_CTL_BIND_MUTE,
14394 "LFE Playback Switch",
14395 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14400 sprintf(name, "%s Playback Volume", chname[i]);
14401 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14402 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14406 sprintf(name, "%s Playback Switch", chname[i]);
14407 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14408 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14417 /* add playback controls for speaker and HP outputs */
14418 /* Based on ALC880 version. But ALC861VD has separate,
14419 * different NIDs for mute/unmute switch and volume control */
14420 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14421 hda_nid_t pin, const char *pfx)
14423 hda_nid_t nid_v, nid_s;
14430 if (alc880_is_fixed_pin(pin)) {
14431 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14432 /* specify the DAC as the extra output */
14433 if (!spec->multiout.hp_nid)
14434 spec->multiout.hp_nid = nid_v;
14436 spec->multiout.extra_out_nid[0] = nid_v;
14437 /* control HP volume/switch on the output mixer amp */
14438 nid_v = alc861vd_idx_to_mixer_vol(
14439 alc880_fixed_pin_idx(pin));
14440 nid_s = alc861vd_idx_to_mixer_switch(
14441 alc880_fixed_pin_idx(pin));
14443 sprintf(name, "%s Playback Volume", pfx);
14444 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14445 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14448 sprintf(name, "%s Playback Switch", pfx);
14449 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14450 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14453 } else if (alc880_is_multi_pin(pin)) {
14454 /* set manual connection */
14455 /* we have only a switch on HP-out PIN */
14456 sprintf(name, "%s Playback Switch", pfx);
14457 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14458 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14465 /* parse the BIOS configuration and set up the alc_spec
14466 * return 1 if successful, 0 if the proper config is not found,
14467 * or a negative error code
14468 * Based on ALC880 version - had to change it to override
14469 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14470 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14472 struct alc_spec *spec = codec->spec;
14474 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14476 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14480 if (!spec->autocfg.line_outs)
14481 return 0; /* can't find valid BIOS pin config */
14483 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14486 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14489 err = alc861vd_auto_create_extra_out(spec,
14490 spec->autocfg.speaker_pins[0],
14494 err = alc861vd_auto_create_extra_out(spec,
14495 spec->autocfg.hp_pins[0],
14499 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14503 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14505 if (spec->autocfg.dig_out_pin)
14506 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14508 if (spec->kctls.list)
14509 add_mixer(spec, spec->kctls.list);
14511 add_verb(spec, alc861vd_volume_init_verbs);
14513 spec->num_mux_defs = 1;
14514 spec->input_mux = &spec->private_imux;
14516 err = alc_auto_add_mic_boost(codec);
14520 store_pin_configs(codec);
14524 /* additional initialization for auto-configuration model */
14525 static void alc861vd_auto_init(struct hda_codec *codec)
14527 struct alc_spec *spec = codec->spec;
14528 alc861vd_auto_init_multi_out(codec);
14529 alc861vd_auto_init_hp_out(codec);
14530 alc861vd_auto_init_analog_input(codec);
14531 alc861vd_auto_init_input_src(codec);
14532 if (spec->unsol_event)
14533 alc_inithook(codec);
14536 static int patch_alc861vd(struct hda_codec *codec)
14538 struct alc_spec *spec;
14539 int err, board_config;
14541 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14545 codec->spec = spec;
14547 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14551 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14552 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14553 "ALC861VD, trying auto-probe from BIOS...\n");
14554 board_config = ALC861VD_AUTO;
14557 if (board_config == ALC861VD_AUTO) {
14558 /* automatic parse from the BIOS config */
14559 err = alc861vd_parse_auto_config(codec);
14565 "hda_codec: Cannot set up configuration "
14566 "from BIOS. Using base mode...\n");
14567 board_config = ALC861VD_3ST;
14571 if (board_config != ALC861VD_AUTO)
14572 setup_preset(spec, &alc861vd_presets[board_config]);
14574 if (codec->vendor_id == 0x10ec0660) {
14575 spec->stream_name_analog = "ALC660-VD Analog";
14576 spec->stream_name_digital = "ALC660-VD Digital";
14577 /* always turn on EAPD */
14578 add_verb(spec, alc660vd_eapd_verbs);
14580 spec->stream_name_analog = "ALC861VD Analog";
14581 spec->stream_name_digital = "ALC861VD Digital";
14584 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14585 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14587 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14588 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14590 spec->adc_nids = alc861vd_adc_nids;
14591 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14592 spec->capsrc_nids = alc861vd_capsrc_nids;
14593 spec->is_mix_capture = 1;
14595 set_capture_mixer(spec);
14597 spec->vmaster_nid = 0x02;
14599 codec->patch_ops = alc_patch_ops;
14601 if (board_config == ALC861VD_AUTO)
14602 spec->init_hook = alc861vd_auto_init;
14603 #ifdef CONFIG_SND_HDA_POWER_SAVE
14604 if (!spec->loopback.amplist)
14605 spec->loopback.amplist = alc861vd_loopbacks;
14614 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14615 * configuration. Each pin widget can choose any input DACs and a mixer.
14616 * Each ADC is connected from a mixer of all inputs. This makes possible
14617 * 6-channel independent captures.
14619 * In addition, an independent DAC for the multi-playback (not used in this
14622 #define ALC662_DIGOUT_NID 0x06
14623 #define ALC662_DIGIN_NID 0x0a
14625 static hda_nid_t alc662_dac_nids[4] = {
14626 /* front, rear, clfe, rear_surr */
14630 static hda_nid_t alc662_adc_nids[1] = {
14635 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14638 /* FIXME: should be a matrix-type input source selection */
14639 static struct hda_input_mux alc662_capture_source = {
14643 { "Front Mic", 0x1 },
14649 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14657 static struct hda_input_mux alc662_eeepc_capture_source = {
14665 static struct hda_input_mux alc663_capture_source = {
14669 { "Front Mic", 0x1 },
14674 static struct hda_input_mux alc663_m51va_capture_source = {
14677 { "Ext-Mic", 0x0 },
14685 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14692 static struct hda_verb alc662_3ST_ch2_init[] = {
14693 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14694 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14695 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14696 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14703 static struct hda_verb alc662_3ST_ch6_init[] = {
14704 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14705 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14706 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14707 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14708 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14709 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14713 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14714 { 2, alc662_3ST_ch2_init },
14715 { 6, alc662_3ST_ch6_init },
14721 static struct hda_verb alc662_sixstack_ch6_init[] = {
14722 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14723 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14724 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14731 static struct hda_verb alc662_sixstack_ch8_init[] = {
14732 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14733 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14734 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14738 static struct hda_channel_mode alc662_5stack_modes[2] = {
14739 { 2, alc662_sixstack_ch6_init },
14740 { 6, alc662_sixstack_ch8_init },
14743 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14744 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14747 static struct snd_kcontrol_new alc662_base_mixer[] = {
14748 /* output mixer control */
14749 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14750 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14751 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14752 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14753 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14754 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14755 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14756 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14759 /*Input mixer control */
14760 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14761 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14762 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14763 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14764 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14765 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14766 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14767 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14771 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14772 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14773 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14774 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14775 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14776 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14777 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14778 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14781 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14782 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14783 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14784 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14788 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14789 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14790 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14791 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14792 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14793 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14794 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14795 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14796 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14797 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14798 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14799 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14800 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14801 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14802 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14804 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14805 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14806 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14807 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14811 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14812 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14813 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14814 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14815 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14816 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14824 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14825 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14827 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14828 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14830 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14831 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14832 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14834 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14835 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14836 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14840 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14841 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14842 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14844 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14845 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14846 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14847 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14848 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14849 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14850 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14858 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14859 .ops = &snd_hda_bind_vol,
14861 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14862 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14867 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14868 .ops = &snd_hda_bind_sw,
14870 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14871 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14876 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14877 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14878 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14884 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14885 .ops = &snd_hda_bind_sw,
14887 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14888 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14889 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14894 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14895 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14896 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14899 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14900 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14905 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14906 .ops = &snd_hda_bind_sw,
14908 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14909 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14910 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14915 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14916 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14917 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14918 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14919 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14920 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14921 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14925 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14926 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14927 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14931 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14932 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14936 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14937 .ops = &snd_hda_bind_vol,
14939 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14940 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14945 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14946 .ops = &snd_hda_bind_sw,
14948 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14949 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14954 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14955 HDA_BIND_VOL("Master Playback Volume",
14956 &alc663_asus_two_bind_master_vol),
14957 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14959 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14960 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14961 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14965 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14966 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14967 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14968 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14969 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14971 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14975 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14976 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14977 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14978 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14979 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14984 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14985 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14989 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14990 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14991 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14996 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14997 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15003 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15006 .name = "Channel Mode",
15007 .info = alc_ch_mode_info,
15008 .get = alc_ch_mode_get,
15009 .put = alc_ch_mode_put,
15014 static struct hda_verb alc662_init_verbs[] = {
15015 /* ADC: mute amp left and right */
15016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15017 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15018 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15028 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15033 /* Front Pin: output 0 (0x0c) */
15034 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15035 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15037 /* Rear Pin: output 1 (0x0d) */
15038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15041 /* CLFE Pin: output 2 (0x0e) */
15042 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15043 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15045 /* Mic (rear) pin: input vref at 80% */
15046 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15047 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15048 /* Front Mic pin: input vref at 80% */
15049 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15050 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15051 /* Line In pin: input */
15052 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15053 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15054 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15055 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15056 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15057 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15058 /* CD pin widget for input */
15059 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15061 /* FIXME: use matrix-type input source selection */
15062 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15072 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15074 /* always trun on EAPD */
15075 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15076 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15081 static struct hda_verb alc662_sue_init_verbs[] = {
15082 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15083 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15087 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15088 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15089 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15093 /* Set Unsolicited Event*/
15094 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15095 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15096 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15101 * generic initialization of ADC, input mixers and output mixers
15103 static struct hda_verb alc662_auto_init_verbs[] = {
15105 * Unmute ADC and set the default input to mic-in
15107 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15112 * Note: PASD motherboards uses the Line In 2 as the input for front
15113 * panel mic (mic 2)
15115 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15123 * Set up output mixers (0x0c - 0x0f)
15125 /* set vol=0 to output mixers */
15126 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15127 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15128 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15130 /* set up input amps for analog loopback */
15131 /* Amp Indices: DAC = 0, mixer = 1 */
15132 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15134 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15136 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15137 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15140 /* FIXME: use matrix-type input source selection */
15141 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15144 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 /* additional verbs for ALC663 */
15149 static struct hda_verb alc663_auto_init_verbs[] = {
15150 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15155 static struct hda_verb alc663_m51va_init_verbs[] = {
15156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15157 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15158 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15159 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15160 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15161 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15163 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15164 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15168 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15169 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15170 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15171 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15172 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15173 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15174 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15175 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15179 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15180 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15182 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15183 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15184 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15186 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15187 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15191 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15192 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15193 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15194 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15195 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15197 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15198 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15202 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15203 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15204 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15205 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15206 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15207 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15208 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15209 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15210 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15212 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15213 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15214 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15218 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15219 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15220 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15221 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15222 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15223 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15225 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15228 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15229 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15230 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15234 static struct hda_verb alc663_g71v_init_verbs[] = {
15235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15236 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15237 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15239 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15240 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15241 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15243 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15244 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15245 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15249 static struct hda_verb alc663_g50v_init_verbs[] = {
15250 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15251 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15252 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15254 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15255 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15259 static struct hda_verb alc662_ecs_init_verbs[] = {
15260 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15262 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15263 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15267 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15268 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15269 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15273 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15275 unsigned int present;
15276 unsigned char bits;
15278 present = snd_hda_codec_read(codec, 0x14, 0,
15279 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15280 bits = present ? HDA_AMP_MUTE : 0;
15281 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15282 HDA_AMP_MUTE, bits);
15285 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15287 unsigned int present;
15288 unsigned char bits;
15290 present = snd_hda_codec_read(codec, 0x1b, 0,
15291 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15292 bits = present ? HDA_AMP_MUTE : 0;
15293 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15294 HDA_AMP_MUTE, bits);
15295 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15296 HDA_AMP_MUTE, bits);
15299 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15302 if ((res >> 26) == ALC880_HP_EVENT)
15303 alc662_lenovo_101e_all_automute(codec);
15304 if ((res >> 26) == ALC880_FRONT_EVENT)
15305 alc662_lenovo_101e_ispeaker_automute(codec);
15308 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15310 unsigned int present;
15312 present = snd_hda_codec_read(codec, 0x18, 0,
15313 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15314 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15315 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15316 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15317 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15318 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15319 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15320 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15321 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15324 /* unsolicited event for HP jack sensing */
15325 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15328 if ((res >> 26) == ALC880_HP_EVENT)
15329 alc262_hippo1_automute( codec );
15331 if ((res >> 26) == ALC880_MIC_EVENT)
15332 alc662_eeepc_mic_automute(codec);
15335 static void alc662_eeepc_inithook(struct hda_codec *codec)
15337 alc262_hippo1_automute( codec );
15338 alc662_eeepc_mic_automute(codec);
15341 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15344 unsigned int present;
15346 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15347 present = snd_hda_codec_read(codec, 0x14, 0,
15348 AC_VERB_GET_PIN_SENSE, 0);
15349 present = (present & 0x80000000) != 0;
15351 /* mute internal speaker */
15352 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15353 HDA_AMP_MUTE, HDA_AMP_MUTE);
15355 /* unmute internal speaker if necessary */
15356 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15357 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15358 HDA_AMP_MUTE, mute);
15362 /* unsolicited event for HP jack sensing */
15363 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15366 if ((res >> 26) == ALC880_HP_EVENT)
15367 alc662_eeepc_ep20_automute(codec);
15370 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15372 alc662_eeepc_ep20_automute(codec);
15375 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15377 unsigned int present;
15378 unsigned char bits;
15380 present = snd_hda_codec_read(codec, 0x21, 0,
15381 AC_VERB_GET_PIN_SENSE, 0)
15382 & AC_PINSENSE_PRESENCE;
15383 bits = present ? HDA_AMP_MUTE : 0;
15384 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15385 AMP_IN_MUTE(0), bits);
15386 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15387 AMP_IN_MUTE(0), bits);
15390 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15392 unsigned int present;
15393 unsigned char bits;
15395 present = snd_hda_codec_read(codec, 0x21, 0,
15396 AC_VERB_GET_PIN_SENSE, 0)
15397 & AC_PINSENSE_PRESENCE;
15398 bits = present ? HDA_AMP_MUTE : 0;
15399 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15400 AMP_IN_MUTE(0), bits);
15401 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15402 AMP_IN_MUTE(0), bits);
15403 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15404 AMP_IN_MUTE(0), bits);
15405 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15406 AMP_IN_MUTE(0), bits);
15409 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15411 unsigned int present;
15412 unsigned char bits;
15414 present = snd_hda_codec_read(codec, 0x15, 0,
15415 AC_VERB_GET_PIN_SENSE, 0)
15416 & AC_PINSENSE_PRESENCE;
15417 bits = present ? HDA_AMP_MUTE : 0;
15418 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15419 AMP_IN_MUTE(0), bits);
15420 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15421 AMP_IN_MUTE(0), bits);
15422 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15423 AMP_IN_MUTE(0), bits);
15424 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15425 AMP_IN_MUTE(0), bits);
15428 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15430 unsigned int present;
15431 unsigned char bits;
15433 present = snd_hda_codec_read(codec, 0x1b, 0,
15434 AC_VERB_GET_PIN_SENSE, 0)
15435 & AC_PINSENSE_PRESENCE;
15436 bits = present ? 0 : PIN_OUT;
15437 snd_hda_codec_write(codec, 0x14, 0,
15438 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15441 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15443 unsigned int present1, present2;
15445 present1 = snd_hda_codec_read(codec, 0x21, 0,
15446 AC_VERB_GET_PIN_SENSE, 0)
15447 & AC_PINSENSE_PRESENCE;
15448 present2 = snd_hda_codec_read(codec, 0x15, 0,
15449 AC_VERB_GET_PIN_SENSE, 0)
15450 & AC_PINSENSE_PRESENCE;
15452 if (present1 || present2) {
15453 snd_hda_codec_write_cache(codec, 0x14, 0,
15454 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15456 snd_hda_codec_write_cache(codec, 0x14, 0,
15457 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15461 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15463 unsigned int present1, present2;
15465 present1 = snd_hda_codec_read(codec, 0x1b, 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_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15474 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15475 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15476 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15478 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15479 AMP_IN_MUTE(0), 0);
15480 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15481 AMP_IN_MUTE(0), 0);
15485 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15487 unsigned int present;
15489 present = snd_hda_codec_read(codec, 0x18, 0,
15490 AC_VERB_GET_PIN_SENSE, 0)
15491 & AC_PINSENSE_PRESENCE;
15492 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15493 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15494 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15495 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15496 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15497 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15498 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15499 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15502 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15505 switch (res >> 26) {
15506 case ALC880_HP_EVENT:
15507 alc663_m51va_speaker_automute(codec);
15509 case ALC880_MIC_EVENT:
15510 alc663_m51va_mic_automute(codec);
15515 static void alc663_m51va_inithook(struct hda_codec *codec)
15517 alc663_m51va_speaker_automute(codec);
15518 alc663_m51va_mic_automute(codec);
15521 /* ***************** Mode1 ******************************/
15522 static void alc663_mode1_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 alc662_eeepc_mic_automute(codec);
15535 static void alc663_mode1_inithook(struct hda_codec *codec)
15537 alc663_m51va_speaker_automute(codec);
15538 alc662_eeepc_mic_automute(codec);
15540 /* ***************** Mode2 ******************************/
15541 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15544 switch (res >> 26) {
15545 case ALC880_HP_EVENT:
15546 alc662_f5z_speaker_automute(codec);
15548 case ALC880_MIC_EVENT:
15549 alc662_eeepc_mic_automute(codec);
15554 static void alc662_mode2_inithook(struct hda_codec *codec)
15556 alc662_f5z_speaker_automute(codec);
15557 alc662_eeepc_mic_automute(codec);
15559 /* ***************** Mode3 ******************************/
15560 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15563 switch (res >> 26) {
15564 case ALC880_HP_EVENT:
15565 alc663_two_hp_m1_speaker_automute(codec);
15567 case ALC880_MIC_EVENT:
15568 alc662_eeepc_mic_automute(codec);
15573 static void alc663_mode3_inithook(struct hda_codec *codec)
15575 alc663_two_hp_m1_speaker_automute(codec);
15576 alc662_eeepc_mic_automute(codec);
15578 /* ***************** Mode4 ******************************/
15579 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15582 switch (res >> 26) {
15583 case ALC880_HP_EVENT:
15584 alc663_21jd_two_speaker_automute(codec);
15586 case ALC880_MIC_EVENT:
15587 alc662_eeepc_mic_automute(codec);
15592 static void alc663_mode4_inithook(struct hda_codec *codec)
15594 alc663_21jd_two_speaker_automute(codec);
15595 alc662_eeepc_mic_automute(codec);
15597 /* ***************** Mode5 ******************************/
15598 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15601 switch (res >> 26) {
15602 case ALC880_HP_EVENT:
15603 alc663_15jd_two_speaker_automute(codec);
15605 case ALC880_MIC_EVENT:
15606 alc662_eeepc_mic_automute(codec);
15611 static void alc663_mode5_inithook(struct hda_codec *codec)
15613 alc663_15jd_two_speaker_automute(codec);
15614 alc662_eeepc_mic_automute(codec);
15616 /* ***************** Mode6 ******************************/
15617 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15620 switch (res >> 26) {
15621 case ALC880_HP_EVENT:
15622 alc663_two_hp_m2_speaker_automute(codec);
15624 case ALC880_MIC_EVENT:
15625 alc662_eeepc_mic_automute(codec);
15630 static void alc663_mode6_inithook(struct hda_codec *codec)
15632 alc663_two_hp_m2_speaker_automute(codec);
15633 alc662_eeepc_mic_automute(codec);
15636 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15638 unsigned int present;
15639 unsigned char bits;
15641 present = snd_hda_codec_read(codec, 0x21, 0,
15642 AC_VERB_GET_PIN_SENSE, 0)
15643 & AC_PINSENSE_PRESENCE;
15644 bits = present ? HDA_AMP_MUTE : 0;
15645 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15646 HDA_AMP_MUTE, bits);
15647 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15648 HDA_AMP_MUTE, bits);
15651 static void alc663_g71v_front_automute(struct hda_codec *codec)
15653 unsigned int present;
15654 unsigned char bits;
15656 present = snd_hda_codec_read(codec, 0x15, 0,
15657 AC_VERB_GET_PIN_SENSE, 0)
15658 & AC_PINSENSE_PRESENCE;
15659 bits = present ? HDA_AMP_MUTE : 0;
15660 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15661 HDA_AMP_MUTE, bits);
15664 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15667 switch (res >> 26) {
15668 case ALC880_HP_EVENT:
15669 alc663_g71v_hp_automute(codec);
15671 case ALC880_FRONT_EVENT:
15672 alc663_g71v_front_automute(codec);
15674 case ALC880_MIC_EVENT:
15675 alc662_eeepc_mic_automute(codec);
15680 static void alc663_g71v_inithook(struct hda_codec *codec)
15682 alc663_g71v_front_automute(codec);
15683 alc663_g71v_hp_automute(codec);
15684 alc662_eeepc_mic_automute(codec);
15687 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15690 switch (res >> 26) {
15691 case ALC880_HP_EVENT:
15692 alc663_m51va_speaker_automute(codec);
15694 case ALC880_MIC_EVENT:
15695 alc662_eeepc_mic_automute(codec);
15700 static void alc663_g50v_inithook(struct hda_codec *codec)
15702 alc663_m51va_speaker_automute(codec);
15703 alc662_eeepc_mic_automute(codec);
15706 /* bind hp and internal speaker mute (with plug check) */
15707 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15708 struct snd_ctl_elem_value *ucontrol)
15710 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15711 long *valp = ucontrol->value.integer.value;
15714 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15716 valp[0] ? 0 : HDA_AMP_MUTE);
15717 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15719 valp[1] ? 0 : HDA_AMP_MUTE);
15721 alc262_hippo1_automute(codec);
15725 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15726 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15729 .name = "Master Playback Switch",
15730 .info = snd_hda_mixer_amp_switch_info,
15731 .get = snd_hda_mixer_amp_switch_get,
15732 .put = alc662_ecs_master_sw_put,
15733 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15736 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15737 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15738 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15740 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15741 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15742 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15746 #ifdef CONFIG_SND_HDA_POWER_SAVE
15747 #define alc662_loopbacks alc880_loopbacks
15751 /* pcm configuration: identiacal with ALC880 */
15752 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15753 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15754 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15755 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15758 * configuration and preset
15760 static const char *alc662_models[ALC662_MODEL_LAST] = {
15761 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15762 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15763 [ALC662_3ST_6ch] = "3stack-6ch",
15764 [ALC662_5ST_DIG] = "6stack-dig",
15765 [ALC662_LENOVO_101E] = "lenovo-101e",
15766 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15767 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15768 [ALC662_ECS] = "ecs",
15769 [ALC663_ASUS_M51VA] = "m51va",
15770 [ALC663_ASUS_G71V] = "g71v",
15771 [ALC663_ASUS_H13] = "h13",
15772 [ALC663_ASUS_G50V] = "g50v",
15773 [ALC663_ASUS_MODE1] = "asus-mode1",
15774 [ALC662_ASUS_MODE2] = "asus-mode2",
15775 [ALC663_ASUS_MODE3] = "asus-mode3",
15776 [ALC663_ASUS_MODE4] = "asus-mode4",
15777 [ALC663_ASUS_MODE5] = "asus-mode5",
15778 [ALC663_ASUS_MODE6] = "asus-mode6",
15779 [ALC662_AUTO] = "auto",
15782 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15783 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15784 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15785 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15786 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15787 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15788 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15789 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15790 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15791 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15792 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15793 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15794 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15795 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15796 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15797 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15798 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15799 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15800 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15801 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15802 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15803 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15804 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15805 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15806 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15807 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15808 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15809 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15810 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15811 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15812 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15813 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15814 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15815 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15816 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15817 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15818 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15819 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15820 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15821 ALC662_3ST_6ch_DIG),
15822 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15823 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15824 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15825 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15826 ALC662_3ST_6ch_DIG),
15827 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15828 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15829 ALC662_3ST_6ch_DIG),
15830 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15831 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15832 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15836 static struct alc_config_preset alc662_presets[] = {
15837 [ALC662_3ST_2ch_DIG] = {
15838 .mixers = { alc662_3ST_2ch_mixer },
15839 .init_verbs = { alc662_init_verbs },
15840 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15841 .dac_nids = alc662_dac_nids,
15842 .dig_out_nid = ALC662_DIGOUT_NID,
15843 .dig_in_nid = ALC662_DIGIN_NID,
15844 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15845 .channel_mode = alc662_3ST_2ch_modes,
15846 .input_mux = &alc662_capture_source,
15848 [ALC662_3ST_6ch_DIG] = {
15849 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15850 .init_verbs = { alc662_init_verbs },
15851 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15852 .dac_nids = alc662_dac_nids,
15853 .dig_out_nid = ALC662_DIGOUT_NID,
15854 .dig_in_nid = ALC662_DIGIN_NID,
15855 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15856 .channel_mode = alc662_3ST_6ch_modes,
15858 .input_mux = &alc662_capture_source,
15860 [ALC662_3ST_6ch] = {
15861 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15862 .init_verbs = { alc662_init_verbs },
15863 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15864 .dac_nids = alc662_dac_nids,
15865 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15866 .channel_mode = alc662_3ST_6ch_modes,
15868 .input_mux = &alc662_capture_source,
15870 [ALC662_5ST_DIG] = {
15871 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
15872 .init_verbs = { alc662_init_verbs },
15873 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15874 .dac_nids = alc662_dac_nids,
15875 .dig_out_nid = ALC662_DIGOUT_NID,
15876 .dig_in_nid = ALC662_DIGIN_NID,
15877 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15878 .channel_mode = alc662_5stack_modes,
15879 .input_mux = &alc662_capture_source,
15881 [ALC662_LENOVO_101E] = {
15882 .mixers = { alc662_lenovo_101e_mixer },
15883 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15884 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15885 .dac_nids = alc662_dac_nids,
15886 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15887 .channel_mode = alc662_3ST_2ch_modes,
15888 .input_mux = &alc662_lenovo_101e_capture_source,
15889 .unsol_event = alc662_lenovo_101e_unsol_event,
15890 .init_hook = alc662_lenovo_101e_all_automute,
15892 [ALC662_ASUS_EEEPC_P701] = {
15893 .mixers = { alc662_eeepc_p701_mixer },
15894 .init_verbs = { alc662_init_verbs,
15895 alc662_eeepc_sue_init_verbs },
15896 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15897 .dac_nids = alc662_dac_nids,
15898 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15899 .channel_mode = alc662_3ST_2ch_modes,
15900 .input_mux = &alc662_eeepc_capture_source,
15901 .unsol_event = alc662_eeepc_unsol_event,
15902 .init_hook = alc662_eeepc_inithook,
15904 [ALC662_ASUS_EEEPC_EP20] = {
15905 .mixers = { alc662_eeepc_ep20_mixer,
15906 alc662_chmode_mixer },
15907 .init_verbs = { alc662_init_verbs,
15908 alc662_eeepc_ep20_sue_init_verbs },
15909 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15910 .dac_nids = alc662_dac_nids,
15911 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15912 .channel_mode = alc662_3ST_6ch_modes,
15913 .input_mux = &alc662_lenovo_101e_capture_source,
15914 .unsol_event = alc662_eeepc_ep20_unsol_event,
15915 .init_hook = alc662_eeepc_ep20_inithook,
15918 .mixers = { alc662_ecs_mixer },
15919 .init_verbs = { alc662_init_verbs,
15920 alc662_ecs_init_verbs },
15921 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15922 .dac_nids = alc662_dac_nids,
15923 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15924 .channel_mode = alc662_3ST_2ch_modes,
15925 .input_mux = &alc662_eeepc_capture_source,
15926 .unsol_event = alc662_eeepc_unsol_event,
15927 .init_hook = alc662_eeepc_inithook,
15929 [ALC663_ASUS_M51VA] = {
15930 .mixers = { alc663_m51va_mixer },
15931 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15932 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15933 .dac_nids = alc662_dac_nids,
15934 .dig_out_nid = ALC662_DIGOUT_NID,
15935 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15936 .channel_mode = alc662_3ST_2ch_modes,
15937 .input_mux = &alc663_m51va_capture_source,
15938 .unsol_event = alc663_m51va_unsol_event,
15939 .init_hook = alc663_m51va_inithook,
15941 [ALC663_ASUS_G71V] = {
15942 .mixers = { alc663_g71v_mixer },
15943 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15944 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15945 .dac_nids = alc662_dac_nids,
15946 .dig_out_nid = ALC662_DIGOUT_NID,
15947 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15948 .channel_mode = alc662_3ST_2ch_modes,
15949 .input_mux = &alc662_eeepc_capture_source,
15950 .unsol_event = alc663_g71v_unsol_event,
15951 .init_hook = alc663_g71v_inithook,
15953 [ALC663_ASUS_H13] = {
15954 .mixers = { alc663_m51va_mixer },
15955 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15956 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15957 .dac_nids = alc662_dac_nids,
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_G50V] = {
15965 .mixers = { alc663_g50v_mixer },
15966 .init_verbs = { alc662_init_verbs, alc663_g50v_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_6ch_modes),
15971 .channel_mode = alc662_3ST_6ch_modes,
15972 .input_mux = &alc663_capture_source,
15973 .unsol_event = alc663_g50v_unsol_event,
15974 .init_hook = alc663_g50v_inithook,
15976 [ALC663_ASUS_MODE1] = {
15977 .mixers = { alc663_m51va_mixer },
15978 .cap_mixer = alc662_auto_capture_mixer,
15979 .init_verbs = { alc662_init_verbs,
15980 alc663_21jd_amic_init_verbs },
15981 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15983 .dac_nids = alc662_dac_nids,
15984 .dig_out_nid = ALC662_DIGOUT_NID,
15985 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15986 .channel_mode = alc662_3ST_2ch_modes,
15987 .input_mux = &alc662_eeepc_capture_source,
15988 .unsol_event = alc663_mode1_unsol_event,
15989 .init_hook = alc663_mode1_inithook,
15991 [ALC662_ASUS_MODE2] = {
15992 .mixers = { alc662_1bjd_mixer },
15993 .cap_mixer = alc662_auto_capture_mixer,
15994 .init_verbs = { alc662_init_verbs,
15995 alc662_1bjd_amic_init_verbs },
15996 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15997 .dac_nids = alc662_dac_nids,
15998 .dig_out_nid = ALC662_DIGOUT_NID,
15999 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16000 .channel_mode = alc662_3ST_2ch_modes,
16001 .input_mux = &alc662_eeepc_capture_source,
16002 .unsol_event = alc662_mode2_unsol_event,
16003 .init_hook = alc662_mode2_inithook,
16005 [ALC663_ASUS_MODE3] = {
16006 .mixers = { alc663_two_hp_m1_mixer },
16007 .cap_mixer = alc662_auto_capture_mixer,
16008 .init_verbs = { alc662_init_verbs,
16009 alc663_two_hp_amic_m1_init_verbs },
16010 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16012 .dac_nids = alc662_dac_nids,
16013 .dig_out_nid = ALC662_DIGOUT_NID,
16014 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16015 .channel_mode = alc662_3ST_2ch_modes,
16016 .input_mux = &alc662_eeepc_capture_source,
16017 .unsol_event = alc663_mode3_unsol_event,
16018 .init_hook = alc663_mode3_inithook,
16020 [ALC663_ASUS_MODE4] = {
16021 .mixers = { alc663_asus_21jd_clfe_mixer },
16022 .cap_mixer = alc662_auto_capture_mixer,
16023 .init_verbs = { alc662_init_verbs,
16024 alc663_21jd_amic_init_verbs},
16025 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16027 .dac_nids = alc662_dac_nids,
16028 .dig_out_nid = ALC662_DIGOUT_NID,
16029 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16030 .channel_mode = alc662_3ST_2ch_modes,
16031 .input_mux = &alc662_eeepc_capture_source,
16032 .unsol_event = alc663_mode4_unsol_event,
16033 .init_hook = alc663_mode4_inithook,
16035 [ALC663_ASUS_MODE5] = {
16036 .mixers = { alc663_asus_15jd_clfe_mixer },
16037 .cap_mixer = alc662_auto_capture_mixer,
16038 .init_verbs = { alc662_init_verbs,
16039 alc663_15jd_amic_init_verbs },
16040 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16042 .dac_nids = alc662_dac_nids,
16043 .dig_out_nid = ALC662_DIGOUT_NID,
16044 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16045 .channel_mode = alc662_3ST_2ch_modes,
16046 .input_mux = &alc662_eeepc_capture_source,
16047 .unsol_event = alc663_mode5_unsol_event,
16048 .init_hook = alc663_mode5_inithook,
16050 [ALC663_ASUS_MODE6] = {
16051 .mixers = { alc663_two_hp_m2_mixer },
16052 .cap_mixer = alc662_auto_capture_mixer,
16053 .init_verbs = { alc662_init_verbs,
16054 alc663_two_hp_amic_m2_init_verbs },
16055 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16057 .dac_nids = alc662_dac_nids,
16058 .dig_out_nid = ALC662_DIGOUT_NID,
16059 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16060 .channel_mode = alc662_3ST_2ch_modes,
16061 .input_mux = &alc662_eeepc_capture_source,
16062 .unsol_event = alc663_mode6_unsol_event,
16063 .init_hook = alc663_mode6_inithook,
16069 * BIOS auto configuration
16072 /* add playback controls from the parsed DAC table */
16073 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16074 const struct auto_pin_cfg *cfg)
16077 static const char *chname[4] = {
16078 "Front", "Surround", NULL /*CLFE*/, "Side"
16083 for (i = 0; i < cfg->line_outs; i++) {
16084 if (!spec->multiout.dac_nids[i])
16086 nid = alc880_idx_to_dac(i);
16089 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16090 "Center Playback Volume",
16091 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16095 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16096 "LFE Playback Volume",
16097 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16101 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16102 "Center Playback Switch",
16103 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16107 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16108 "LFE Playback Switch",
16109 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16114 sprintf(name, "%s Playback Volume", chname[i]);
16115 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16116 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16120 sprintf(name, "%s Playback Switch", chname[i]);
16121 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16122 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16131 /* add playback controls for speaker and HP outputs */
16132 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16143 /* ALC663 has a mono output pin on 0x17 */
16144 sprintf(name, "%s Playback Switch", pfx);
16145 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16146 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16150 if (alc880_is_fixed_pin(pin)) {
16151 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16152 /* printk("DAC nid=%x\n",nid); */
16153 /* specify the DAC as the extra output */
16154 if (!spec->multiout.hp_nid)
16155 spec->multiout.hp_nid = nid;
16157 spec->multiout.extra_out_nid[0] = nid;
16158 /* control HP volume/switch on the output mixer amp */
16159 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16160 sprintf(name, "%s Playback Volume", pfx);
16161 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16162 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16165 sprintf(name, "%s Playback Switch", pfx);
16166 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16167 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16170 } else if (alc880_is_multi_pin(pin)) {
16171 /* set manual connection */
16172 /* we have only a switch on HP-out PIN */
16173 sprintf(name, "%s Playback Switch", pfx);
16174 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16175 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16182 /* create playback/capture controls for input pins */
16183 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16184 const struct auto_pin_cfg *cfg)
16186 struct hda_input_mux *imux = &spec->private_imux;
16189 for (i = 0; i < AUTO_PIN_LAST; i++) {
16190 if (alc880_is_input_pin(cfg->input_pins[i])) {
16191 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16192 err = new_analog_input(spec, cfg->input_pins[i],
16193 auto_pin_cfg_labels[i],
16197 imux->items[imux->num_items].label =
16198 auto_pin_cfg_labels[i];
16199 imux->items[imux->num_items].index =
16200 alc880_input_pin_idx(cfg->input_pins[i]);
16207 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16208 hda_nid_t nid, int pin_type,
16211 alc_set_pin_output(codec, nid, pin_type);
16212 /* need the manual connection? */
16213 if (alc880_is_multi_pin(nid)) {
16214 struct alc_spec *spec = codec->spec;
16215 int idx = alc880_multi_pin_idx(nid);
16216 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16217 AC_VERB_SET_CONNECT_SEL,
16218 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16222 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16224 struct alc_spec *spec = codec->spec;
16227 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16228 for (i = 0; i <= HDA_SIDE; i++) {
16229 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16230 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16232 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16237 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16239 struct alc_spec *spec = codec->spec;
16242 pin = spec->autocfg.hp_pins[0];
16243 if (pin) /* connect to front */
16245 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16246 pin = spec->autocfg.speaker_pins[0];
16248 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16251 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16252 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16254 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16256 struct alc_spec *spec = codec->spec;
16259 for (i = 0; i < AUTO_PIN_LAST; i++) {
16260 hda_nid_t nid = spec->autocfg.input_pins[i];
16261 if (alc662_is_input_pin(nid)) {
16262 snd_hda_codec_write(codec, nid, 0,
16263 AC_VERB_SET_PIN_WIDGET_CONTROL,
16264 (i <= AUTO_PIN_FRONT_MIC ?
16265 PIN_VREF80 : PIN_IN));
16266 if (nid != ALC662_PIN_CD_NID)
16267 snd_hda_codec_write(codec, nid, 0,
16268 AC_VERB_SET_AMP_GAIN_MUTE,
16274 #define alc662_auto_init_input_src alc882_auto_init_input_src
16276 static int alc662_parse_auto_config(struct hda_codec *codec)
16278 struct alc_spec *spec = codec->spec;
16280 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16282 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16286 if (!spec->autocfg.line_outs)
16287 return 0; /* can't find valid BIOS pin config */
16289 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16292 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16295 err = alc662_auto_create_extra_out(spec,
16296 spec->autocfg.speaker_pins[0],
16300 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16304 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16308 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16310 if (spec->autocfg.dig_out_pin)
16311 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16313 if (spec->kctls.list)
16314 add_mixer(spec, spec->kctls.list);
16316 spec->num_mux_defs = 1;
16317 spec->input_mux = &spec->private_imux;
16319 add_verb(spec, alc662_auto_init_verbs);
16320 if (codec->vendor_id == 0x10ec0663)
16321 add_verb(spec, alc663_auto_init_verbs);
16323 err = alc_auto_add_mic_boost(codec);
16327 store_pin_configs(codec);
16331 /* additional initialization for auto-configuration model */
16332 static void alc662_auto_init(struct hda_codec *codec)
16334 struct alc_spec *spec = codec->spec;
16335 alc662_auto_init_multi_out(codec);
16336 alc662_auto_init_hp_out(codec);
16337 alc662_auto_init_analog_input(codec);
16338 alc662_auto_init_input_src(codec);
16339 if (spec->unsol_event)
16340 alc_inithook(codec);
16343 static int patch_alc662(struct hda_codec *codec)
16345 struct alc_spec *spec;
16346 int err, board_config;
16348 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16352 codec->spec = spec;
16354 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16356 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16359 if (board_config < 0) {
16360 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16361 "trying auto-probe from BIOS...\n");
16362 board_config = ALC662_AUTO;
16365 if (board_config == ALC662_AUTO) {
16366 /* automatic parse from the BIOS config */
16367 err = alc662_parse_auto_config(codec);
16373 "hda_codec: Cannot set up configuration "
16374 "from BIOS. Using base mode...\n");
16375 board_config = ALC662_3ST_2ch_DIG;
16379 if (board_config != ALC662_AUTO)
16380 setup_preset(spec, &alc662_presets[board_config]);
16382 if (codec->vendor_id == 0x10ec0663) {
16383 spec->stream_name_analog = "ALC663 Analog";
16384 spec->stream_name_digital = "ALC663 Digital";
16385 } else if (codec->vendor_id == 0x10ec0272) {
16386 spec->stream_name_analog = "ALC272 Analog";
16387 spec->stream_name_digital = "ALC272 Digital";
16389 spec->stream_name_analog = "ALC662 Analog";
16390 spec->stream_name_digital = "ALC662 Digital";
16393 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16394 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16396 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16397 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16399 spec->adc_nids = alc662_adc_nids;
16400 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16401 spec->capsrc_nids = alc662_capsrc_nids;
16402 spec->is_mix_capture = 1;
16404 if (!spec->cap_mixer)
16405 set_capture_mixer(spec);
16407 spec->vmaster_nid = 0x02;
16409 codec->patch_ops = alc_patch_ops;
16410 if (board_config == ALC662_AUTO)
16411 spec->init_hook = alc662_auto_init;
16412 #ifdef CONFIG_SND_HDA_POWER_SAVE
16413 if (!spec->loopback.amplist)
16414 spec->loopback.amplist = alc662_loopbacks;
16423 struct hda_codec_preset snd_hda_preset_realtek[] = {
16424 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16425 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16426 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16427 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16428 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16429 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16430 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16431 .patch = patch_alc861 },
16432 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16433 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16434 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16435 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16436 .patch = patch_alc883 },
16437 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16438 .patch = patch_alc662 },
16439 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16440 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16441 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16442 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16443 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16444 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16445 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16446 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16447 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16448 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16449 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16450 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16451 .patch = patch_alc883 },
16452 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16453 {} /* terminator */